/* Madam Legal Design System, material and core components.
   Requires tokens.css. Import order matters: tokens first.

   THE RULE THIS FILE ENFORCES: glass for chrome, solid for consequence.
   .g and .g-chrome are for navigation, panels and ambience.
   .solid is for credentials, bar standing, contact details and forms —
   anything a visitor decides whether to retain counsel on.

   Both themes are served by the tokens; nothing here is theme-specific. */

/* ═══════════════ THE GLASS MATERIAL ═══════════════
   Six layers. Removing any one collapses it into a flat frosted panel,
   which is the thing Liquid Glass specifically is not:
   1 refraction  2 tint  3 pointer specular  4 lens bevel
   5 chromatic rim  6 cast shadow

   The specular is champagne (--spec-gold), not white: on a noir ground a
   white highlight reads as a screen reflection, a gold one reads as light
   moving across metal. That single substitution is most of what separates
   this material from a generic frosted panel.                        */
.g,
.g-panel,
.glass-card {
  position: relative;
  background:
    radial-gradient(140% 110% at var(--mx,50%) var(--my,-10%), var(--spec-gold), transparent 58%),
    var(--tint-panel);
  -webkit-backdrop-filter: blur(var(--blur-panel)) saturate(var(--sat)) brightness(var(--bright));
          backdrop-filter: blur(var(--blur-panel)) saturate(var(--sat)) brightness(var(--bright));
  border-radius: var(--r-lg);
  box-shadow:
    inset 0 1px 0 var(--lens-top),
    inset 0 26px 44px -34px var(--lens-top),
    inset 0 -26px 44px -30px var(--lens-bot),
    var(--shadow-glass);
}
.g::before,
.g-panel::before,
.glass-card::before { /* specular rim */
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px;
  background: linear-gradient(135deg, var(--edge-bright) 0%, var(--edge-mid) 34%,
              var(--edge-dim) 58%, var(--edge-mid) 76%, var(--edge-bright) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  pointer-events: none; z-index: 1;
}
.g::after,
.g-panel::after,
.glass-card::after { /* chromatic aberration */
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  box-shadow: inset 1.5px 0 0 var(--ca-cool), inset -1.5px 0 0 var(--ca-warm),
              inset 0 -1px 0 var(--ca-warm);
  z-index: 1;
}
.g > *,
.g-panel > *,
.glass-card > * { position: relative; z-index: 2; }

.g-chrome,
.glass-nav {
  --blur-panel: var(--blur-chrome);
  background:
    radial-gradient(140% 110% at var(--mx,50%) var(--my,-10%), var(--spec-gold), transparent 58%),
    var(--tint-chrome);
}

/* Bedrock. Credentials, bar standing, contact details, long-form prose.
   Opaque by definition: the 7:1 credentials floor is computed against this
   surface, and a translucent ground makes that ratio unknowable. */
.solid,
.solid-card {
  background: var(--ink-700);
  border: 1px solid var(--gold-800);
  border-radius: var(--r-lg);
  backdrop-filter: none; -webkit-backdrop-filter: none;
}

/* Fallback: the interface must be complete and brand-correct with no glass. */
@supports not (backdrop-filter: blur(1px)) {
  .g, .g-panel, .glass-card, .g-chrome, .glass-nav { background: var(--ink-800); }
}

/* ═══════════════ GLASS COMPONENTS ═══════════════
   Promoted from site/assets/css/glass-tokens.css, which reimplemented the
   material against variables that only existed in main.css and so could not
   be used outside those two pages. These are self-contained. */

.btn-glass {
  position: relative;
  overflow: hidden;
  font-family: var(--f-ui);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-6);
  border-radius: var(--r-pill);
  border: 1px solid var(--gold-700);
  background: linear-gradient(180deg, var(--tint-panel-gold), var(--tint-chrome));
  color: var(--ink-050);
  -webkit-backdrop-filter: blur(16px);
          backdrop-filter: blur(16px);
  cursor: pointer;
  transition: border-color var(--quick) var(--liquid),
              background var(--quick) var(--liquid),
              transform var(--quick) var(--liquid),
              box-shadow var(--quick) var(--liquid);
  box-shadow: inset 0 1px 0 var(--lens-top), 0 4px 20px var(--lens-bot);
}
.btn-glass:hover {
  border-color: var(--gold-500);
  color: var(--ink-050);
  transform: translateY(-2px);
}

/* Primary is a gold fill, so its label uses --on-gold, which flips to white
   in Ivory. Hardcoding near-black here would fail contrast on the dark gold. */
.btn-glass-primary {
  background: linear-gradient(180deg, var(--gold-300), var(--gold-500));
  color: var(--on-gold);
  font-weight: 700;
  border: 1px solid var(--gold-300);
  box-shadow: inset 0 1px 0 var(--lens-top), 0 4px 25px var(--lens-bot);
}
.btn-glass-primary:hover {
  background: linear-gradient(180deg, var(--gold-200), var(--gold-300));
  color: var(--on-gold);
  transform: translateY(-2px);
}

/* Credential tile. The figure uses --credential-figure, never --gold-500:
   brand gold is 6.69:1 on bedrock and misses the 7:1 credentials floor. */
