/* t42:music house style.
 *
 * The taste in telos42-ui-base/music/TASTE.md, made into a layer every surface can adopt.
 * That file measured six music sites through their computed styles; the nine rules it
 * produced are enforced here rather than restated per page:
 *
 *   1 one face, two weights   Archivo 400/500/700. Archivo Narrow 700 for a poster only.
 *   2 small type              the scale below tops out at 32px outside a poster.
 *   3 one poster moment       .h-poster exists once per surface or not at all.
 *   4 radius zero             --r is 0. Media gets 4px, an input 2px. Nothing else.
 *   5 one electric accent     --live. It marks the live, the primary and the focused.
 *   6 artwork or nothing      no generated stand-in mark is provided, on purpose.
 *   7 mono inline only        --mono is for an identifier's value. Never a label.
 *   8 content on the ground   one ground per surface. A panel needs a real edge.
 *   9 density is bimodal      the wall, or the object.
 *
 * This supersedes atlas.css on any surface that links it. atlas.css measured its ratios
 * against a #F4F4F4 ground and none of them hold here, so the two are never linked together.
 */

@import url('https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;700&family=Archivo+Narrow:wght@700&family=DM+Mono:wght@400;500&display=swap');

/* ── the two grounds ──────────────────────────────────────────────────────────────────
 * Light is the default and dark is a choice, which is the reverse of how this was built.
 *
 * Both are committed grounds rather than one filtered into the other. Rule 8 of the measured
 * taste asks for a ground a surface sits on directly, and the light values are Ableton's
 * register, which is the one light ground in the sample of six. The accent cannot survive the
 * inversion: hsl(152 100% 44%) is 1.58 : 1 on paper, so light carries a darker green at
 * 4.86 : 1 and every semantic hue is darkened with it. Each figure below was measured, not
 * chosen, and the numbers are in the comment beside them.
 *
 * Two things stay dark in both. A poster is a full-bleed image with a scrim over it and is its
 * own environment rather than the page's, and the sign-in wall is the same. Inverting either
 * would mean re-grading photographs, and the scrim is what makes the type legible in the first
 * place.
 */
:root{
  /* paper. --plate is the ground under media that has not loaded or does not exist, so it is
     always a step away from the page rather than a step down. */
  --bg:#F3F2EF; --bg2:#FFFFFF; --plate:#E7E5E0;
  --rule:#DEDBD3; --rule2:#C4C0B6;
  /* 16.50, 6.45 and 4.82 to 1 on the ground above. --ink3 is the one that is easy to get
     wrong: it is the quietest text on the page and it still has to clear AA. */
  --ink:#14140F; --ink2:#5A574E; --ink3:#6E6A60;

  /* the one accent. 4.86 : 1, so it can carry text as well as a fill. */
  --live:#067A3C;
  --live-ink:#FFFFFF;

  /* semantics, which are not the accent and never decorate. 4.86, 5.51, 5.29, 5.64 to 1. */
  --vitality:#067A3C; --proven:#0B5FBF; --caution:#8A5A00; --leak:#B03308;

  /* the graph canvas reads these directly, so they are declared and not derived */
  --graph-bg:#F3F2EF; --graph-ink:#14140F; --graph-edge:#C4C0B6; --graph-node:#5A574E;

  /* over media, in both themes, because media is its own ground */
  --scrim:0,0,0;
  --on-media:#FFFFFF;
  --on-media-2:#C9C9C9;

  --sans:'Archivo','Helvetica Neue',Arial,sans-serif;
  --narrow:'Archivo Narrow','Archivo',Arial,sans-serif;
  --mono:'DM Mono',ui-monospace,SFMono-Regular,Menlo,monospace;

  --r:0px; --r-media:4px; --r-input:2px;
  --bar:44px; --dur:180ms; --ease:cubic-bezier(.4,0,.2,1);

  /* ── rhythm. One scale, so breathing room is a decision made once rather than a number
        typed forty times. Rule 2 governs the type scale. It does not ask for the space
        between things to be small as well. ────────────────────────────────────────────── */
  --s1:6px; --s2:10px; --s3:14px; --s4:20px; --s5:28px; --s6:40px;
  --block:clamp(22px,2.4vw,38px);
  /* The page gutter, owned here and nowhere else, so both sides move together. */
  --gutter:clamp(20px,2.2vw,40px);
}

