/* ============================================================================
 * portal.css — the Regis design system, ported to the client portal.
 *
 * WHY THIS FILE EXISTS
 * The portal and Regis are the same firm and looked like two different products:
 * Regis is "Regency" (navy/gilt glass slabs, Playfair, three themes, motion
 * discipline); the portal was a flat teal admin panel on a font it never loaded.
 * This carries the Regis MATERIALS across — tokens, fonts, slab, hairlines,
 * gilt, motion — without carrying its INFORMATION ARCHITECTURE, which is built
 * for people who live in it all day and is wrong for a client reading about
 * their own lawsuit on a phone.
 *
 * SOURCE OF TRUTH
 * Tokens and component recipes are copied from ~/vindex-command-center/public/
 * matters.html (chmod 444, READ ONLY — never edited, never unlocked). Where a
 * value here differs from Regis it is deliberate and the reason is in a comment
 * next to it. Token NAMES are preserved because Regis's own JS templates
 * inline-reference them and ours now do too.
 *
 * EXTERNAL STYLESHEET, ON PURPOSE
 * style-src is 'self' 'unsafe-inline' (server.js:79) and express.static mounts
 * public/ at /assets (server.js:1026), so this loads as /assets/portal.css.
 * Critically it is NOT a <script>: test/render-lang.js and test/e2e.js both
 * inspect inline <script> blocks only, so moving CSS out of the pages costs
 * nothing in test coverage. Moving the SCRIPTS out would break both.
 *
 * TWO AUDIENCES, ONE SYSTEM
 * Everything here is shared except type scale. `.is-client` on <body> bumps the
 * small-caps idiom up ~1.25x — Regis's 10px/.2em labels are correct density for
 * a ledger and are the single biggest readability problem on a client page.
 * ========================================================================== */

/* ── FONTS — three files, not six ───────────────────────────────────────────
 * Regis ships Inter under three names and Playfair under two; all are
 * byte-identical variable fonts (verified by sha256: Inter-400/600/700 are one
 * file with a wght axis of 100-900, Playfair-600/700 one file, 400-900). The
 * duplicate URLs cost three downloads of the same bytes. Declared once each
 * against the true axis range here: identical rendering, 112K instead of 245K.
 * font-src is 'self' (server.js:82) so these MUST be same-origin. A CDN font
 * fails silently — which is exactly how the portal shipped 'Libre Franklin' on
 * all three pages for a font that was never loaded anywhere. */
@font-face{font-family:'Inter';src:url('/assets/fonts/Inter.woff2') format('woff2');font-weight:100 900;font-display:swap}
@font-face{font-family:'Playfair Display';src:url('/assets/fonts/PlayfairDisplay.woff2') format('woff2');font-weight:400 900;font-display:swap}
@font-face{font-family:'Cormorant Garamond';src:url('/assets/fonts/CormorantGaramond.woff2') format('woff2');font-weight:600 700;font-display:swap}

/* ── TOKENS: REGENCY (dark) — the base, copied verbatim from matters.html:33 ── */
:root{
  /* navy surface ladder — hue constant, only lightness moves */
  --canvas:#070b13; --card:#0e1626; --soft:#0b1120; --elev:#131c30;
  --border:rgba(255,255,255,.10); --border-2:rgba(255,255,255,.06);
  /* --border is a SEPARATOR (1.29-1.42:1 here) and fine for one. An input
     or select edge is a control boundary and WCAG 1.4.11 wants 3:1, so
     interactive edges use --border-strong instead. */
  --border-strong:rgba(255,255,255,.38);
  --hairline-gold:rgba(201,168,76,.24);
  /* four ink levels — warm off-whites */
  --ink:#f2efe6; --ink-2:#c8cdd8; --muted:#8d96a7; --faint:#5b6579;
  --hover:#141d31; --input:#0a101d;
  /* gilt range */
  --gold:#C9A84C; --gold-bright:#D4AF37; --champagne:#d8c690; --gold-deep:#8a6e2f;
  --link:#d8c690; --cyan:#C9A84C;
  /* Focus ring, themed. Regis hardcodes rgba(201,168,76,.55) at matters.html:720,
     which measures 3.23:1 on the dark card but only 1.50:1 on light and 1.47:1
     on beige — and light is the CLIENT DEFAULT. WCAG 2.4.11 wants 3:1. */
  --focus-ring:rgba(201,168,76,.75);
  /* desaturated semantics — the private-bank rule: no traffic lights */
  --green:#4fae76; --red:#e07a68; --blue:#7da9d8;
  --serif:'Playfair Display',Georgia,serif; --brand-serif:'Cormorant Garamond',Georgia,serif;
  --shadow:inset 0 1px 0 rgba(255,255,255,.05),0 0 0 1px rgba(255,255,255,.045),0 12px 32px -16px rgba(2,5,12,.7);
  --shadow-2:inset 0 1px 0 rgba(255,255,255,.06),0 0 0 1px rgba(255,255,255,.05),0 24px 60px -20px rgba(1,3,8,.85);
  --slab:linear-gradient(180deg,rgba(17,25,42,.82) 0%,rgba(12,18,31,.9) 100%);
  --slab-ring:inset 0 1px 0 rgba(255,255,255,.05),0 0 0 1px rgba(255,255,255,.045),0 16px 44px -18px rgba(1,3,8,.8);
  /* motion — three easings, 300ms functional ceiling */
  --t-instant:90ms; --t-fast:150ms; --t-base:240ms; --t-slow:300ms; --t-fill:800ms;
  --ease-standard:cubic-bezier(.23,1,.32,1); --ease-out:cubic-bezier(.23,1,.32,1);
  --ease-in:cubic-bezier(.32,.72,0,1); --ease-drawer:cubic-bezier(.32,.72,0,1);
}