.glass-stat-tile {
  padding: var(--space-6);
  border-radius: var(--r-md);
  background: var(--tint-panel);
  -webkit-backdrop-filter: blur(20px);
          backdrop-filter: blur(20px);
  border: 1px solid var(--gold-800);
  transition: border-color var(--quick) ease, transform var(--quick) ease;
}
.glass-stat-tile:hover {
  border-color: var(--gold-700);
  transform: translateY(-3px);
}
.glass-stat-tile .figure {
  font-family: var(--f-display);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
  color: var(--credential-figure);
}
.glass-stat-tile .label {
  font-family: var(--f-ui);
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
  color: var(--credential-label);
}

.glass-input {
  width: 100%;
  padding: var(--space-4) var(--space-5);
  background: var(--tint-chrome);
  border: 1px solid var(--gold-800);
  border-radius: var(--r-sm);
  color: var(--ink-050);
  font-family: var(--f-text);
  font-size: 16px; /* iOS zooms the viewport on focus below 16px. */
  -webkit-backdrop-filter: blur(12px);
          backdrop-filter: blur(12px);
  transition: border-color var(--quick) ease, background var(--quick) ease;
}
.glass-input:focus {
  outline: 2px solid var(--gold-500);
  outline-offset: 2px;
  border-color: var(--gold-500);
  background: var(--tint-panel);
}

/* ═══════════════ TYPE ═══════════════
   Tabular numerals on every figure and date. Proportional digits make a
   column of years or a set of credential figures ragged, and a figure that
   shifts as it changes reads as an estimate rather than a fact. */
.numeric, .metric, .score, td.n {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}

/* ═══════════════ CHIPS ═══════════════
   NEVER colour alone. Icon or text label plus colour, always.
   These carry system state — a file accepted, a form field rejected — and
   are not for describing a practice: a chip that renders a claim about the
   work belongs inside the solicitation perimeter and needs a component. */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px 5px 9px; border-radius: var(--r-pill);
  font-family: var(--f-ui); font-size: 12.5px; font-weight: 500; line-height: 1;
  border: 1px solid; white-space: nowrap;
}
.chip svg { width: 13px; height: 13px; flex: none; }
.c-positive { background: color-mix(in srgb, var(--positive) 13%, transparent); border-color: color-mix(in srgb, var(--positive) 33%, transparent); color: var(--positive); }
.c-caution  { background: color-mix(in srgb, var(--caution) 13%, transparent);  border-color: color-mix(in srgb, var(--caution) 33%, transparent);  color: var(--caution); }
.c-critical { background: color-mix(in srgb, var(--critical) 13%, transparent); border-color: color-mix(in srgb, var(--critical) 33%, transparent); color: var(--critical); }
.c-neutral  { background: color-mix(in srgb, var(--ink-200) 8%, transparent);   border-color: var(--ink-600);                                       color: var(--ink-100); }

/* ═══════════════ BUTTONS ═══════════════ */
.btn {
  position: relative; overflow: hidden;
  font-family: var(--f-ui); font-weight: 600; font-size: 13.5px; letter-spacing: .005em;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 18px; min-height: 38px;
  border-radius: var(--r-pill); border: 1px solid transparent; cursor: pointer;
  transition: transform var(--quick) var(--spring),
              background var(--quick) var(--liquid),
              border-color var(--quick) var(--liquid),
              color var(--quick) var(--liquid);
}
.btn svg { width: 15px; height: 15px; flex: none; }
.btn:active { transform: scale(.97); }
.btn:disabled { opacity: .4; cursor: not-allowed; transform: none; }
.btn:focus-visible { outline: 2px solid var(--gold-400); outline-offset: 2px; }