/* Dark. The ground this was designed on, kept whole rather than derived: #767676 clears
   4.62 : 1 on pure black and only 4.41 : 1 on the #080808 panels it is actually used over, so
   the quiet ink here is #7C7C7C at 4.80 : 1 against the real ground. */
:root[data-theme="t42dark"]{
  --bg:#000000; --bg2:#0A0A0A; --plate:#080808;
  --rule:#1C1C1C; --rule2:#2E2E2E;
  --ink:#FFFFFF; --ink2:#8A8A8A; --ink3:#7C7C7C;

  --live:#00E078;                                           /* 11.93 : 1 */
  --live-ink:#000000;

  /* 11.93, 7.65, 11.70 and 6.34 to 1 on the ground above */
  --vitality:#00E078; --proven:#3AA0FF; --caution:#FFB300; --leak:#FF4D26;

  --graph-bg:#000000; --graph-ink:#FFFFFF; --graph-edge:#2E2E2E; --graph-node:#8A8A8A;
}

/* The element resets are Tailwind's preflight now, and ours are gone rather than kept beside
   them. This was not tidying. These rules are unlayered and daisyUI's components are layered,
   so at any specificity ours won: `button{padding:0}` zeroed the padding on every button the
   library draws, and the first converted filter run came out as words with no space between
   them. A reset that fights the component library is worse than no reset.
   What is left is what preflight has no opinion about. */
body{background:var(--bg);color:var(--ink);font:400 13.5px/1.58 var(--sans);
  -webkit-font-smoothing:antialiased}
::selection{background:var(--live);color:var(--live-ink)}
/* `a{color:inherit}` was the last of the unlayered resets and it did the same thing the button
   one did: menu-active paints the row and sets the label to the ground colour, and ours put it
   back to the ink, so the active rail item was black on black with the label invisible.
   Preflight sets color:inherit on a link in a layer, where the library can still win. */
:focus-visible{outline:2px solid var(--live);outline-offset:2px}
img{display:block;max-width:100%}

/* ── the label register ────────────────────────────────────────────────────────────
 * TASTE finding 7 names monospace as the developer-tool signal. What actually carries that
 * signal is the uppercase tracked micro-label, and Archivo at 10.5px/.11em reads at a glance
 * exactly as DM Mono at 10.5px/.11em does. Forty-two rules across this sheet and term.css set
 * one, which made it the texture of every page rather than an accent on one.
 *
 * Uppercase is now a single register, .eyebrow, permitted once at the head of a surface.
 * Every other label is sentence case at a size a person reads without leaning in. The pages
 * already emit sentence case in their markup, so this is a subtraction, not a rewrite.
 */

/* ── type scale. Rule 2: hierarchy from weight, case and rule, not from size. ─────── */
.h1{font:700 22px/1.1 var(--sans);letter-spacing:-.022em;margin:0}
.h2{font:700 16.5px/1.2 var(--sans);letter-spacing:-.015em;margin:0}
.h3{font:700 13.5px/1.3 var(--sans);letter-spacing:-.005em;margin:0}
/* Rule 7. Mono is a value, never a label. A class that sets mono on a heading is a defect. */
.mono{font-family:var(--mono);font-size:.92em;letter-spacing:-.01em}
.lede{font:400 13.5px/1.55 var(--sans);color:var(--ink2);margin:0;max-width:72ch}
.dim{color:var(--ink2)} .faint{color:var(--ink3)}
.num{font-variant-numeric:tabular-nums}

/* Rule 3. One per surface, uppercase, narrow, negative tracking, over media. */
.h-poster{position:relative;overflow:hidden;background:var(--bg2);
  border-bottom:1px solid var(--rule)}