/* ── GALLERY (light) — ivory marble, navy ink, gold leaf. matters.html:838 ──
 * --muted and --cyan carry measured accessibility fixes from Regis. Do NOT
 * "tidy" them back to the dark values: --cyan was defined dark-only and the
 * SELECTED control measured 1.97:1 here, the least readable thing on the page. */
html[data-theme="light"]{
  color-scheme:light;
  --canvas:#f2eee4; --card:#fcfaf4; --soft:#f6f2e8; --elev:#ffffff;
  --border:rgba(38,46,66,.16); --border-2:rgba(38,46,66,.09);
  --border-strong:rgba(38,46,66,.52);
  --hairline-gold:rgba(138,110,47,.35);
  --ink:#1c2434; --ink-2:#3a4458; --muted:#626b7c; --faint:#9aa2b2;
  --hover:#efe9db; --input:#ffffff;
  /* The gilt that carries TEXT is #7d6229, not #8a6e2f. Light collapses
     --champagne/--gold-bright/--link onto one value, and at #8a6e2f four
     components sat under the 4.5:1 floor: the status pill (4.16), the selected
     segment (4.35), banner emphasis (3.96) and confirmation text (4.28). The
     pill is where a client reads the status of their own lawsuit. #7d6229 is
     already this theme's --cyan, chosen for exactly this reason — so the two
     now agree instead of disagreeing by an invisible amount.
     --gold stays #a8842e: it is only ever a BORDER or rule (3:1 floor), never
     text, and it keeps the leaf warmer than the ink. */
  --gold:#a8842e; --gold-bright:#7d6229; --champagne:#7d6229; --gold-deep:#6e5517;
  --link:#7d6229; --cyan:#7d6229;
  --focus-ring:#6e5517;
  --green:#2e7d4f; --red:#b4432f; --blue:#33547e;
  --shadow:inset 0 1px 0 rgba(255,255,255,.8),0 0 0 1px rgba(38,46,66,.07),0 12px 32px -16px rgba(50,42,20,.25);
  --shadow-2:inset 0 1px 0 rgba(255,255,255,.9),0 0 0 1px rgba(38,46,66,.08),0 24px 60px -20px rgba(50,42,20,.3);
  --slab:linear-gradient(180deg,rgba(255,253,248,.92) 0%,rgba(250,246,236,.96) 100%);
  --slab-ring:inset 0 1px 0 rgba(255,255,255,.9),0 0 0 1px rgba(38,46,66,.08),0 16px 44px -18px rgba(50,42,20,.22);
}

/* ── READING ROOM (beige) — parchment, espresso, candlelight. matters.html:974 ── */
html[data-theme="beige"]{
  color-scheme:light;
  --canvas:#ede4d0; --card:#f8f2e3; --soft:#f2ebda; --elev:#fdf9ee;
  --border:rgba(74,58,28,.2); --border-2:rgba(74,58,28,.11);
  --border-strong:rgba(74,58,28,.56);
  --hairline-gold:rgba(138,110,47,.4);
  --ink:#2b2414; --ink-2:#453b24; --muted:#6f6248; --faint:#a1947a;
  --hover:#eae0c8; --input:#fffdf6;
  --gold:#8a6d24; --gold-bright:#75591a; --champagne:#75591a; --gold-deep:#5a4416;
  --link:#75591a; --cyan:#75591a;
  --focus-ring:#5a4416;
  --green:#3f6b34; --red:#a03a20; --blue:#4a5e7c;
  --shadow:inset 0 1px 0 rgba(255,252,240,.85),0 0 0 1px rgba(74,58,28,.09),0 12px 32px -16px rgba(70,52,20,.28);
  --shadow-2:inset 0 1px 0 rgba(255,252,240,.95),0 0 0 1px rgba(74,58,28,.1),0 24px 60px -20px rgba(70,52,20,.35);
  --slab:linear-gradient(180deg,rgba(253,249,238,.94) 0%,rgba(246,239,224,.97) 100%);
  --slab-ring:inset 0 1px 0 rgba(255,252,240,.9),0 0 0 1px rgba(74,58,28,.1),0 16px 44px -18px rgba(70,52,20,.26);
}

/* ── NO-JAVASCRIPT FALLBACK ─────────────────────────────────────────────────
 * The theme is normally stamped onto <html> by a bootstrap script. With JS
 * disabled that never runs, no data-theme attribute exists, and every page fell
 * back to the dark base — contradicting the light default chosen for clients.
 * These rules apply only when nothing has been stamped, so they can never fight
 * an explicit choice. */