.b-pri {
  background: linear-gradient(180deg, var(--gold-400), var(--gold-500));
  color: var(--on-gold);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.45), 0 2px 10px -2px rgba(202,153,89,.5);
}
.b-pri:hover { background: linear-gradient(180deg, var(--gold-500), var(--gold-600)); }
.b-sec { background: var(--ink-700); color: var(--ink-100); border-color: var(--ink-600); }
.b-sec:hover { border-color: var(--gold-600); background: var(--ink-600); }
.b-ghost { background: transparent; color: var(--ink-200); }
.b-ghost:hover { background: var(--ink-800); color: var(--ink-100); }
.b-danger { background: var(--critical); color: #fff; }
.b-sm { font-size: 12.5px; padding: 6px 13px; min-height: 32px; }
.b-lg { font-size: 15px; padding: 12px 24px; min-height: 46px; }

/* ═══════════════ FORMS ═══════════════
   Inputs are Bedrock, never glass. A field someone is typing bank details
   into must not have content moving behind it. */
.field { display: flex; flex-direction: column; gap: 6px; }
/* Manrope, explicitly. These inherited whatever face the host page set, so a
   form dropped into an editorial page rendered its labels in Newsreader —
   correct-looking enough that nobody would file it, and wrong. */
.lab { font-family: var(--f-ui); font-size: 12.5px; font-weight: 600; color: var(--ink-200); }
.hint { font-family: var(--f-ui); font-size: 11.5px; color: var(--ink-300); }
.err { font-family: var(--f-ui); font-size: 11.5px; color: var(--critical); display: flex; align-items: center; gap: 5px; }
.inp {
  font-family: var(--f-ui); font-size: 14px; padding: 10px 13px; width: 100%;
  background: var(--ink-850); border: 1px solid var(--ink-600);
  border-radius: var(--r-sm); color: var(--ink-100);
  transition: border-color var(--quick) var(--liquid), box-shadow var(--quick) var(--liquid);
}
.inp::placeholder { color: var(--ink-400); }
.inp:focus { outline: none; border-color: var(--gold-500); box-shadow: 0 0 0 3px rgba(202,153,89,.18); }
.inp.bad { border-color: var(--critical); }

/* ═══════════════ MOTION ═══════════════
   Money-state changes commit. They never morph, bounce or celebrate. */
@keyframes commit { from { opacity: 0; transform: translateY(2px); } }
.commit { animation: commit var(--commit) var(--liquid); }

/* ═══════════════ ACCESSIBILITY ═══════════════ */
@media (prefers-reduced-transparency: reduce) {
  .g, .g-chrome { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--ink-800); }
  .g::before { background: var(--ink-600); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ════════════════════════════════════════════════════════════════
   PART 2: full component surface, matching styleguide.html
   Everything below is consumed by the React library in react/.
   ════════════════════════════════════════════════════════════════ */

/* ── loading spinner (used by Button loading state) ── */
.spin { width:15px; height:15px; border:2px solid currentColor; border-right-color:transparent;
  border-radius:50%; animation:spin .7s linear infinite; flex:none; }
@keyframes spin { to { transform:rotate(360deg); } }

/* ── button extras ── */
.b-glass { background:var(--tint-chrome); color:var(--ink-100); border-color:var(--edge-mid);
  -webkit-backdrop-filter:blur(20px) saturate(var(--sat)); backdrop-filter:blur(20px) saturate(var(--sat));
  box-shadow:inset 0 1px 0 var(--lens-top); }
.b-icon { padding:0; width:38px; height:38px; }
.b-icon.b-sm { width:32px; height:32px; }
.ripple { position:absolute; border-radius:50%; transform:scale(0); background:rgba(255,255,255,.4);
  pointer-events:none; animation:ripple 560ms var(--liquid); }
@keyframes ripple { to { transform:scale(3.2); opacity:0; } }

/* ── forms ── */
textarea.inp { resize:vertical; min-height:84px; font-family:var(--f-ui); }
select.inp { appearance:none; padding-right:34px;
  background-image:linear-gradient(45deg,transparent 50%,var(--ink-300) 50%),
                   linear-gradient(135deg,var(--ink-300) 50%,transparent 50%);
  background-position:calc(100% - 17px) 50%, calc(100% - 12px) 50%;
  background-size:5px 5px,5px 5px; background-repeat:no-repeat; }
.inp-ic { position:relative; display:flex; align-items:center; }
.inp-ic > svg { position:absolute; left:12px; width:15px; height:15px; color:var(--ink-400); pointer-events:none; }
.inp-ic .inp { padding-left:35px; }

.check { display:flex; align-items:flex-start; gap:9px; cursor:pointer;
  font-family:var(--f-ui); font-size:14px; line-height:1.5; color:var(--ink-200); }
.check input { position:absolute; opacity:0; width:0; height:0; }
.box { width:18px; height:18px; border-radius:5px; border:1.5px solid var(--ink-500); flex:none;
  margin-top:1px; display:grid; place-items:center; background:var(--ink-850);
  transition:all var(--quick) var(--spring); }
.box svg { width:11px; height:11px; color:var(--on-gold); opacity:0; transform:scale(.5);
  transition:all var(--quick) var(--spring); }
.check input:checked + .box { background:var(--gold-500); border-color:var(--gold-500); }
.check input:checked + .box svg { opacity:1; transform:scale(1); }
.check input:focus-visible + .box,
.check input:focus-visible + .sw { outline:2px solid var(--gold-400); outline-offset:2px; }
.box.radio { border-radius:50%; }
.box.radio i { width:7px; height:7px; border-radius:50%; background:var(--on-gold); opacity:0;
  transform:scale(.4); transition:all var(--quick) var(--spring); display:block; }
.check input:checked + .box.radio i { opacity:1; transform:scale(1); }

.sw { position:relative; width:44px; height:26px; border-radius:var(--r-pill); background:var(--ink-600);
  flex:none; cursor:pointer; transition:background var(--commit) var(--liquid); }
.sw::after { content:""; position:absolute; top:3px; left:3px; width:20px; height:20px; border-radius:50%;
  background:var(--ink-100); box-shadow:0 1px 3px rgba(0,0,0,.4);
  transition:transform var(--commit) var(--spring); }
.check input:checked + .sw { background:var(--gold-500); }
.check input:checked + .sw::after { transform:translateX(18px); background:var(--on-gold); }

.range { -webkit-appearance:none; appearance:none; width:100%; height:5px; border-radius:var(--r-pill);
  outline:none; background:linear-gradient(90deg,var(--gold-500) var(--pct,50%),var(--ink-600) var(--pct,50%)); }
.range::-webkit-slider-thumb { -webkit-appearance:none; width:19px; height:19px; border-radius:50%;
  background:var(--ink-100); border:2px solid var(--gold-500); cursor:pointer;
  box-shadow:0 1px 4px rgba(0,0,0,.45); }
.range::-moz-range-thumb { width:19px; height:19px; border-radius:50%; background:var(--ink-100);
  border:2px solid var(--gold-500); cursor:pointer; }

.otp { display:flex; gap:var(--space-2); }
.otp input { width:44px; height:52px; text-align:center; font-family:var(--f-mono); font-size:19px;
  background:var(--ink-850); border:1px solid var(--ink-600); border-radius:var(--r-sm); color:var(--ink-100); }
.otp input:focus { outline:none; border-color:var(--gold-500); box-shadow:0 0 0 3px rgba(202,153,89,.18); }

/* ── file upload ── */
.drop { border:1.5px dashed var(--ink-500); border-radius:var(--r-md); padding:var(--space-6);
  display:flex; flex-direction:column; align-items:center; gap:var(--space-2); text-align:center;
  background:var(--ink-850); cursor:pointer; transition:all var(--quick) var(--liquid); }
.drop:hover, .drop.over { border-color:var(--gold-500); background:rgba(202,153,89,.06); }
.drop > svg { width:26px; height:26px; color:var(--ink-400); }
.file-r { display:flex; align-items:center; gap:var(--space-3); padding:var(--space-3); border-radius:var(--r-sm);
  background:var(--ink-850); border:1px solid var(--ink-600); }
.file-r.bad { border-color:rgba(217,76,67,.4); }
.file-ic { width:32px; height:32px; border-radius:var(--r-xs); background:var(--ink-700);
  display:grid; place-items:center; flex:none; color:var(--gold-400); }
.file-m { display:flex; flex-direction:column; gap:2px; min-width:0; flex:1; }
.file-n { font-size:13px; color:var(--ink-100); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.file-s { font-family:var(--f-mono); font-size:10.5px; color:var(--ink-400); }

/* ── navigation ── */
.tabs { position:relative; display:flex; gap:var(--space-5); border-bottom:1px solid var(--ink-600); }
.tab { background:none; border:0; padding:10px 2px; font-family:var(--f-ui); font-size:14px;
  font-weight:500; color:var(--ink-300); cursor:pointer; transition:color var(--quick) var(--liquid); }
.tab[aria-selected="true"] { color:var(--ink-100); }
.tab:focus-visible { outline:2px solid var(--gold-400); outline-offset:2px; }
.tab-ind { position:absolute; bottom:-1px; height:2px; background:var(--gold-500); border-radius:2px;
  transition:transform var(--morph) var(--liquid), width var(--morph) var(--liquid); }

.seg { position:relative; display:inline-flex; padding:3px; border-radius:var(--r-pill);
  background:var(--ink-850); border:1px solid var(--ink-600); gap:2px; }
.seg-b { position:relative; z-index:1; font-family:var(--f-ui); font-size:12.5px; font-weight:500;
  padding:7px 15px; min-height:32px; border-radius:var(--r-pill); border:0; background:transparent;
  color:var(--ink-300); cursor:pointer; transition:color var(--quick) var(--liquid); }
.seg-b[aria-pressed="true"] { color:var(--on-gold); font-weight:600; }
.seg-b:focus-visible { outline:2px solid var(--gold-400); outline-offset:2px; }
.seg-pill { position:absolute; top:3px; bottom:3px; z-index:0; background:var(--gold-500);
  border-radius:var(--r-pill); transition:transform var(--morph) var(--liquid), width var(--morph) var(--liquid); }

.crumb { display:flex; align-items:center; gap:var(--space-2); font-size:13px; font-family:var(--f-ui); color:var(--ink-400); flex-wrap:wrap; }
.crumb a { color:var(--ink-300); text-decoration:none; }
.crumb a:hover { color:var(--gold-400); }
.crumb [aria-current] { color:var(--ink-100); }

.pag { display:flex; gap:var(--space-1); align-items:center; }
.pag button { width:32px; height:32px; border-radius:var(--r-sm); border:1px solid var(--ink-600);
  background:transparent; color:var(--ink-200); font-family:var(--f-mono); font-size:12.5px;
  cursor:pointer; transition:all var(--quick) var(--liquid); }
.pag button:hover { border-color:var(--gold-600); color:var(--ink-100); }
.pag button[aria-current] { background:var(--gold-500); border-color:var(--gold-500);
  color:var(--on-gold); font-weight:700; }

.steps { display:flex; align-items:flex-start; }
.step { display:flex; flex-direction:column; gap:7px; flex:1; min-width:0; }
.step-top { display:flex; align-items:center; width:100%; }
.step-dot { width:24px; height:24px; border-radius:50%; flex:none; display:grid; place-items:center;
  font-size:11px; font-weight:700; font-family:var(--f-mono); }
.step-line { height:2px; flex:1; background:var(--ink-600); }
.step-tx { font-size:12px; font-family:var(--f-ui); color:var(--ink-300); padding-right:var(--space-3); }
.s-done .step-dot { background:var(--gold-500); color:var(--on-gold); }
.s-done .step-line { background:var(--gold-500); }
.s-done .step-tx, .s-now .step-tx { color:var(--ink-100); }
.s-now .step-dot { background:transparent; border:2px solid var(--gold-500); color:var(--gold-400); }
.s-wait .step-dot { background:var(--ink-700); border:1px solid var(--ink-500); color:var(--ink-400); }

/* ── menus ── */
.menu-wrap { position:relative; display:inline-flex; }
.menu { position:absolute; top:calc(100% + 7px); left:0; min-width:210px; padding:var(--space-2);
  border-radius:var(--r-md); z-index:40; opacity:0; transform:translateY(-6px) scale(.97);
  pointer-events:none; transition:all var(--morph) var(--liquid);
  /* visibility, not just opacity: an invisible menu must also leave the tab
     order, or a keyboard user tabs into items they cannot see. */
  visibility:hidden; }
.menu.open { opacity:1; transform:none; pointer-events:auto; visibility:visible; }
.menu-i { display:flex; align-items:center; gap:var(--space-3); padding:8px 10px; width:100%;
  border-radius:var(--r-sm); font-size:13.5px; color:var(--ink-200); cursor:pointer; border:0;
  background:none; text-align:left; font-family:var(--f-ui);
  transition:background var(--quick) var(--liquid); }
.menu-i:hover { background:var(--edge-mid); color:var(--ink-100); }
.menu-i > svg { width:15px; height:15px; flex:none; color:var(--ink-400); }
.menu-i kbd { margin-left:auto; font-family:var(--f-mono); font-size:10px; color:var(--ink-400);
  border:1px solid var(--ink-600); border-radius:4px; padding:1px 5px; }
.menu-i.danger { color:var(--critical); }
.menu-sep { height:1px; background:var(--ink-600); margin:var(--space-2) 0; }

/* ── feedback ── */
.alert { display:flex; gap:var(--space-3); padding:var(--space-4); border-radius:var(--r-md); border:1px solid;
  align-items:flex-start; font-size:13.5px; line-height:1.55; }
.alert > svg { width:17px; height:17px; flex:none; margin-top:1px; }
.alert b { color:var(--ink-100); font-weight:600; }
/* Informational alerts carry no hue. The inherited palette used blue, which has
   no place in noir and champagne, and gold is brand and action only — never a
   status. A neutral tone plus the icon and label the Alert already requires is
   sufficient, and it is the only tone that reads correctly in both themes. */
.a-info { background:color-mix(in srgb, var(--ink-200) 8%, transparent); border-color:var(--ink-600); color:var(--ink-100); }
.a-ok   { background:color-mix(in srgb, var(--positive) 12%, transparent); border-color:color-mix(in srgb, var(--positive) 34%, transparent); color:var(--positive); }
.a-warn { background:color-mix(in srgb, var(--caution) 12%, transparent); border-color:color-mix(in srgb, var(--caution) 34%, transparent); color:var(--caution); }
.a-err  { background:color-mix(in srgb, var(--critical) 12%, transparent);  border-color:color-mix(in srgb, var(--critical) 34%, transparent);  color:var(--critical); }

.toast-wrap { position:fixed; bottom:var(--space-6); right:var(--space-6); z-index:200; display:flex;
  flex-direction:column; gap:var(--space-2); pointer-events:none; }
.toast { padding:var(--space-3) var(--space-4); display:flex; align-items:center; gap:var(--space-3);
  font-size:13.5px; color:var(--ink-100); min-width:260px; pointer-events:auto;
  animation:toast-in var(--morph) var(--liquid); }
@keyframes toast-in { from { opacity:0; transform:translateX(24px) scale(.96); } }
.toast.out { animation:toast-out var(--commit) var(--liquid) forwards; }
@keyframes toast-out { to { opacity:0; transform:translateX(24px) scale(.96); } }

.scrim { position:fixed; inset:0; background:rgba(4,5,7,.62); z-index:180; display:grid;
  place-items:center; padding:var(--space-6); animation:fade var(--commit) ease;
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px); }
@keyframes fade { from { opacity:0; } }
.modal { max-width:440px; width:100%; padding:var(--space-6); display:flex; flex-direction:column;
  gap:var(--space-4); animation:modal-in var(--morph) var(--liquid); }
@keyframes modal-in { from { opacity:0; transform:translateY(14px) scale(.97); filter:blur(6px); } }

.tip { position:relative; display:inline-flex; }
.tip-b { position:absolute; bottom:calc(100% + 8px); left:50%; padding:6px 10px; z-index:20;
  transform:translateX(-50%) translateY(4px); border-radius:var(--r-xs); font-size:12px;
  white-space:nowrap; color:var(--ink-100); opacity:0; pointer-events:none;
  transition:all var(--quick) var(--liquid); }
.tip:hover .tip-b, .tip:focus-within .tip-b { opacity:1; transform:translateX(-50%) translateY(0); }

.bar { height:6px; border-radius:var(--r-pill); background:var(--ink-600); overflow:hidden; }
.bar > i { display:block; height:100%; border-radius:var(--r-pill);
  background:linear-gradient(90deg,var(--gold-600),var(--gold-400));
  transition:width var(--morph) var(--liquid); }

.skel { border-radius:var(--r-xs); background-size:200% 100%; animation:shimmer 1.4s linear infinite;
  background-image:linear-gradient(90deg,var(--ink-700) 25%,var(--ink-600) 50%,var(--ink-700) 75%); }
@keyframes shimmer { to { background-position:-200% 0; } }

.empty { padding:var(--space-10) var(--space-6); display:flex; flex-direction:column; align-items:center;
  gap:var(--space-3); text-align:center; }
.empty-ic { width:44px; height:44px; border-radius:var(--r-md); background:var(--ink-800);
  display:grid; place-items:center; color:var(--ink-400); }

/* ── data display ── */
.stat { padding:var(--space-5); display:flex; flex-direction:column; gap:var(--space-2); }
.stat-l { font-size:11.5px; letter-spacing:.04em; color:var(--ink-400); text-transform:uppercase; font-weight:600; }
.stat-v { font-family:var(--f-display); font-size:29px; font-weight:600; color:var(--ink-100); letter-spacing:-.02em; }
.stat-d { font-size:12px; display:flex; align-items:center; gap:5px; }
.stat-up { color:var(--positive); } .stat-down { color:var(--critical); }

.av { width:34px; height:34px; border-radius:50%; display:grid; place-items:center; flex:none;
  font-size:12px; font-weight:700; font-family:var(--f-ui);
  background:linear-gradient(145deg,var(--gold-500),var(--gold-700)); color:var(--on-gold); }
.av-g { display:flex; }
.av-g .av { margin-left:-9px; border:2px solid var(--ink-900); }
.av-g .av:first-child { margin-left:0; }

/* ── utility ── */
.stack { display:flex; flex-direction:column; gap:var(--space-4); }
.stack-sm { display:flex; flex-direction:column; gap:var(--space-2); }
.row { display:flex; gap:var(--space-3); flex-wrap:wrap; align-items:center; }
.mono { font-family:var(--f-mono); font-size:12px; }

/* ═══════════════ EDITORIAL ═══════════════
   The magazine layer. Fraunces states, Newsreader speaks, Manrope labels. */

.eyebrow {
  display: flex; align-items: center; gap: var(--rhythm-3);
  font-family: var(--f-ui); font-size: var(--fs-eyebrow); line-height: var(--lh-eyebrow);
  font-weight: var(--fw-semibold); letter-spacing: var(--tr-eyebrow); text-transform: uppercase;
  color: var(--gold-500); margin-bottom: var(--rhythm-4);
}
.eyebrow::after { content: ""; height: 1px; flex: 1; background: var(--gold-700); }
.eyebrow--bare::after { display: none; }

.lede {
  font-family: var(--f-text); font-size: var(--fs-lede); line-height: var(--lh-lede);
  font-weight: var(--fw-regular); color: var(--ink-100); max-width: var(--measure-lede);
}

/* Newsreader italic, never Fraunces: the display face is for statements,
   the text face is for voice. */
.pq {
  font-family: var(--f-text); font-style: italic;
  font-size: var(--fs-pull-quote); line-height: var(--lh-pull-quote);
  font-weight: var(--fw-regular); letter-spacing: -.01em;
  color: var(--ink-050); max-width: var(--measure-lede);
  border-left: 2px solid var(--gold-700); padding-left: var(--rhythm-4); margin: 0;
}
.pq-f { margin: var(--rhythm-5) 0; }
.pq-c {
  font-family: var(--f-ui); font-size: var(--fs-caption); letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--ink-300);
  margin-top: var(--rhythm-3); padding-left: calc(var(--rhythm-4) + 2px);
}

.seal-lockup { display: inline-flex; align-items: center; gap: var(--rhythm-3); }
.seal-w {
  font-family: var(--f-ui); font-size: var(--fs-wordmark); font-weight: var(--fw-semibold);
  letter-spacing: var(--tr-wordmark); text-transform: uppercase; color: var(--ink-050);
}

.pf { display: block; margin: 0; }
.pf-i { display: block; max-width: 100%; border-radius: var(--r-md); }
/* Duotone: the portrait is pushed to noir and champagne rather than being
   tinted, so it belongs to the palette instead of sitting on top of it. */
.pf-i--duotone { filter: grayscale(1) contrast(1.08) sepia(.42) saturate(1.5) hue-rotate(348deg); }
.pf-c {
  font-family: var(--f-ui); font-size: var(--fs-caption); color: var(--ink-300);
  margin-top: var(--rhythm-2);
}

/* ═══════════════ PRACTICE ═══════════════
   Inside the solicitation perimeter. See react/practice.tsx. */

.cred {
  display: flex; flex-direction: column; gap: var(--space-1);
  padding: var(--space-6); border-radius: var(--r-md);
}
/* --credential-figure, never --gold-500: brand gold is 6.69:1 on bedrock. */
.cred-f {
  font-family: var(--f-display); font-size: var(--fs-display-m); line-height: 1;
  font-weight: var(--fw-regular); color: var(--credential-figure);
}
.cred-l {
  font-family: var(--f-ui); font-size: var(--fs-eyebrow); font-weight: var(--fw-semibold);
  letter-spacing: var(--tr-eyebrow); text-transform: uppercase; color: var(--credential-label);
  margin-top: var(--space-2);
}
.cred-n {
  font-family: var(--f-text); font-size: var(--fs-body-s); line-height: var(--lh-body-s);
  color: var(--ink-200);
}

.bstand { padding: var(--space-6); }
.bstand-c {
  display: block; font-family: var(--f-display); font-size: var(--fs-title-l);
  color: var(--ink-050); margin-bottom: var(--space-4);
}
.bstand-d {
  display: grid; grid-template-columns: auto 1fr; gap: var(--space-2) var(--space-5);
  margin: 0; font-size: var(--fs-body-s); line-height: var(--lh-body-s);
}
.bstand-d dt {
  font-family: var(--f-ui); font-size: var(--fs-caption); font-weight: var(--fw-semibold);
  letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--ink-300);
}
.bstand-d dd { margin: 0; font-family: var(--f-text); color: var(--ink-050); }