.h-poster>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:grayscale(1) contrast(1.08) brightness(.6)}
.h-poster .veil{position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(0,0,0,.9),rgba(0,0,0,.5) 55%,rgba(0,0,0,.18))}
.h-poster .in{position:relative;padding:0 16px 26px;display:flex;flex-direction:column;
  justify-content:flex-end;height:100%}
.h-poster h1{font-family:var(--narrow);font-weight:700;text-transform:uppercase;
  font-size:clamp(28px,6.4vw,69px);line-height:.92;letter-spacing:-.022em;margin:0;
  text-wrap:balance}
.h-poster h1 em{font-style:normal;color:var(--live)}

/* ── bar. The single sticky strip every surface opens with. ───────────────────────── */
.h-bar{display:flex;align-items:stretch;border-bottom:1px solid var(--rule);
  position:sticky;top:0;background:var(--bg);z-index:30}
.h-bar>*{display:flex;align-items:center;padding:0 16px;height:var(--bar)}
.h-bar .id{font:700 14px/1 var(--sans);letter-spacing:-.02em;gap:8px}
.h-bar .id i{width:7px;height:7px;background:var(--live);font-style:normal;flex:none}
.h-bar .sep{border-left:1px solid var(--rule);padding:0}
.h-bar .grow{flex:1;min-width:0}

/* segmented switch. Rule 4: no pills. */
.h-sw{display:flex;padding:0;border-left:1px solid var(--rule)}
.h-sw button{padding:0 18px;height:var(--bar);font:500 12.5px/1 var(--sans);
  color:var(--ink2);transition:color var(--dur) var(--ease)}
.h-sw button:hover{color:var(--ink)}
.h-sw button.on{background:var(--ink);color:var(--bg)}

.h-q{flex:1;min-width:0;padding:0;border-left:1px solid var(--rule)}
.h-q input{width:100%;height:var(--bar);background:none;border:0;padding:0 16px;
  border-radius:var(--r-input);font-size:12.5px}
.h-q input::placeholder{color:var(--ink3)}
.h-q input:focus{outline:none;box-shadow:inset 0 0 0 1px var(--live)}

/* ── chips. A filter, not an ornament. ───────────────────────────────────────────── */
.h-chips{display:flex;flex-wrap:wrap;gap:0;border-bottom:1px solid var(--rule)}
.h-chip{padding:10px 14px;font:500 11.5px/1 var(--sans);color:var(--ink3);
  border-right:1px solid var(--rule);transition:color var(--dur) var(--ease);
  display:flex;align-items:center;gap:7px;white-space:nowrap}
.h-chip:hover{color:var(--ink)}
.h-chip.on{background:var(--ink);color:var(--bg);font-weight:700}
.h-chip u{text-decoration:none;color:var(--ink3);font-size:10.5px}
.h-chip.on u{color:var(--bg);opacity:.6}
.h-chip i{width:6px;height:6px;flex:none;font-style:normal}

/* ── rows. Rule 8: on the ground, separated by a rule, not floated on a card. ─────── */
.h-rows{border-bottom:1px solid var(--rule)}
.h-row{display:flex;align-items:center;gap:12px;padding:10px 16px;width:100%;
  border-bottom:1px solid var(--rule);text-align:left;
  transition:background var(--dur) var(--ease)}
.h-row:last-child{border-bottom:0}
.h-row:hover{background:var(--bg2)}
.h-row.on{background:var(--ink);color:var(--bg)}
.h-row.on .dim,.h-row.on .faint{color:rgba(0,0,0,.62)}
.h-row b{font:700 12.5px/1.3 var(--sans);letter-spacing:-.008em}
.h-row .sub{font:400 11.5px/1.3 var(--sans);color:var(--ink2)}

/* ── key and value. The object view's spine. ─────────────────────────────────────── */
.h-kv{display:grid;grid-template-columns:130px 1fr;border-top:1px solid var(--rule)}
.h-kv>dt{padding:10px 0;border-bottom:1px solid var(--rule);
  font:500 11.5px/1.5 var(--sans);color:var(--ink2)}