@media (prefers-color-scheme: light){
  html:not([data-theme]){
    color-scheme:light;
    --canvas:#f2eee4; --card:#fcfaf4; --soft:#f6f2e8; --elev:#ffffff;
    --border:rgba(38,46,66,.16); --border-2:rgba(38,46,66,.09); --border-strong:rgba(38,46,66,.52);
    --hairline-gold:rgba(138,110,47,.35);
    --ink:#1c2434; --ink-2:#3a4458; --muted:#626b7c; --faint:#9aa2b2;
    --hover:#efe9db; --input:#ffffff;
    --gold:#a8842e; --gold-bright:#7d6229; --champagne:#7d6229; --gold-deep:#6e5517;
    --link:#7d6229; --cyan:#7d6229; --focus-ring:#6e5517;
    --green:#2e7d4f; --red:#b4432f; --blue:#33547e;
    --slab:linear-gradient(180deg,rgba(255,253,248,.92) 0%,rgba(250,246,236,.96) 100%);
    --slab-ring:inset 0 1px 0 rgba(255,255,255,.9),0 0 0 1px rgba(38,46,66,.08),0 16px 44px -18px rgba(50,42,20,.22);
  }
  html:not([data-theme]) body{background:
    radial-gradient(1300px 640px at 24% -12%,rgba(255,255,255,.85) 0%,rgba(255,255,255,0) 58%),
    radial-gradient(58% 38% at 50% 0%,rgba(201,168,76,.07),transparent 70%),
    radial-gradient(900px 560px at 88% 112%,rgba(168,132,46,.06),transparent 62%),
    radial-gradient(115% 95% at 50% 44%,transparent 60%,rgba(90,70,30,.1) 100%) fixed,
    var(--canvas)}
}

/* ── MOTION KILL SWITCH — copied verbatim; respects the OS setting globally ── */
@media (prefers-reduced-motion: reduce){
  *,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
}
::view-transition-old(root),::view-transition-new(root){animation-duration:320ms;animation-timing-function:var(--ease-standard)}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;font-family:'Inter',"Segoe UI",Helvetica,Arial,sans-serif;
  color:var(--ink);background:var(--canvas);-webkit-font-smoothing:antialiased;
  font-size:14px;line-height:1.5;min-height:100dvh;
}
/* ATMOSPHERE — the lit room. Regis pins this `fixed`; kept, because it is the
 * single strongest "same house" signal and costs one paint. */
body{background:
  radial-gradient(1300px 640px at 24% -12%,rgba(21,35,60,.85) 0%,rgba(21,35,60,0) 58%),
  radial-gradient(58% 38% at 50% 0%,rgba(201,168,76,.05),transparent 70%),
  radial-gradient(900px 560px at 88% 112%,rgba(138,110,47,.08),transparent 62%),
  radial-gradient(115% 95% at 50% 44%,transparent 55%,rgba(1,3,8,.6) 100%) fixed,
  var(--canvas)}
html[data-theme="light"] body{background:
  radial-gradient(1300px 640px at 24% -12%,rgba(255,255,255,.85) 0%,rgba(255,255,255,0) 58%),
  radial-gradient(58% 38% at 50% 0%,rgba(201,168,76,.07),transparent 70%),
  radial-gradient(900px 560px at 88% 112%,rgba(168,132,46,.06),transparent 62%),
  radial-gradient(115% 95% at 50% 44%,transparent 60%,rgba(90,70,30,.1) 100%) fixed,
  var(--canvas)}
html[data-theme="beige"] body{background:
  radial-gradient(1300px 640px at 24% -12%,rgba(255,251,238,.9) 0%,rgba(255,251,238,0) 58%),
  radial-gradient(58% 38% at 50% 0%,rgba(201,168,76,.09),transparent 70%),
  radial-gradient(900px 560px at 88% 112%,rgba(138,109,36,.08),transparent 62%),
  radial-gradient(115% 95% at 50% 44%,transparent 60%,rgba(74,58,28,.13) 100%) fixed,
  var(--canvas)}