.pc { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-6); }
.pc-a {
  font-family: var(--f-display); font-size: var(--fs-title-l); line-height: var(--lh-title-l);
  font-weight: var(--fw-regular); letter-spacing: var(--tr-title); color: var(--ink-050); margin: 0;
}
.pc-d {
  font-family: var(--f-text); font-size: var(--fs-body-m); line-height: var(--lh-body-m);
  font-weight: var(--fw-medium); color: var(--ink-100); margin: 0;
}
.pc-i { display: flex; flex-wrap: wrap; gap: var(--space-2); list-style: none; margin: 0; padding: 0; }
.pc-i li {
  font-family: var(--f-ui); font-size: var(--fs-caption); letter-spacing: .06em;
  text-transform: uppercase; color: var(--gold-500);
  border: 1px solid var(--gold-800); border-radius: var(--r-pill); padding: 4px 10px;
}

.tm { margin: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.tm-q {
  font-family: var(--f-text); font-style: italic; font-size: var(--fs-body-l);
  line-height: var(--lh-body-l); color: var(--ink-050);
  max-width: var(--measure-prose); margin: 0;
}
.tm-a {
  font-family: var(--f-ui); font-size: var(--fs-caption); letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--ink-300);
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4);
}
.tm-o { color: var(--gold-500); }