.h-kv>dd{padding:10px 0;margin:0;border-bottom:1px solid var(--rule);
  font:400 12.5px/1.55 var(--sans)}
.h-kv code{font:500 12.5px/1.5 var(--mono);letter-spacing:-.01em;
  border-bottom:1px solid var(--rule2);cursor:pointer}
.h-kv code:hover{border-bottom-color:var(--live)}

/* ── action. Rule 5: the live colour marks the primary and nothing else. ─────────── */
.h-go{background:var(--live);color:var(--live-ink);font:700 11px/1 var(--sans);
  letter-spacing:0;padding:11px 18px;border-radius:var(--r);font-size:12.5px}
.h-go:hover{filter:brightness(1.1)}
.h-btn{border:1px solid var(--rule2);padding:9px 14px;font:500 11.5px/1 var(--sans);
  border-radius:var(--r);transition:border-color var(--dur) var(--ease)}
.h-btn:hover{border-color:var(--live)}

/* the state of a thing, as a rule under it rather than a coloured pill */
.h-state{height:3px;background:var(--rule2)}
.h-state.vitality{background:var(--vitality)} .h-state.proven{background:var(--proven)}
.h-state.caution{background:var(--caution)} .h-state.leak{background:var(--leak)}

.h-foot{padding:20px 16px 40px;font:400 11.5px/1.6 var(--sans);color:var(--ink3);
  border-top:1px solid var(--rule);display:flex;justify-content:space-between;gap:20px;
  flex-wrap:wrap}

@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

/* ══ shared page furniture ═══════════════════════════════════════════════════════════
 * Every workbench surface was carrying its own copy of the rail, the masthead, the panel
 * and the table, and the copies had drifted. They live here now, in both class prefixes the
 * pages already use, so converting a page is deleting its furniture rather than rewriting it.
 */

/* ── rail ─────────────────────────────────────────────────────────────────────────── */
.rail,.s-rail{position:fixed;inset:0 auto 0 0;width:var(--rail,236px);background:var(--bg);
  border-right:1px solid var(--rule);display:flex;flex-direction:column;z-index:40;
  overflow-y:auto}
.rail .r-top,.s-rail .s-top{padding:0 16px;height:var(--bar);display:flex;align-items:center;
  border-bottom:1px solid var(--rule)}
.rail .r-toprow,.s-rail .s-toprow{display:flex;gap:8px;align-items:center}
/* the brand is the way back to the front door, and must not pick up the nav item's padding */
.r-home{padding:0!important;background:none!important;width:auto}
.r-home:hover{background:none!important}
.r-home:hover .brand,.r-home:hover .s-brand,.r-home:hover .v-brand{color:var(--live)}
.rail .mark,.s-rail .mark{width:7px;height:7px;flex:none;background:var(--live);
  border-radius:0;font-size:0;color:transparent}
.rail .brand,.s-rail .brand{font:700 14px/1 var(--sans);letter-spacing:-.02em;color:var(--ink)}
.rail .r-whose,.s-rail .s-whose{padding:12px 16px;border-bottom:1px solid var(--rule);
  font:400 11px/1.5 var(--sans);color:var(--ink3);margin:0}
.rail .runbar,.s-rail .runbar{margin-top:auto;padding:14px 16px 18px;
  border-top:1px solid var(--rule);color:var(--ink3);font:400 11px/1.6 var(--sans)}
.rail .runbar b,.s-rail .runbar b{display:block;color:var(--ink2);font-weight:500;
  letter-spacing:.02em;font-size:11px;margin-bottom:6px}
.rail .runbar .warn,.s-rail .runbar .warn{color:var(--caution)}

/* the disclosure chevron nav.js injects */
/* The menu draws the row. These are the two things it has no opinion about: the icon's
   weight, and the label clipping rather than wrapping in a 236px column. */