.atmo{position:fixed;inset:0;pointer-events:none;z-index:0}
.atmo .grain{position:absolute;inset:0;opacity:.05;filter:url(#vxgrain) contrast(140%);mix-blend-mode:overlay}
.atmo .vghost{position:absolute;right:-2.5vw;bottom:-16vh;font-family:var(--serif);font-weight:700;font-size:64vh;line-height:1;
  color:transparent;-webkit-text-stroke:1px rgba(201,168,76,.05);user-select:none}
html[data-theme="light"] .atmo .vghost{-webkit-text-stroke-color:rgba(138,110,47,.07)}
html[data-theme="beige"] .atmo .vghost{-webkit-text-stroke-color:rgba(138,109,36,.08)}
/* The ghost V is 64vh of decoration. On a phone it crowds real content and on a
 * short viewport it sits behind the composer — Regis never has to care because
 * it is desktop-only by construction. */
@media(max-width:700px){.atmo .vghost{display:none}}

/* ── COMMAND BAR — glass chrome, gold seam beneath. matters.html:78 ──
 * The SHELL ports; the CONTENTS do not. Regis carries global matter search,
 * a billing timer, a create menu and a notification bell — a client has one
 * destination and no use for any of them, and advertising a Cmd-K shortcut to
 * someone on an iPhone is noise. */
.top{height:58px;display:flex;align-items:center;gap:14px;padding:0 22px;z-index:20;position:relative;
  background:rgba(8,13,22,.58);backdrop-filter:blur(16px) saturate(1.7);-webkit-backdrop-filter:blur(16px) saturate(1.7)}
html[data-theme="light"] .top{background:rgba(250,247,239,.65);backdrop-filter:blur(16px) saturate(1.4);-webkit-backdrop-filter:blur(16px) saturate(1.4)}
html[data-theme="beige"] .top{background:rgba(244,236,219,.65);backdrop-filter:blur(16px) saturate(1.4);-webkit-backdrop-filter:blur(16px) saturate(1.4)}
.top:after{content:'';position:absolute;left:0;right:0;bottom:-1px;height:1px;
  background:linear-gradient(90deg,transparent,rgba(201,168,76,.55) 16%,rgba(201,168,76,.55) 84%,transparent);pointer-events:none}
.top .sp{flex:1}
.top .who{color:var(--muted);font-size:12.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:38vw}
/* The bar must WRAP, never clip. Regis is desktop-only by construction and can
   ignore this; a paralegal opening a client thread from a phone cannot. Clipped
   it put the third theme button off-screen entirely and cut the wordmark
   mid-word — no scrollbar, no overflow, just unreachable. */
@media(max-width:760px){
  .top,.tbar{height:auto;flex-wrap:wrap;padding:10px 14px 12px;gap:10px}
  .top .sp{flex-basis:100%;height:0;order:1}
  .top .who{max-width:100%;order:2;flex:1 1 auto}
  .top .wordmark{order:0}
}
@media(max-width:420px){
  .top .who{flex-basis:100%;order:3}
}

/* Wordmark — Cormorant, gilt sweep. The rail's monument reduced to a line. */
.wordmark{display:flex;align-items:center;gap:11px;text-decoration:none;min-width:0}
.wordmark .bname{font-family:var(--brand-serif);font-weight:600;font-size:19px;line-height:1;letter-spacing:.13em;white-space:nowrap;
  background:linear-gradient(100deg,#e8d9a8 0%,#D4AF37 30%,#f4e8c8 50%,#C9A84C 70%,#e8d9a8 100%);background-size:220% 100%;
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
  animation:vxsweep 12s cubic-bezier(.6,.05,.4,.95) infinite}
html[data-theme="light"] .wordmark .bname,html[data-theme="beige"] .wordmark .bname{
  background:linear-gradient(100deg,#8a6e2f 0%,#a8842e 30%,#c9a84c 50%,#8a6e2f 70%,#6e5517 100%);background-size:220% 100%;
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
@keyframes vxsweep{0%{background-position:120% 0}55%{background-position:-20% 0}100%{background-position:-20% 0}}
.wordmark .bfirm{font-size:8.5px;font-weight:600;letter-spacing:.3em;color:var(--muted);text-transform:uppercase;white-space:nowrap}
@media(max-width:560px){.wordmark .bfirm{display:none}}

/* ── THE MACHINED V — matters.html:151. Four stacked layers with a 13.5s
 * specular sweep. The one place a slow decorative animation earns its keep:
 * a login page reached from an email has to answer "is this really my law
 * firm?" before it asks for anything. */
.bmark{position:relative;width:40px;height:44px;flex:0 0 40px}
.bmark span{position:absolute;inset:0;font-family:var(--serif);font-weight:700;font-size:40px;line-height:44px;text-align:center;display:block}
.bmark .bshadow{color:#000;opacity:.55;filter:blur(5px);transform:translate(1px,2px)}
.bmark .bvee{background:linear-gradient(167deg,#081726 0%,#0f2c49 16%,#1d4a75 26%,#0c2038 33%,#3a6f9e 41%,#9fc6e2 46%,#d6e9f7 48%,#7ba7c9 51%,#16385c 58%,#0a1e33 68%,#12314f 78%,#081524 88%,#04090f 100%);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.bmark .bbezel{color:transparent;-webkit-text-stroke:1px rgba(214,180,86,.6);filter:drop-shadow(0 0 3px rgba(201,168,76,.3))}
.bmark .bsweep{background:linear-gradient(115deg,transparent 34%,rgba(255,236,200,.05) 43%,rgba(255,248,232,.85) 50%,rgba(214,240,255,.06) 57%,transparent 66%);
  background-size:340% 100%;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
  animation:bsweep 13.5s cubic-bezier(.6,.05,.4,.95) infinite}
@keyframes bsweep{0%{background-position:135% 0;opacity:0}8%{opacity:1}62%{background-position:-35% 0;opacity:1}74%{opacity:0}100%{background-position:-35% 0;opacity:0}}
.bmark.lg{width:72px;height:80px;flex:0 0 72px}
.bmark.lg span{font-size:72px;line-height:80px}

/* ── LAYOUT ─────────────────────────────────────────────────────────────────
 * Regis is `html,body{overflow:hidden}` + 100vh panes: correct for an app that
 * owns the whole screen, wrong for a document. These scroll normally, use dvh
 * so the iOS URL bar does not eat the composer, and never trap the page. */
.wrap{position:relative;z-index:1;max-width:1180px;margin:0 auto;padding:26px 22px 72px}
.wrap.narrow{max-width:860px}
.wrap.mini{max-width:460px;padding-top:6vh}
@media(max-width:640px){.wrap{padding:18px 14px 56px}}

/* ── CARDS — glass slabs with inner light. matters.html:437 ──
 * No border: the edge is a three-part box-shadow. An inline border-color on
 * .card is inert (a real no-op exists in Regis at matters.html:6374). */
.card{border-radius:14px;padding:24px 26px;position:relative;background:var(--slab);
  box-shadow:var(--slab-ring);transition:box-shadow 200ms var(--ease-out)}
.card+.card{margin-top:18px}
@media(max-width:640px){.card{padding:20px 18px;border-radius:12px}}
.ct{font-size:10.5px;font-weight:600;letter-spacing:.2em;text-transform:uppercase;color:var(--champagne);
  margin:0 0 16px;display:flex;align-items:center;justify-content:space-between;gap:12px}
.ct .act{font-size:11.5px;font-weight:600;letter-spacing:.03em;text-transform:none;color:var(--link);cursor:pointer;background:none;border:0;font-family:inherit;padding:0}
.ct .act:hover{color:var(--gold-bright);text-decoration:underline;text-underline-offset:3px}
.stack{display:flex;flex-direction:column;gap:18px}

/* ── DISPLAY TYPE — Playfair. The portal reached for Georgia everywhere; the
 * instinct was right and the execution was a system fallback. ── */
.display{font-family:var(--serif);font-weight:600;letter-spacing:-.005em;line-height:1.15;color:var(--ink);margin:0}
.greet{font-family:var(--serif);font-weight:600;font-size:30px;line-height:1.15;margin:4px 0 20px;color:var(--ink);letter-spacing:-.005em}
@media(max-width:640px){.greet{font-size:25px}}

/* ── BUTTONS — one gilt primary per view; everything else quiet. ──
 * The portal shipped a FILLED gold gradient on every action, which competes
 * with the status pill and the section heads. Regis's outline recipe is the
 * correct doctrine and is what ports. */
.btn{height:38px;padding:0 18px;border-radius:9px;font-weight:600;font-size:13px;letter-spacing:.02em;cursor:pointer;
  font-family:inherit;border:0;display:inline-flex;align-items:center;justify-content:center;gap:7px;background:none;color:var(--ink-2);
  transition:background var(--t-fast) var(--ease-out),border-color var(--t-fast) var(--ease-out),box-shadow var(--t-fast) var(--ease-out),transform 100ms var(--ease-out)}
.btn.primary{color:var(--gold-bright);border:1px solid rgba(212,175,55,.8);
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,0) 45%),rgba(212,175,55,.09)}
.btn.primary:hover{background:linear-gradient(180deg,rgba(255,255,255,.06),rgba(255,255,255,0) 45%),rgba(212,175,55,.2);box-shadow:0 6px 22px rgba(212,175,55,.16)}
html[data-theme="light"] .btn.primary,html[data-theme="beige"] .btn.primary{color:var(--gold-deep);border-color:rgba(138,110,47,.75);
  background:linear-gradient(180deg,rgba(255,255,255,.6),rgba(255,255,255,0) 45%),rgba(201,168,76,.13)}
html[data-theme="light"] .btn.primary:hover,html[data-theme="beige"] .btn.primary:hover{background:rgba(201,168,76,.24)}
.btn.ghost{background:transparent;color:var(--ink-2);border:1px solid var(--border)}
.btn.ghost:hover{border-color:rgba(201,168,76,.55);color:var(--champagne);background:rgba(201,168,76,.05)}
.btn:active{transform:scale(.97);transition-duration:60ms}
/* Regis has NO :disabled styling at all — a real gap, not a thing to port. */
.btn:disabled,.btn[aria-disabled="true"]{opacity:.5;cursor:not-allowed;transform:none;box-shadow:none}
.btn.wide{width:100%}

/* ── LINKS ── */
.linkish{color:var(--link);cursor:pointer;font-weight:600;text-decoration:none;background:none;border:0;font-family:inherit;font-size:inherit;padding:0}
.linkish:hover{text-decoration:underline;text-underline-offset:3px}

/* ── PILLS — the outline lozenge. Calm, because the thing it labels is the
 * status of someone's lawsuit. Categorical, never severity-graded: the
 * private-bank rule is no traffic lights. ── */
.pill{display:inline-block;font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;padding:3px 10px;
  border-radius:20px;white-space:nowrap;border:1px solid transparent;
  background:rgba(201,168,76,.1);border-color:rgba(201,168,76,.4);color:var(--champagne)}
.pill.quiet{background:rgba(125,169,216,.1);border-color:rgba(125,169,216,.35);color:var(--blue)}
.pill.new{background:rgba(201,168,76,.16);border-color:rgba(201,168,76,.5);color:var(--gold-bright)}

/* ── SUBTABS — the whole navigation on the client side. matters.html:367 ── */
.subtabs{display:flex;gap:4px;border-bottom:1px solid var(--border-2);margin:0 0 20px;overflow-x:auto;scrollbar-width:none}
.subtabs::-webkit-scrollbar{display:none}
.subtabs button{padding:12px 16px;font-size:13px;letter-spacing:.03em;color:var(--muted);cursor:pointer;
  border:0;border-bottom:2px solid transparent;margin-bottom:-1px;font-weight:600;background:none;font-family:inherit;white-space:nowrap;
  transition:color var(--t-fast) var(--ease-out)}
.subtabs button:hover{color:var(--ink)}
.subtabs button.on{color:var(--gold-bright);border-bottom-color:var(--gold)}

/* ── KEY/VALUE ROWS — the client's case summary. NEVER a <table>: Regis tables
 * do not reflow and on a 375px screen a case summary becomes a horizontal
 * scroller. flex-wrap + a left-aligned value below 480px instead. ── */
.kv{display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;padding:11px 0;border-bottom:1px solid var(--border-2)}
.kv:last-child{border-bottom:0}
.kv .k{color:var(--muted);font-size:13px}
.kv .v{font-weight:600;text-align:right;font-size:14px;color:var(--ink);min-width:0;overflow-wrap:anywhere}
@media(max-width:480px){.kv{gap:2px}.kv .v{text-align:left;flex-basis:100%}}

/* ── STAT ROW — gradient numerals, struck in metal. matters.html:426 ── */
.stat-row{display:grid;grid-template-columns:repeat(3,1fr);border-radius:14px;overflow:hidden;background:var(--slab);box-shadow:var(--slab-ring)}
@media(max-width:640px){.stat-row{grid-template-columns:1fr}}
.stat{padding:20px 24px 18px;position:relative}
.stat+.stat:before{content:'';position:absolute;left:0;top:16px;bottom:16px;width:1px;background:linear-gradient(180deg,transparent,rgba(201,168,76,.22),transparent)}
@media(max-width:640px){.stat+.stat:before{left:16px;right:16px;top:0;bottom:auto;width:auto;height:1px;background:linear-gradient(90deg,transparent,rgba(201,168,76,.22),transparent)}}
.stat .k{font-size:10px;color:var(--muted);font-weight:600;text-transform:uppercase;letter-spacing:.16em}
.stat .v{font-family:var(--serif);font-size:30px;font-weight:600;margin-top:8px;line-height:1.1;font-variant-numeric:tabular-nums;
  background:linear-gradient(160deg,#f0ddad 0%,#D4AF37 48%,#f5ead0 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
html[data-theme="light"] .stat .v,html[data-theme="beige"] .stat .v{
  background:linear-gradient(160deg,#a8842e 0%,#6e5517 48%,#8a6e2f 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}

/* ── TABLES — the ledger. STAFF SIDE ONLY. overflow-x must stay scrollable:
 * clipping it once silently swallowed 134px of table in Regis with no
 * scrollbar to reveal it. ── */
.tablecard{border-radius:14px;overflow-x:auto;overflow-y:hidden;background:var(--slab);box-shadow:var(--slab-ring)}
.tablecard table{width:100%;border-collapse:collapse}
.tablecard thead th{text-align:left;font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--champagne);font-weight:600;
  padding:14px 20px;border-bottom:1px solid var(--hairline-gold);white-space:nowrap;user-select:none}
.tablecard tbody td{padding:15px 20px;border-bottom:1px solid var(--border-2);font-size:13.5px;vertical-align:middle}
.tablecard tbody tr:last-child td{border-bottom:0}
.tablecard tbody tr{cursor:pointer;transition:background var(--t-instant) linear}
.tablecard tbody tr:hover td{background:rgba(255,255,255,.028)}
html[data-theme="light"] .tablecard tbody tr:hover td,html[data-theme="beige"] .tablecard tbody tr:hover td{background:rgba(74,58,28,.045)}
.tablecard tbody tr:hover td:first-child{box-shadow:inset 2px 0 0 rgba(201,168,76,.6)}
/* Regis rows are <tr onclick> and unreachable by keyboard. These are focusable. */
.tablecard tbody tr:focus-visible{outline:2px solid var(--focus-ring);outline-offset:-2px}
.mlink{color:var(--link);font-weight:600}

/* ── LIST ROWS — the staff inbox. A table would not reflow; this does. ── */
.lrow{display:flex;justify-content:space-between;gap:16px;padding:15px 6px;border-bottom:1px solid var(--border-2);
  cursor:pointer;text-align:left;width:100%;background:none;border-left:0;border-right:0;border-top:0;font-family:inherit;color:inherit;
  transition:background var(--t-instant) linear}
.lrow:last-child{border-bottom:0}
.lrow:hover{background:rgba(201,168,76,.05)}
.lrow .t{font-weight:600;font-size:14px;color:var(--ink)}
.lrow .s{color:var(--muted);font-size:12.5px;margin-top:3px;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.lrow .b{color:var(--muted);font-size:11.5px;margin-top:4px}
.lrow .rt{text-align:right;white-space:nowrap;flex:0 0 auto;display:flex;flex-direction:column;align-items:flex-end;gap:5px}
.lrow .rt .ts{color:var(--muted);font-size:11.5px}
@media(max-width:560px){.lrow{flex-direction:column;gap:8px}.lrow .rt{flex-direction:row;align-items:center;text-align:left}}

/* ── MESSAGES ─────────────────────────────────────────────────────────────── */
.msgs{display:flex;flex-direction:column;gap:12px;max-height:56dvh;overflow-y:auto;padding-right:4px;overscroll-behavior:contain}
/* pre-wrap lives on .bd, NOT on .msg. On .msg it also preserves the newlines and
   indentation of the template literal that builds the bubble, which silently
   indented every message body by the width of the source file's indent. */
.msg{padding:11px 14px;border-radius:12px;font-size:14px;line-height:1.6;max-width:80%;overflow-wrap:anywhere;
  background:var(--soft);border:1px solid var(--border-2)}
.msg .bd{white-space:pre-wrap}
.msg.mine{align-self:flex-end;background:rgba(201,168,76,.1);border-color:rgba(201,168,76,.32)}
.msg.theirs{align-self:flex-start}
/* The separator lives INSIDE .nm so it can never orphan at the start of a
   wrapped line. An earlier attempt used white-space:nowrap instead, which made
   83 of 84 attributions truncate at 375px — and since the ellipsis is at the
   end, the TIMESTAMP was what disappeared. Wrapping is the lesser evil. */
.msg .meta{font-size:12px;color:var(--muted);margin-bottom:5px;letter-spacing:.01em}
.msg .meta .nm{white-space:nowrap}
@media(max-width:560px){.msg{max-width:92%}}
/* A system event is not something a person said, so it must not look like a
 * chat bubble. Regis's timeline marker is the better model than a bordered band. */
.msg.system{align-self:stretch;max-width:100%;background:none;border:0;text-align:center;padding:14px 8px 12px;position:relative;color:var(--champagne);font-size:13.5px}
.msg.system:before{content:'';position:absolute;left:8%;right:8%;top:0;height:1px;background:linear-gradient(90deg,transparent,var(--hairline-gold),transparent)}
.msg.system .meta{color:var(--muted);margin-bottom:4px}

/* ── COMPOSER ── */
.composer{margin-top:16px}
.composer textarea{width:100%;border:1px solid var(--border-strong);border-radius:10px;padding:12px;font-family:inherit;font-size:14px;
  resize:vertical;min-height:64px;background:var(--input);color:var(--ink);
  transition:border-color var(--t-fast) var(--ease-out),box-shadow var(--t-fast) var(--ease-out)}
.composer textarea:focus{border-color:rgba(201,168,76,.6);box-shadow:0 0 0 3px rgba(201,168,76,.12)}
.composer .row{display:flex;gap:10px;align-items:center;margin-top:10px;flex-wrap:wrap}
.composer .sp{flex:1}

/* ── FORM CONTROLS ── */
label.fl{display:block;font-size:10.5px;font-weight:600;color:var(--champagne);text-transform:uppercase;letter-spacing:.16em;margin:0 0 7px}
input[type=text],input[type=email],input[type=password],select,textarea{
  width:100%;border:1px solid var(--border-strong);border-radius:9px;padding:11px;font-family:inherit;font-size:14px;
  background:var(--input);color:var(--ink);
  transition:border-color var(--t-fast) var(--ease-out),box-shadow var(--t-fast) var(--ease-out)}
input:focus,select:focus,textarea:focus{border-color:rgba(201,168,76,.65);box-shadow:0 0 0 3px rgba(201,168,76,.13)}
input::placeholder,textarea::placeholder{color:var(--muted)}
.fld{margin-bottom:16px}

/* ── FEEDBACK — the portal's inline error box is BETTER than Regis, which has
 * no inline error state at all (toast + focus only, one gold slab for both a
 * success and a failure). Kept, restyled, and given role="alert" in markup. ── */
.err,.ok{border-radius:9px;padding:11px 14px;font-size:13.5px;line-height:1.55;margin-top:14px;display:none}
.err.show,.ok.show{display:block}
.err{background:rgba(224,122,104,.1);border:1px solid rgba(224,122,104,.5);color:var(--red)}
.ok{background:rgba(79,174,118,.1);border:1px solid rgba(79,174,118,.5);color:var(--green)}
html[data-theme="light"] .err,html[data-theme="beige"] .err{color:var(--red)}
.note{color:var(--muted);font-size:12.5px;line-height:1.6;margin-top:10px}
.banner{border-radius:10px;padding:14px 16px;font-size:13.5px;line-height:1.65;margin-bottom:18px;
  background:rgba(201,168,76,.08);border:1px solid rgba(201,168,76,.35);color:var(--ink-2)}
.banner b{color:var(--champagne)}

/* ── EMPTY + LOADING ──────────────────────────────────────────────────────── */
.empty-state{text-align:center;padding:56px 20px;color:var(--muted);font-size:14px;line-height:1.7}
.empty-state .ic{font-size:34px;margin-bottom:12px;opacity:.45;line-height:1}
.empty-state .cta{margin-top:18px}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.45}}
.sk{background:rgba(255,255,255,.06);border-radius:6px;animation:pulse 1400ms ease-in-out infinite}
html[data-theme="light"] .sk,html[data-theme="beige"] .sk{background:rgba(74,58,28,.09)}
.sk-line{height:14px;margin:0 0 10px}
/* A skeleton has no text and therefore cannot be in the wrong language — which
 * is why it replaces the hardcoded English "Loading your case…" the Spanish
 * client used to see as their very first paint. */

/* ── DOCUMENTS ── */
.doc{display:flex;justify-content:space-between;align-items:center;gap:14px;padding:12px 0;border-bottom:1px solid var(--border-2);font-size:14px}
.doc:last-child{border-bottom:0}
.doc .n{color:var(--ink);overflow-wrap:anywhere;font-weight:500}
.doc .s{color:var(--muted);font-size:12px;margin-top:3px}
.doc a{color:var(--link);text-decoration:none;font-size:12.5px;font-weight:600;white-space:nowrap;
  border:1px solid var(--border);border-radius:8px;padding:7px 13px;transition:border-color var(--t-fast) var(--ease-out),background var(--t-fast) var(--ease-out)}
.doc a:hover{border-color:rgba(201,168,76,.55);background:rgba(201,168,76,.06);color:var(--gold-bright)}
@media(max-width:480px){.doc{flex-direction:column;align-items:flex-start;gap:9px}}
/* A file input is invisible to the keyboard once display:none'd and wrapped in
 * a label. Clipped instead of hidden so it keeps focus and a focus ring. */
.filein{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.filein:focus-visible+.uplabel{outline:2px solid var(--focus-ring);outline-offset:2px}
.uplabel{display:inline-flex;align-items:center;gap:7px;height:38px;padding:0 18px;border-radius:9px;font-weight:600;font-size:13px;
  cursor:pointer;color:var(--ink-2);border:1px solid var(--border);transition:border-color var(--t-fast) var(--ease-out),background var(--t-fast) var(--ease-out)}
.uplabel:hover{border-color:rgba(201,168,76,.55);color:var(--champagne);background:rgba(201,168,76,.05)}

/* ── TIMELINE — matters.html:462. Makes "your case moved to a new stage" feel
 * like a milestone rather than an interruption. ── */
.tl{position:relative;padding-left:24px}
.tl:before{content:'';position:absolute;left:6px;top:6px;bottom:6px;width:1px;background:linear-gradient(180deg,rgba(201,168,76,.35),rgba(255,255,255,.07))}
.ev{position:relative;padding:0 0 17px}
.ev:before{content:'';position:absolute;left:-22px;top:4px;width:10px;height:10px;border-radius:50%;background:var(--card);border:1.5px solid var(--muted)}
.ev.gold:before{border-color:var(--gold);box-shadow:0 0 8px rgba(201,168,76,.35)}
.ev .who{font-size:13px;font-weight:600;color:var(--ink)}
.ev .tx{font-size:13.5px;line-height:1.55;margin-top:4px;color:var(--ink-2)}
.ev .ts{font-size:11.5px;color:var(--muted);margin-top:3px}

/* ── SEGMENTED CONTROL — theme + language switchers ─────────────────────────
 * Regis puts theme in a settings modal. A client will never look there, so it
 * sits in the open — and a client who cannot read the page is not going to hunt
 * for the control that fixes it. */
.seg{display:inline-flex;flex:0 0 auto;border:1px solid var(--border-strong);border-radius:9px;overflow:hidden;background:var(--input)}
.seg button{border:0;background:none;font-family:inherit;font-size:11.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);padding:7px 11px;cursor:pointer;transition:background var(--t-fast) var(--ease-out),color var(--t-fast) var(--ease-out)}
.seg button+button{border-left:1px solid var(--border)}
.seg button:hover{color:var(--ink);background:rgba(201,168,76,.06)}
.seg button.on{color:var(--gold-bright);background:rgba(201,168,76,.14)}
.seg.sm button{padding:6px 9px;font-size:11px}

/* ── FOCUS — matters.html:720. The portal did outline:none on inputs and gave
 * buttons, links and tabs nothing at all. ── */
:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px;border-radius:6px}
.skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--elev);color:var(--ink);padding:10px 16px;border-radius:0 0 9px 0;
  border:1px solid var(--hairline-gold);font-size:13px;font-weight:600;text-decoration:none}
.skip:focus{left:0}

::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-thumb{background:#232e46;border-radius:8px;border:2px solid var(--canvas)}
::-webkit-scrollbar-thumb:hover{background:var(--gold-deep)}
html[data-theme="light"] ::-webkit-scrollbar-thumb,html[data-theme="beige"] ::-webkit-scrollbar-thumb{background:rgba(74,58,28,.3)}

/* ── CLIENT TYPE SCALE ──────────────────────────────────────────────────────
 * Regis's 10-10.5px small-caps at .2em tracking is correct density for a
 * ledger read by someone who is in it every day. On a page where a client reads
 * about their own legal matter — often on a phone, often older — it is the
 * single biggest readability problem. Same idiom, raised ~1.25x. Costs nothing. */
body.is-client{font-size:15px}
body.is-client .ct{font-size:12px;letter-spacing:.14em}
body.is-client .pill{font-size:11px;letter-spacing:.08em;padding:4px 12px}
body.is-client .msg .meta{font-size:12px}
body.is-client .kv .k{font-size:14px}
body.is-client .kv .v{font-size:15px}
body.is-client .note{font-size:13px}
body.is-client label.fl{font-size:11.5px;letter-spacing:.14em}
body.is-client .stat .k{font-size:11px;letter-spacing:.14em}
body.is-client .doc{font-size:14.5px}
body.is-client .doc .s{font-size:12.5px}

/* ── PRINT — clients print case summaries. Regis has no print styles at all,
 * so a Regis-style port would emit one clipped viewport. ── */
@media print{
  /* Redefine the TOKENS, not two selectors. Forcing the paper white while the
     dark palette still resolves left --ink at #f2efe6 = 1.15:1 on white: a
     client in OS dark mode printed a column of labels with blank space beside
     every value. Every theme is pinned to ink-on-paper here. */
  :root,html[data-theme="dark"],html[data-theme="light"],html[data-theme="beige"]{
    --canvas:#fff; --card:#fff; --soft:#fff; --elev:#fff;
    --ink:#000; --ink-2:#1a1a1a; --muted:#3a3a3a; --faint:#4a4a4a;
    --gold:#5a4416; --gold-bright:#5a4416; --champagne:#5a4416; --gold-deep:#5a4416;
    --link:#000; --cyan:#5a4416;
    --border:#bbb; --border-2:#ddd; --hairline-gold:#bbb;
    --slab:none; --slab-ring:none;
  }
  .atmo,.top,.tbar,.subtabs,.composer,.uplabel,.filein,.seg,.skip,.btn,.doc a{display:none!important}
  html,body{background:#fff!important;color:#000!important}
  body{font-size:11pt}
  .card{box-shadow:none!important;border:1px solid #bbb!important;background:#fff!important;break-inside:avoid;margin-bottom:12pt}
  /* background-clip:text + transparent fill prints as nothing. Six rules use it;
     these are the two that carry content a client needs on paper. */
  .stat .v,.wordmark .bname{background:none!important;-webkit-text-fill-color:#000!important;color:#000!important}
  .pill{border-color:#666!important;background:none!important}
  .msgs{max-height:none!important;overflow:visible!important}
  .msg{max-width:100%!important;break-inside:avoid;border-color:#ccc!important}
  .msg.system:before{background:#bbb!important}
  .wrap{max-width:none;padding:0}
  a[href]:after{content:""}
}