/* ═══════════════ COVER ═══════════════
   The masthead. Everything here is mobile-first: the monument size is a
   clamp, so the only breakpoint needed is the one where the lockup stops
   being the whole screen. */

.cv {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: var(--rhythm-4); padding: var(--rhythm-6) 0;
}
.cv-e { margin-bottom: 0; }
.cv-p { max-width: min(100%, 420px); }
.cv-lk { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); }
/* The person before the brand. "Madam Legal" is what clients call her; the
   name accountable to the Bar is the one above it. */
.cv-n {
  font-family: var(--f-ui); font-size: var(--fs-label); font-weight: var(--fw-semibold);
  letter-spacing: var(--tr-wordmark); text-transform: uppercase;
  color: var(--ink-300); margin: 0;
}
.cv-b {
  font-family: var(--f-display); font-size: var(--fs-monument);
  line-height: var(--lh-monument); letter-spacing: var(--tr-monument);
  font-weight: var(--fw-light); color: var(--ink-050); margin: 0;
}
.cv-s {
  font-family: var(--f-text); font-size: var(--fs-lede); line-height: var(--lh-lede);
  color: var(--ink-100); max-width: var(--measure-lede); margin: 0;
}
.cv-sl { display: block; }
/* --ink-300, not --ink-400: ink-400 is a declared non-text token in Noir. */
.cv-h {
  font-family: var(--f-ui); font-size: var(--fs-caption); letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--ink-300); margin: 0;
}