.nv-a{position:relative}
.nv-i{width:13px;height:13px;flex:none;opacity:.55}
.nv-a.on .nv-i{opacity:1}
.nv-l{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ── page shell and masthead ──────────────────────────────────────────────────────── */
/* The header is fixed at the top and the rail hangs beneath it, so the page is offset on
   both axes. --rail is declared only by surfaces that have a rail, and --bar only takes
   effect where nav.js has put a header, so the landing and the lab need no opt-out. */
body{padding-left:var(--rail,0px);padding-top:var(--railtop,0px)}
body:has(#t-top){--railtop:var(--bar)}
.rail,.s-rail,.v-rail{top:var(--railtop,0px)}
/* the brand now lives in the header, so the rail head carries what the page is about */
body:has(#t-top) .r-home,body:has(#t-top) .v-toprow{display:none}
main{padding:0 var(--gutter) 60px;min-width:0}
.wrap{max-width:none}
.mast{display:flex;align-items:flex-start;justify-content:space-between;gap:40px;
  padding:26px 0 22px;border-bottom:1px solid var(--rule);flex-wrap:wrap}
.mast>.l{flex:1 1 auto;min-width:320px}
/* .head is the same masthead under an older name: a title block on the left and a single
   headline figure on the right. The conform transform removed each page's copy and house.css
   only carried `.head h1`, so the two blocks stacked and the figure printed over its label. */
.head{display:flex;align-items:flex-start;justify-content:space-between;gap:40px;
  padding:26px 0 22px;border-bottom:1px solid var(--rule);flex-wrap:wrap}
.head>div:first-child{flex:1 1 auto;min-width:300px}
.eyebrow{font:700 10px/1.6 var(--sans);letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink3);margin:0 0 12px}
.eyebrow b{color:var(--live);font-weight:700}
h1,.head h1{font:700 22px/1.1 var(--sans);letter-spacing:-.022em;margin:0 0 10px;
  text-wrap:balance;max-width:24ch;color:var(--ink)}
.kicker,.lede{font:400 12.5px/1.55 var(--sans);color:var(--ink2);margin:0;max-width:80ch}
.mast>.l>.kicker,.head>div>.kicker,.head>div>.lede{font-size:13.5px;max-width:none;
  text-wrap:pretty}
.kicker b,.lede b{color:var(--ink);font-weight:500}
.kicker .hl{color:var(--leak);font-weight:500}
.kicker .sep,.lede .sep{color:var(--rule2);margin:0 7px}

/* the stat strip. Rule 2: these are the only numbers allowed to be large, and they cap at 32. */

/* ── control bar ──────────────────────────────────────────────────────────────────── */
/* A control strip. Four of these stack above the content on the catalogue surface, and they
   carried no vertical padding at all: the rule between two of them was the only thing keeping
   PROBE, GRAIN, VIEW and FIND apart, so the eye met four hairlines and no air before reaching a
   single row of data. The rule still does the separating. The padding gives it something to
   separate. */
.bar{display:flex;align-items:stretch;flex-wrap:wrap;border-bottom:1px solid var(--rule);
  margin:0;max-width:100%;padding:var(--s2) 0;row-gap:var(--s2)}
/* And air before the content the strips are filtering, so the table is not welded to them. */
.bar+.panel,.bar+.dg-wrap,.bar+.cols{margin-top:var(--block)}
/* Wide content scrolls inside its own container. The page body never scrolls sideways, and
   nothing is allowed to clip a row of tabs or a run of chips at the frame edge. */
.scrollx{overflow-x:auto;overflow-y:hidden;max-width:100%;scrollbar-width:thin}
.scrollx::-webkit-scrollbar{height:6px}
.scrollx::-webkit-scrollbar-thumb{background:var(--rule2)}
.bar>*{display:flex;align-items:center}
.lbl{font:500 11.5px/1.3 var(--sans);color:var(--ink3);padding:0 14px 0 0}
.seg{display:flex;border:0}
.seg button{padding:0 16px;height:var(--bar);background:none;border:0;border-right:1px solid var(--rule);
  font:500 12.5px/1 var(--sans);color:var(--ink3);border-radius:0;
  transition:color var(--dur) var(--ease)}
.seg button:hover{color:var(--ink)}
.seg button.on{background:var(--ink);color:var(--bg);font-weight:700}
.note,.hint{font:400 11.5px/1.4 var(--sans);color:var(--ink3);padding:0;flex:1;
  min-width:240px}
.note b,.hint b{color:var(--ink);font-weight:500}

/* ── panel and table. Rule 8: the panel is a rule and a heading, not a floating card. ─ */
.panel{margin:0;border:0;border-bottom:1px solid var(--rule);background:none;border-radius:0}
.panel h2{font:600 14px/1.3 var(--sans);letter-spacing:-.008em;
  color:var(--ink);margin:0;padding:26px 0 13px;border-bottom:1px solid var(--rule);
  display:flex;justify-content:space-between;gap:20px;align-items:baseline}
.panel h2 em{font:400 11.5px/1.45 var(--sans);letter-spacing:0;text-transform:none;
  color:var(--ink2);text-align:right;max-width:64ch}
.pad{padding:20px 0}
td.id{font:500 11.5px/1.4 var(--mono);color:var(--ink);white-space:nowrap}
td b{color:var(--ink);font-weight:700}
td.num{text-align:right;font:500 14px/1 var(--sans);font-variant-numeric:tabular-nums;
  color:var(--ink)}
td.num.zero{color:var(--ink3)}
td small{display:block;margin-top:4px;font:400 11.5px/1.5 var(--sans);color:var(--ink3)}
td code{font:500 11.5px/1.6 var(--mono);color:var(--ink);background:none;
  border-bottom:1px solid var(--rule2);padding:0;border-radius:0;margin:0 6px 3px 0;
  display:inline-block}
td code.x{color:var(--leak);border-bottom-color:color-mix(in srgb,var(--leak) 45%,transparent)}

/* a tag names a thing. Rule 4: no pills. */
.tag{display:inline-block;font:500 11px/1 var(--sans);padding:5px 8px;border-radius:0;
  border:1px solid var(--rule2);color:var(--ink2);margin:0 -1px -1px 0}
.tag.r{color:var(--vitality);border-color:color-mix(in srgb,var(--vitality) 45%,transparent)}
.tag.x{color:var(--leak);border-color:color-mix(in srgb,var(--leak) 45%,transparent)}
.tag.c{color:var(--caution);border-color:color-mix(in srgb,var(--caution) 45%,transparent)}
.meter{display:flex;height:3px;background:var(--rule2);overflow:hidden;margin-top:6px;max-width:190px}
.meter i{display:block;height:100%;background:var(--leak)}
/* Two segments where a figure has a before and an after: what was supplied, then what a
   source added on top of it. The base was already one fill, so one <i> is unchanged. */
.meter i.was{background:var(--ink2)}
.meter i.added{background:var(--live)}

/* ── the dark scene, which is now the same ground as the page ─────────────────────── */
.stage{position:relative;border:0;border-top:1px solid var(--rule);
  border-bottom:1px solid var(--rule);border-radius:0;background:var(--bg);overflow:hidden}
.scene{position:relative}
.scene svg{display:block;width:100%;height:auto}
.legend{display:flex;gap:20px;flex-wrap:wrap;padding:12px 0;
  border-top:1px solid var(--rule);font:400 11.5px/1.5 var(--sans);color:var(--ink3);
  align-items:center}
.legend b{color:var(--ink2);font-weight:500}
.legend .sw,.legend i{display:inline-block;width:20px;height:8px;margin-right:8px;
  vertical-align:-1px;border-radius:0}
.tip{position:absolute;pointer-events:none;opacity:0;transition:opacity var(--dur);z-index:5;
  background:var(--ink);color:var(--bg);border-radius:0;padding:11px 14px;max-width:350px;
  font:400 11.5px/1.5 var(--sans)}
.tip.on{opacity:1}
.tip b{display:block;font-weight:700;margin-bottom:4px}
.tip .m{font:500 11px/1.5 var(--mono);color:rgba(0,0,0,.6);display:block;margin-top:7px}

/* ── drawer ───────────────────────────────────────────────────────────────────────── */
.drawer{position:fixed;top:0;right:0;bottom:0;width:440px;background:var(--bg);
  border-left:1px solid var(--rule2);z-index:60;transform:translateX(100%);
  transition:transform 240ms var(--ease);overflow-y:auto;padding:24px 24px 44px;
  box-shadow:-20px 0 50px rgba(0,0,0,.6)}
.drawer.on{transform:none}
.drawer .x{position:absolute;top:16px;right:20px;color:var(--ink3);font-size:16.5px}
.drawer h3{font:700 18px/1.2 var(--sans);letter-spacing:-.018em;margin:10px 0 4px}
.drawer .band{height:3px;margin:0 0 16px}
.drawer dl{margin:20px 0 0;display:grid;gap:0}
.drawer dt{font:500 11.5px/1.4 var(--sans);color:var(--ink2);padding-top:16px;
  border-top:1px solid var(--rule)}
.drawer dd{margin:7px 0 14px;font:400 12.5px/1.55 var(--sans);color:var(--ink2)}
.drawer code{font:500 11.5px/1.6 var(--mono);color:var(--ink);background:none;
  border-bottom:1px solid var(--rule2);padding:0;border-radius:0;margin:0 6px 3px 0;
  display:inline-block}
.drawer .ent{border-left:1px solid var(--rule2);padding:2px 0 2px 12px;margin-bottom:12px}
.drawer .ent b{display:block;font:700 11.5px/1.3 var(--sans);color:var(--ink)}
.drawer .ent span{display:block;font:400 11px/1.6 var(--sans);color:var(--ink3)}
.drawer .ent p{margin:5px 0 0;font:400 11.5px/1.55 var(--sans);color:var(--ink3)}

footer{display:flex;justify-content:space-between;gap:30px;padding:20px 0;
  border-top:1px solid var(--rule);font:400 11.5px/1.6 var(--sans);color:var(--ink3);
  flex-wrap:wrap}
footer .r{color:var(--ink2);font-weight:500;flex:none}

/* The catalogue switch in the rail. A control, not a panel: it sits on the ground the rail
   already made and takes the full width so the longest client name is not clipped. Present
   only when this account holds more than one catalogue. */
.rail .r-cat{display:block;width:100%;margin:8px 0 0;padding:6px 0;background:none;
  border:0;border-bottom:1px solid var(--rule2);border-radius:0;
  font:500 11.5px/1.4 var(--sans);color:var(--ink);cursor:pointer;
  -webkit-appearance:none;appearance:none}
.rail .r-cat:hover{border-bottom-color:var(--live)}
.rail .r-cat:focus-visible{outline:2px solid var(--live);outline-offset:2px}
body.railfold .rail .r-cat{display:none}


/* ── the RVLI mark, three treatments ────────────────────────────────────────────────────
   Design Specification v3.0 section 5. One measure, three sizes, one geometry. The bands are
   a reading aid on a continuous index and the tones come from the house status tokens rather
   than from a palette of their own, so a band never competes with a status elsewhere. */
.rv-impaired, .rv-exposed { --rv: var(--leak); }
.rv-guarded               { --rv: var(--caution); }
.rv-assured               { --rv: var(--vitality); }

/* inline and tight. The rule carries the band, so the number is legible without it. */
.rv-mark { display:inline-flex; align-items:center; gap:7px; padding:2px 0 2px 9px;
  border-left:3px solid var(--rv, var(--rule)); line-height:1.2; white-space:nowrap; }
.rv-mark .rv-n { font-family:var(--mono); font-size:15px; font-weight:600; color:var(--ink); }
.rv-mark .rv-b { font-size:11px; letter-spacing:.04em; text-transform:uppercase;
  color:var(--rv, var(--ink3)); }
.rv-tight { gap:5px; padding-left:7px; }
.rv-tight .rv-n { font-size:13px; }
.rv-g { font-family:var(--mono); font-size:11px; font-weight:600; padding:1px 6px;
  border:1px solid var(--rule); border-radius:3px; color:var(--ink2); }
.rv-g.rv-big { font-size:15px; padding:4px 11px; }

/* the plaque */
.rv-plaque { border:1px solid var(--rule); border-radius:var(--r-media, 4px);
  background:var(--plate); padding:clamp(18px,2.2vw,30px); margin:22px 0; }
.rv-grid { display:grid; grid-template-columns:minmax(200px,.85fr) minmax(260px,1.3fr)
  minmax(240px,1fr); gap:clamp(20px,3vw,44px); }
@media (max-width:1000px){ .rv-grid { grid-template-columns:1fr; gap:26px; } }
.rv-head { display:flex; align-items:baseline; gap:9px; margin:7px 0 0; }
.rv-score { font-family:var(--mono); font-size:clamp(40px,5vw,58px); font-weight:600;
  line-height:1; color:var(--ink); letter-spacing:-.02em; }
.rv-den { font-family:var(--mono); font-size:15px; color:var(--ink3); }
.rv-bandline { display:flex; align-items:baseline; gap:11px; margin:9px 0 0; flex-wrap:wrap; }
.rv-word { font-size:15px; font-weight:600; color:var(--rv, var(--ink)); }
.rv-delta { font-size:12px; }
.rv-delta.up { color:var(--vitality); } .rv-delta.dn { color:var(--leak); }
/* An absent comparison says so. A blank would read as no movement, which is a claim. */
.rv-nomove { font-size:12px; color:var(--ink3); }
.rv-why { font-size:13px; line-height:1.55; color:var(--ink2); margin:11px 0 0; }
.rv-arith b { color:var(--ink); font-family:var(--mono); }

/* the published scale, at the declared geometry */
.rv-scale { position:relative; margin:4px 0 0; }
.rv-track { display:flex; height:9px; border-radius:5px; overflow:hidden; }
.rv-track i { display:block; height:100%; }
.rv-track .rv-impaired { background:color-mix(in oklab, var(--leak) 42%, transparent); }
.rv-track .rv-exposed  { background:color-mix(in oklab, var(--leak) 22%, transparent); }
.rv-track .rv-guarded  { background:color-mix(in oklab, var(--caution) 34%, transparent); }
.rv-track .rv-assured  { background:color-mix(in oklab, var(--vitality) 42%, transparent); }
/* Other catalogues in the book. Behind the reader's own mark, never over it. */
.rv-peer { position:absolute; top:-3px; width:2px; height:15px; margin-left:-1px;
  background:var(--ink3); opacity:.5; }
.rv-me { position:absolute; top:-6px; width:3px; height:21px; margin-left:-1.5px;
  background:var(--ink); border-radius:2px; }
.rv-axis { display:flex; justify-content:space-between; margin:9px 0 0;
  font-family:var(--mono); font-size:11px; color:var(--ink3); }
.rv-key { display:flex; flex-wrap:wrap; gap:5px 15px; margin:13px 0 0; font-size:11px;
  color:var(--ink2); }
.rv-key span { display:inline-flex; align-items:center; gap:6px; }
.rv-key i { width:11px; height:11px; border-radius:2px; display:inline-block; }
.rv-key .rv-impaired { background:color-mix(in oklab, var(--leak) 42%, transparent); }
.rv-key .rv-exposed  { background:color-mix(in oklab, var(--leak) 22%, transparent); }
.rv-key .rv-guarded  { background:color-mix(in oklab, var(--caution) 34%, transparent); }
.rv-key .rv-assured  { background:color-mix(in oklab, var(--vitality) 42%, transparent); }
.rv-cohort { display:flex; flex-wrap:wrap; gap:6px; margin:15px 0 0; }
.rv-ck { font-family:var(--mono); font-size:11px; padding:3px 8px; border:1px solid var(--rule);
  border-radius:3px; color:var(--ink2); }
/* The cohort we do not hold. Present as a slot so its absence is legible, never as a number. */
.rv-absent { opacity:.62; border-style:dashed; }