/* ═══════════════ THREAD NAV ═══════════════
   Anchors, not buttons: the primary navigation has to survive with no
   JavaScript. 44px minimum in both layouts — the touch target rule does not
   relax because a row happens to sit in a nav bar. */

.tn { display: block; width: 100%; }
.tn--fan { max-width: var(--measure-page); margin-inline: auto; }
.tn-l {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-3);
}
.tn-x { white-space: nowrap; }
.tn-i {
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-height: 44px; padding: 9px 16px;
  font-family: var(--f-ui); font-size: var(--fs-label); font-weight: var(--fw-semibold);
  letter-spacing: var(--tr-label); text-transform: uppercase;
  color: var(--ink-200); text-decoration: none;
  border: 1px solid var(--gold-800); border-radius: var(--r-pill);
  transition: border-color var(--quick) var(--liquid), color var(--quick) var(--liquid),
              transform var(--quick) var(--liquid);
}
.tn-i:hover { border-color: var(--gold-600); color: var(--ink-050); transform: translateY(-1px); }
.tn-i:focus-visible { outline: 2px solid var(--gold-400); outline-offset: 2px; }
.tn-i[aria-current] { border-color: var(--gold-500); color: var(--gold-500); }
/* --gold-600, not --gold-700: 700 is non-text in Noir. */
.tn-n { font-size: var(--fs-caption); color: var(--gold-600); }

.tn--docked .tn-l { justify-content: flex-start; gap: var(--space-2); }
.tn--docked .tn-i { padding: 9px 13px; font-size: var(--fs-caption); }
.tn--docked .tn-n { display: none; }

/* ═══════════════ TIMELINE ═══════════════
   One column on a phone, two from tablet up. The rail is drawn on the entry
   rather than the list, so the last one can drop it without a wrapper. */

.tl { list-style: none; margin: 0; padding: 0; }
.tl-e { position: relative; padding-left: var(--rhythm-4); padding-bottom: var(--rhythm-5); }
.tl-e::before {
  content: ""; position: absolute; left: 4px; top: 22px; bottom: 0; width: 1px;
  background: var(--gold-800);
}
.tl-e:last-child { padding-bottom: 0; }
.tl-e:last-child::before { display: none; }
.tl-d {
  position: absolute; left: 0; top: 9px; width: 9px; height: 9px; border-radius: 50%;
  border: 1px solid var(--gold-600); background: var(--ink-950);
}
.tl-e--now .tl-d {
  background: var(--gold-500); border-color: var(--gold-500);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--gold-500) 18%, transparent);
}
.tl-p { display: block; }
.tl-y {
  font-family: var(--f-ui); font-size: var(--fs-caption); font-weight: var(--fw-semibold);
  letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--gold-500);
}
.tl-c { margin-top: var(--space-2); }
.tl-t {
  font-family: var(--f-display); font-size: var(--fs-title-m); line-height: var(--lh-title-m);
  font-weight: var(--fw-regular); color: var(--ink-050); margin: 0;
}
.tl-in {
  font-family: var(--f-text); font-size: var(--fs-body-s); line-height: var(--lh-body-s);
  color: var(--ink-200); margin: var(--space-1) 0 0;
}
.tl-x {
  font-family: var(--f-text); font-size: var(--fs-body-m); line-height: var(--lh-body-m);
  color: var(--ink-100); max-width: var(--measure-prose); margin: var(--space-3) 0 0;
}

@media (min-width: 768px) {
  .tl-e { display: grid; grid-template-columns: 11rem minmax(0, 1fr); column-gap: var(--rhythm-4); }
  .tl-c { margin-top: 0; }
}

/* ═══════════════ INSIGHT CARD ═══════════════ */

.ic {
  position: relative; display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-6);
}
.ic-k {
  font-family: var(--f-ui); font-size: var(--fs-eyebrow); font-weight: var(--fw-semibold);
  letter-spacing: var(--tr-eyebrow); text-transform: uppercase;
  color: var(--gold-500); margin: 0;
}
.ic-t {
  font-family: var(--f-display); font-size: var(--fs-title-l); line-height: var(--lh-title-l);
  font-weight: var(--fw-regular); letter-spacing: var(--tr-title); margin: 0;
}
.ic-t a { color: var(--ink-050); text-decoration: none; }
/* The whole card is the hit area. z-index 3 clears the material's rim and
   aberration layers, which sit at 1, and the content, which sits at 2. */
.ic-t a::after { content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: 3; }
.ic-t a:focus-visible { outline: none; }
.ic:has(a:focus-visible) { outline: 2px solid var(--gold-400); outline-offset: 3px; }
.ic-x {
  font-family: var(--f-text); font-size: var(--fs-body-m); line-height: var(--lh-body-m);
  color: var(--ink-100); margin: 0;
}
.ic-m {
  font-family: var(--f-ui); font-size: var(--fs-caption); letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--ink-300); margin: 0;
  display: flex; align-items: center; gap: var(--space-2);
}
.ic-sep { color: var(--gold-700); }

/* ═══════════════ INQUIRY FORM ═══════════════
   Bedrock. Submitting an enquiry is consequential, so the control takes the
   48px target rather than the 44px default. */

.iq { padding: var(--space-8); }
.iq-f { display: flex; flex-direction: column; gap: var(--space-5); }
.iq-n {
  font-family: var(--f-text); font-size: var(--fs-body-m); line-height: var(--lh-body-m);
  color: var(--ink-100); margin: 0;
}
/* The Rule 36 notice. Set as quiet prose, not as an alert: it is a standing
   condition of the page, not something that has just gone wrong. */
.iq-d {
  font-family: var(--f-ui); font-size: var(--fs-caption); line-height: var(--lh-caption);
  color: var(--ink-200); margin: 0; padding: var(--space-4);
  border-left: 2px solid var(--gold-700); border-radius: 0 var(--r-sm) var(--r-sm) 0;
  background: color-mix(in srgb, var(--ink-200) 6%, transparent);
}
.iq .btn { min-height: 48px; align-self: flex-start; }

/* ═══════════════ MARQUEE ═══════════════
   The mask stops are alpha, not colour: #000 here means "fully opaque", so
   tokenising it would break the fade rather than theme it. */

.mq {
  position: relative; overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.mq-t {
  display: flex; width: max-content;
  animation: mq-slide var(--mq-dur, 40s) linear infinite;
}
.mq-s { display: flex; gap: var(--space-6); padding-right: var(--space-6); }
/* Each half is padded by exactly one gap, so half the track is one seamless
   repeat. Without that padding the loop jumps by a gap on every pass. */
@keyframes mq-slide { to { transform: translateX(-50%); } }
.mq--rev .mq-t { animation-direction: reverse; }
/* Focus as well as hover: pausing on hover alone strands a keyboard user,
   whose focus ring slides away from under them. */
.mq:hover .mq-t,
.mq:focus-within .mq-t { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  /* animation-name, not the shorthand: the global reduced-motion rule sets
     animation-duration with !important, which a shorthand cannot outrank. */
  .mq-t { animation-name: none; }
  .mq { overflow-x: auto; }
  .mq-s[aria-hidden] { display: none; }
}
