/*
 * ============================================================================
 * Vidhipandit — visual system
 * ============================================================================
 *
 * The register is the LAW REPORT, not the SaaS landing page: bound volumes,
 * tabular figures, quiet authority. Everything below is CSS only. There is no
 * JavaScript on this site and none of these rules assume any; every page must
 * work fully with scripting disabled, and does.
 *
 * External and cacheable on purpose -- see tests/test_web_pages.py's
 * test_css_is_external_not_inlined. Live Law inlines ~548 KB of CSS into every
 * article; this file sits behind a long max-age instead, so a repeat visitor
 * pays for it once, not on every page.
 *
 * The long max-age is only safe because the URL is content-versioned (a
 * `?v=<hash>` query string, computed in web/__init__.py's _asset_version and
 * emitted by base.html) -- an un-versioned URL with a one-year max-age would
 * mean a browser that already cached the old bytes never revalidates, so an
 * edit here would be invisible to returning visitors for up to a year. Edit
 * this file freely; the URL changes with it.
 *
 * SELF-HOSTED FONTS ONLY (brand spec 2026-09-11 §1, §2.2). Every face below
 * is a WOFF2 file in static/fonts/, served from this origin with its OFL
 * licence beside it. No Google Fonts request, no CDN, no remote host of any
 * kind. The Latin faces carry a Latin unicode-range; Noto Serif Devanagari
 * carries ONLY the Devanagari ranges, so a browser downloads it on a page that
 * actually contains Devanagari text and on no other. The masthead's वि and
 * विधिपंडित are inline SVG outlines, not text, precisely so the mark never
 * triggers that download. Only Literata (the body face) is preloaded.
 *
 * COLOUR CONTRACT (brand spec 2026-09-11 §2.1, values verbatim). One chromatic
 * value on the whole site -- the highlighter. Everything else is ink on paper.
 *     --paper #FBFBF8   --ink #16181D 17.13:1   --ink-2 #3B3F47 10.19:1
 *     --graphite #5E636B 5.83:1   --rule #DADCE0 1.32:1 (decorative)
 *     --control-border #767676 4.38:1   --highlighter #FFE872 (ink on it 14.41:1)
 * Dark values and their ratios are in section 14. Three rules follow and must
 * not be broken:
 *   1. --control-border is the ONLY border permitted on a form control. WCAG
 *      1.4.11 requires 3:1 for a UI-component boundary; --rule is 1.32:1.
 *   2. --rule is DECORATIVE. It may divide content. It may never be the
 *      visible edge of an input, a select, a textarea or a button, and it may
 *      never carry meaning that is not also carried by text.
 *   3. The highlighter is never text, never a border, never a button, never a
 *      large fill. It is painted in exactly four places: <mark> (search hits,
 *      marked holdings), a pinpointed paragraph (:target), the monogram (an
 *      SVG in _lockup.html), and the link band -- the stroke a link gets on
 *      hover, which the current nav item keeps. No other rule in this file
 *      may reference --highlighter or --hl-ground. tests/test_brand_tokens.py
 *      fails if one does.
 *
 * NO SHADOWS, radius <= 2px, one 8px spacing ramp (spec §1). Separation comes
 * from a 1px rule or an ink keyline, never from a tinted panel.
 *
 * LAYOUT. `.site-main` is a five-band named grid, not a centred column. Prose
 * is capped at a reading measure; listings, figures and the search field are
 * given a wider band so a 1440px viewport carries data instead of emptiness.
 * See the grid block for the band names (text / doc / wide / full).
 *
 * MARGINS DO NOT COLLAPSE between grid items. Every vertical margin below is
 * therefore tuned for ADDITION: a paragraph's 1.1rem bottom plus a heading's
 * 1.7rem top is the 2.8rem gap you see. Changing one without the other will
 * move the rhythm.
 * ============================================================================
 */

/* ---------------------------------------------------------------------------
 * 0 · FACES
 * ---------------------------------------------------------------------------
 * Files are exactly as Google Fonts serves them (Latin / Devanagari subsets),
 * unmodified -- IBM Plex's OFL reserves the name "Plex" for unmodified copies.
 * Eczar, Literata, Plex Sans and Noto Serif Devanagari are variable fonts, so
 * each file's declared weight range is the range the file really carries; the
 * type roles below use only the spec's weights (Eczar 600/700, Literata
 * 400/600 + 400 italic, Plex Sans 400/600, Plex Mono 400).
 * ------------------------------------------------------------------------ */

@font-face {
  font-family: "Eczar";
  src: url("fonts/eczar-latin.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Literata";
  src: url("fonts/literata-latin.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Literata";
  src: url("fonts/literata-italic-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Sans";
  src: url("fonts/ibm-plex-sans-latin.woff2") format("woff2");
  font-weight: 100 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/ibm-plex-mono-400-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Noto Serif Devanagari";
  src: url("fonts/noto-serif-devanagari.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0900-097F, U+1CD0-1CFF, U+A8E0-A8FF;
}

/* ---------------------------------------------------------------------------
 * 1 · TOKENS
 * ------------------------------------------------------------------------ */

:root {
  color-scheme: light;

  /* -- Palette: brand spec §2.1, verbatim. Ratios measured on --paper. ---- */
  --paper: #fbfbf8;
  --ink: #16181d;              /* 17.13:1 — text, masthead, primary fill    */
  --ink-2: #3b3f47;            /* 10.19:1 — secondary prose, snippets       */
  --graphite: #5e636b;         /*  5.83:1 — metadata, labels, notes         */
  --rule: #dadce0;             /*  1.32:1 — DECORATIVE dividers only        */
  --control-border: #767676;   /*  4.38:1 — UI-component boundary ONLY      */
  --highlighter: #ffe872;      /*  ink on it 14.41:1 — mark ground ONLY     */
  --on-ink: var(--paper);      /* text on an --ink fill: 17.13:1            */

  /* How the highlighter is painted. Light: the yellow itself, under ink.
     Dark (section 14): a deep amber ground under pale text, with a 2px yellow
     underline -- pale text on #FFE872 itself would be unreadable. */
  --hl-ground: var(--highlighter);
  --hl-text: var(--ink);

  /* -- Type roles: brand spec §2.2 ---------------------------------------- */
  /* Display: Eczar. Headings, case names. Its figures are proportional and it
     has no tnum, so it never sets a figure that must line up. */
  --font-display: "Eczar", "Noto Serif Devanagari", "Iowan Old Style", Charter,
    Cambria, Georgia, serif;
  /* Reading: Literata, with Noto Serif Devanagari for any Hindi run. */
  --font-serif: "Literata", "Noto Serif Devanagari", "Iowan Old Style", Charter,
    Cambria, Georgia, serif;
  /* Utility: nav, labels, chips, buttons, metadata. Tabular by default. */
  --font-sans: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Helvetica, Arial, sans-serif;
  /* Identifier: citations, case numbers, pinpoints, page counters. */
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas,
    monospace;

  /* -- Type scale (px at a 16px root) ------------------------------------ */
  --fs-2xs: 0.8125rem;   /* 13 — labels: Plex Sans 600, uppercase, +0.06em  */
  --fs-xs: 0.875rem;     /* 14 — identifiers, Plex Mono                     */
  --fs-sm: 0.9375rem;    /* 15 — metadata                                   */
  --fs-base: 1.0625rem;  /* 17 reading, mobile -- 18 from 48rem             */
  --fs-md: 1.1875rem;    /* 19 — the search field (spec §2.4)               */
  --fs-lg: 1.375rem;     /* 22 — H3                                         */
  --fs-xl: 1.625rem;     /* 26 — H2, mobile -- 30 from 48rem                */
  --fs-2xl: 2rem;        /* 32 — H1, mobile -- 44 from 48rem                */
  --label-track: 0.06em;

  /* -- Space: brand spec §1, one 8px ramp, no off-ramp values ------------ */
  --sp-1: 0.25rem;       /*   4 */
  --sp-2: 0.5rem;        /*   8 */
  --sp-3: 1rem;          /*  16 */
  --sp-4: 1.5rem;        /*  24 */
  --sp-5: 2.5rem;        /*  40 */
  --sp-6: 4rem;          /*  64 */
  --sp-7: 6rem;          /*  96 */
  --sp-8: 8rem;          /* 128 */
  --section: var(--sp-6);  /* section rhythm: 64 mobile, 96 desktop (§1)   */

  /* -- Layout bands ------------------------------------------------------ */
  /* --measure is the prose cap: about 68 CHARACTERS per rendered line of
     Literata at 18px (spec §2.2), and the judgment band (`doc`) is about
     72. Both are precomputed in rem, not written as `ch`, because (a) `ch`
     resolves against the font of the element that USES it -- the masthead
     and footer, which share this band's left edge, are set in other faces
     -- and (b) `ch` is the width of the "0" glyph, which is WIDER than an
     average character. The first version of this file used exactly that:
     68ch x Literata's "0" advance (0.579em) x 18px = 709px = 44.25rem --
     and measuring the rendered page (chunk B1) showed that comes out to
     about 78-80 *characters* per line, not 68. These values are instead
     chosen from real average-character-width measurement (Literata prose
     at 18px averages about 0.484em/character) and confirmed against
     screenshots of `/case/sc-2024-12-2113-2122` at 1440px: about 68-69
     characters/line in prose, about 71-73 in the judgment body -- see
     vidhipandit-B1-report.md for the exact counts.
     --side is the extra width listings and figures may claim; zero on
     phones. */
  --measure: 37rem;
  --doc-pad: 0rem;
  --side: 0rem;
  --pad: 1.5rem;         /* 24px content padding on mobile -- never 0 (§1) */
  --band: calc(var(--measure) + 2 * var(--doc-pad) + 2 * var(--side));
}

@media (min-width: 48rem) {
  :root {
    --doc-pad: 1rem;  /* (~72 - ~68 characters) / 2, in rem, not ch -- see above */
    --pad: 2.5rem;
    --fs-base: 1.125rem;
    --fs-xl: 1.875rem;
    --fs-2xl: 2.75rem;
    --section: var(--sp-7);
  }
}
@media (min-width: 64rem) {
  :root { --side: 6rem; }
}
@media (min-width: 80rem) {
  :root { --side: 13rem; }
}
@media (min-width: 100rem) {
  :root { --side: 18rem; }
}

/* ---------------------------------------------------------------------------
 * 2 · RESET & BASE
 * ------------------------------------------------------------------------ */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-serif);
  font-size: var(--fs-base);
  line-height: 1.65;
  font-synthesis-weight: none;
  font-optical-sizing: auto;
  /* A judgment is read for an hour at a time. Turn on whatever the resolved
     face happens to offer for that. */
  font-kerning: normal;
  text-rendering: optimizeLegibility;
}

img, svg { max-width: 100%; height: auto; }

/* Links are ink, underlined 1px (spec §2.1). Colour cannot mark a link on a
   site whose only colour is the highlighter, so the underline is the cue.
   On hover the underline becomes the highlighter band -- see section 19,
   which sits last so it wins over every component's own link rule. */
a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

/* ---------------------------------------------------------------------------
 * 3 · FOCUS
 * ---------------------------------------------------------------------------
 * Keyboard users are a first-class constituency here: an advocate tabbing
 * through 25 search results must never lose the caret. One ring everywhere
 * (spec §1): 2px, offset 2px, in --ink -- near-black on light paper and
 * near-white on dark paper, so the ring always sits against the page ground
 * at 17.13:1 / 15.87:1, outside its element, over fills and rules alike.
 * ------------------------------------------------------------------------ */

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  border-radius: 1px;
}

/* Belt and braces for engines without :focus-visible. */
:focus:not(:focus-visible) { outline: none; }

/* ---------------------------------------------------------------------------
 * 4 · LAYOUT GRID
 * ---------------------------------------------------------------------------
 * Four nested bands, named. Every direct child of .site-main lands in `text`
 * unless it asks for more:
 *
 *   text  |──────────|                prose: ~70 characters, the reading cap
 *   doc   |───────────────|           the judgment band, ~78 characters
 *   wide  |──────────────────────|    listings, figures, the search field
 *   full  |─────────────────────────| edge to edge
 *
 * They share a LEFT EDGE and grow rightwards; they are not concentric. That
 * is the whole point. Concentric bands put a listing's left edge outside the
 * left edge of the paragraph above it, which reads as a misalignment rather
 * than as a wider band — the first draft of this grid did exactly that and it
 * looked broken. One left margin, aligned with the masthead, and data extends
 * into the room a 1440px viewport actually has.
 * ------------------------------------------------------------------------ */

.site-main {
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--pad), 1fr)
    [wide-start doc-start text-start] minmax(0, var(--measure))
    [text-end] minmax(0, calc(var(--doc-pad) * 2))
    [doc-end] minmax(0, calc(var(--side) * 2))
    [wide-end] minmax(var(--pad), 1fr)
    [full-end];
  row-gap: 0;
  padding-block: var(--sp-5) var(--sp-6);
}

.site-main > * { grid-column: text; min-width: 0; }

/* ---------------------------------------------------------------------------
 * 5 · TYPOGRAPHY
 * ------------------------------------------------------------------------ */

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--ink);
  font-weight: 600;
  letter-spacing: 0;
  text-wrap: balance;
}

.site-main h1 {
  font-size: var(--fs-2xl);
  font-weight: 700;
  line-height: 1.1;
  margin: 0 0 var(--sp-3);
}

/* The homepage is the one surface allowed to breathe. It is identified by the
   figures band it alone carries, so no template edit is needed to mark it. */
.site-main:has(.stat-list) > h1 { margin-bottom: var(--sp-3); }

.site-main h2 {
  font-size: var(--fs-xl);
  line-height: 1.15;
  margin: var(--sp-4) 0 var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--rule);
}

.site-main h2:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* A section rule that stops short of the listing beneath it reads as an
   unfinished edge. Where a section heads data, its rule runs the data's
   width; where it heads prose, it runs the prose's. */
.site-main:has(.doc-list) > h2,
.site-main:has(.count-list) > h2 { grid-column: wide; }

.site-main h3 {
  font-size: var(--fs-lg);
  line-height: 1.25;
  margin: var(--sp-3) 0 var(--sp-1);
}

/* The paragraph colour rule that used to live here made EVERY paragraph on
   the site grey, which is what flattened the hierarchy. Body prose is now
   primary ink; hierarchy comes from scale, weight and family, and grey is
   reserved for genuinely tertiary text (meta, labels, notes, footer). */
.site-main p {
  margin: 0 0 var(--sp-3);
  color: var(--ink);
  text-wrap: pretty;
}

/* A standfirst without a class: the paragraph immediately under the page
   title on prose surfaces. `.lede` is the explicit version, used by the
   withheld and not-indexed pages. */
.site-main > h1 + p:not([class]),
.lede {
  font-size: var(--fs-md);
  line-height: 1.5;
  color: var(--ink-2);
  margin-bottom: var(--sp-3);
}

.site-main ul:not([class]),
.site-main ol:not([class]) {
  margin: 0 0 var(--sp-3);
  padding-left: 1.35rem;
}

.site-main ul:not([class]) > li,
.site-main ol:not([class]) > li { margin-bottom: var(--sp-2); }

.site-main ul:not([class]) > li::marker { color: var(--graphite); }
.site-main ol:not([class]) > li::marker {
  color: var(--graphite);
  font-variant-numeric: tabular-nums;
}

code, kbd, samp {
  font-family: var(--font-mono);
  font-size: 0.875em;
  border: 1px solid var(--rule);
  padding: 0 0.3em;
  border-radius: 2px;
}

/* Literata and Plex Sans are both specified at 600 for emphasis (spec §2.2). */
strong, b { font-weight: 600; }

/* THE HIGHLIGHTER (spec §2.3). Search hits and marked holdings. The uneven
   radius is the end of a real marker stroke; `clone` gives every wrapped line
   its own ends instead of one stroke broken across lines.
   ⚠ Defined ONCE, on purpose. The dark theme only adds its 2px underline in
   section 14; a second full `mark` rule anywhere would fight the tokens. */
mark {
  background: var(--hl-ground);
  color: var(--hl-text);
  padding: 0 0.12em;
  border-radius: 0.1em 0.3em 0.1em 0.25em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* Anything read as a figure, a date or an identifier is set in columns. */
time,
.count,
.case-slug,
.stat-list dd,
.case-pager,
.case-jump input,
.doc-list .case-meta,
p.case-meta,
.result-count,
.result-pager,
.pagination,
.doc-rank {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* ---------------------------------------------------------------------------
 * 6 · MASTHEAD & FOOTER
 * ---------------------------------------------------------------------------
 * The rule beneath the masthead is a double rule — a hairline plus an ink
 * keyline — because that is what the head of a bound law report looks like,
 * and because it separates chrome from record more firmly than one line does.
 * The banded padding trick keeps the content aligned with .site-main's `wide`
 * band while the rules still run the full width of the viewport.
 * ------------------------------------------------------------------------ */

.site-header {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2) var(--sp-5);
  padding: var(--sp-3) max(var(--pad), calc((100% - var(--band)) / 2));
  border-bottom: 1px solid var(--rule);
}

.site-header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -4px;
  height: 1px;
  background: var(--ink);
}

/* The lockup (spec §4): [वि] monogram · Vidhipandit · विधिपंडित, drawn as
   inline SVG outlines by scripts/build_brand_assets.py. The wordmark paths
   are `currentColor`, so they follow --ink into the dark theme; the monogram
   keeps its own yellow block and ink glyphs in both themes. */
.lockup {
  display: inline-flex;
  align-items: center;
  color: var(--ink);
  line-height: 0;
}

.lockup,
.lockup:hover { text-decoration: none; }

.lockup-svg {
  width: auto;
  height: 2.75rem;               /* 44px desktop */
}

@media (max-width: 30rem) {
  .lockup-svg { height: 2.25rem; }  /* 36px phone */
}

/* Skip link (WCAG 2.4.1): the first focusable element on every page, off
   screen until focused, then an ink plate over the masthead. */
.skip-link {
  position: absolute;
  top: var(--sp-2);
  left: var(--sp-2);
  z-index: 10;
  padding: var(--sp-2) var(--sp-3);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--on-ink);
  background: var(--ink);
  text-decoration: none;
  transform: translateY(-300%);
}

.skip-link:focus,
.skip-link:hover { transform: none; text-decoration: none; }

/* Browse entry points, on every page. Wraps under the wordmark on a narrow
   viewport rather than overflowing (no JS, so no hamburger). Micro-caps: the
   running-head convention, and it keeps four links to one quiet line. */
.site-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-3);
}

.site-nav a,
.footer-nav a {
  color: var(--ink-2);
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-track);
  text-decoration: none;
  padding-block: var(--sp-1);
}

/* The current section: ink, and it keeps the link band (section 19). */
.site-nav a[aria-current="page"] { color: var(--ink); }

.site-footer {
  margin-top: var(--section);
  padding: var(--sp-4) max(var(--pad), calc((100% - var(--band)) / 2))
    var(--sp-5);
  border-top: 1px solid var(--rule);
  color: var(--graphite);
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
}

.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-4);
  margin: 0 0 var(--sp-3);
}

.site-footer p { margin: 0; }

/* ---------------------------------------------------------------------------
 * 7 · THE SEARCH FIELD
 * ---------------------------------------------------------------------------
 * Search is the product, so on the two surfaces that carry it the field is
 * the largest, heaviest object on the page: a bordered plate with an ink
 * keyline on top, a 3.5rem input set in the reading serif at 20px, and a
 * solid ink button. The 2px border is --control-border (4.38:1), never the
 * decorative --rule that used to sit here at 1.32:1.
 * ------------------------------------------------------------------------ */

.search-form {
  grid-column: wide;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--sp-3);
  margin: var(--sp-2) 0 var(--sp-5);
  padding: var(--sp-3);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--ink);
}

.search-form label {
  grid-column: 1 / -1;
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-track);
  color: var(--graphite);
}

.search-form input[type="search"] {
  min-width: 0;
  min-height: 3.4rem;
  padding: 0 var(--sp-3);
  font-family: var(--font-serif);
  font-size: var(--fs-md);
  color: var(--ink);
  background: var(--paper);
  border: 2px solid var(--control-border);
  border-radius: 2px;
  -webkit-appearance: none;
  appearance: none;
}

.search-form input[type="search"]::placeholder {
  color: var(--graphite);
  opacity: 1;
}

/* One ring, not two: the outline is the indicator; the control keeps its
   resting border. A recoloured border inside an outline reads as a
   validation error on an autofocused field, not as focus. */

.search-form button {
  min-height: 3.4rem;
  padding: 0 var(--sp-4);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--on-ink);
  background: var(--ink);
  border: 2px solid var(--ink);
  border-radius: 2px;
  cursor: pointer;
}

.search-form button:hover { background: var(--ink-2); border-color: var(--ink-2); }

@media (max-width: 30rem) {
  .search-form { grid-template-columns: minmax(0, 1fr); }
}

/* ---------------------------------------------------------------------------
 * 8 · RESULT & LISTING ROWS
 * ---------------------------------------------------------------------------
 * One row shape for /search, /recent/, /courts/<code>/ and /years/<year>/ —
 * they share _macros.html's doc_row, so they share this. On a wide viewport
 * the row becomes two columns: the case name and its snippet on the left, the
 * court and date right-aligned in a tabular rail on the right. That rail is
 * the point: it turns a listing into a column of figures an advocate can scan
 * down, which is what a law report's table of cases does.
 *
 * The row works with or without a party name. When doc_row has a title it
 * renders the title as .doc-title and the citation moves into .case-meta;
 * when it has only a citation, the citation IS the title. Both land in the
 * same slots, so nothing here needs to know which happened.
 * ------------------------------------------------------------------------ */

.doc-list {
  grid-column: wide;
  list-style: none;
  margin: var(--sp-3) 0 0;
  padding: 0;
  border-top: 1px solid var(--ink);
}

.doc-list > li {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "title" "meta" "snip";
  gap: var(--sp-1) var(--sp-4);
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--rule);
}

.doc-title { grid-area: title; }
.doc-list .case-meta { grid-area: meta; }
.doc-list .snippet { grid-area: snip; }

a.doc-title,
.doc-list > li > a:first-child {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink);
  text-decoration: none;
  text-wrap: pretty;
}

/* A row whose document has no address is deliberately NOT a link — see
   display.py's document_href. It must not look like one either. */
span.doc-title {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink-2);
}

.doc-list .case-meta {
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--graphite);
}

.doc-list .snippet {
  margin: var(--sp-1) 0 0;
  max-width: var(--measure);
  font-family: var(--font-serif);
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--ink-2);
}

/* The extractor could not read a day out of the judgment, so only the year is
   shown. Quiet, but never invisible: the reason is in the abbr's title and
   the note above the list. */
.date-approx {
  margin-left: 0.3rem;
  font-size: var(--fs-2xs);
  color: var(--graphite);
  text-decoration: none;
  border-bottom: 1px dotted var(--control-border);
  cursor: help;
}

@media (min-width: 64rem) {
  .doc-list > li {
    grid-template-columns: minmax(0, 1fr) minmax(0, 19rem);
    grid-template-areas: "title meta" "snip meta";
  }
  .doc-list .case-meta {
    align-self: start;
    text-align: right;
    padding-top: 0.18rem;
  }
}

/* --- Why search results carry no visible rank number ----------------------
 * Search results are an <ol> and rank IS real information, so a first pass
 * numbered them with a CSS counter. That shipped a lie: the server paginates
 * with `<ol start="26">` on page two, a CSS counter cannot read an attribute,
 * and every page therefore restarted at 1 — directly under a line reading
 * "showing 26–50". Caught on the live site.
 *
 * The native marker WOULD honour `start`, but `::marker` requires
 * `display: list-item`, and `.doc-list > li` is `display: grid` — which is
 * what makes the two-column row work. The two are mutually exclusive here.
 *
 * A wrong number is worse than no number, so there is none. `.doc-rank` below
 * is styled and ready: emit the true rank as text in the row and it appears,
 * correct, with no further CSS. See the handoff in the design-system spec.
 */
.doc-rank {
  grid-area: rank;
  align-self: start;
  padding-top: 0.3rem;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
  color: var(--graphite);
}

@media (min-width: 48rem) {
  .doc-list > li:has(> .doc-rank) {
    grid-template-columns: 2.6rem minmax(0, 1fr);
    grid-template-areas: "rank title" "rank meta" "rank snip";
  }
}

@media (min-width: 64rem) {
  .doc-list > li:has(> .doc-rank) {
    grid-template-columns: 2.6rem minmax(0, 1fr) minmax(0, 19rem);
    grid-template-areas: "rank title meta" "rank snip meta";
  }
}

/* The "N judgments matched" line above a result set. */
p.case-meta {
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  color: var(--graphite);
  font-variant-numeric: tabular-nums;
}

.date-precision-note {
  margin: var(--sp-2) 0 var(--sp-1);
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  line-height: 1.5;
  color: var(--graphite);
  max-width: 46rem;
}

/* An annotation belongs in the band of the thing it annotates: over a
   listing it sits with the listing, over a judgment it sits with the
   judgment. Neither needs a template edit to say so. */
.site-main:has(.doc-list) > p.case-meta,
.site-main:has(.doc-list) > .date-precision-note { grid-column: wide; }

.site-main:has(.case-body) > .date-precision-note { grid-column: doc; }

.pagination {
  grid-column: wide;
  margin: var(--sp-4) 0 0;
}

.pagination a {
  display: inline-block;
  padding: var(--sp-2) var(--sp-3);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  border: 1px solid var(--control-border);
  border-radius: 2px;
}

.pagination a:hover {
  color: var(--on-ink);
  background: var(--ink);
  border-color: var(--ink);
  text-decoration: none;
}

/* ---------------------------------------------------------------------------
 * 9 · BROWSE INDEXES — /courts/ and /years/
 * ---------------------------------------------------------------------------
 * 23,405 judgments across ~70 years is a void when it is a stack of one-line
 * rows. As a card grid it is an index: each card is a destination with its own
 * count set in tabular figures, and the whole thing fills the wide band.
 *
 * `auto-fill` (not `auto-fit`) is deliberate. /courts/ currently has exactly
 * one court; `auto-fit` would stretch that single card across 1200px, which
 * would read as a layout accident. `auto-fill` keeps the empty tracks, so one
 * court sits at its natural card width and seventy years tile.
 * ------------------------------------------------------------------------ */

.count-list {
  grid-column: wide;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: var(--sp-3);
  list-style: none;
  margin: var(--sp-3) 0 0;
  padding: 0;
}

.count-list > li {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  padding: var(--sp-3) var(--sp-3) var(--sp-4);
  background: var(--paper);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--ink);
}

.count-list a {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 600;
  line-height: 1.2;
  color: var(--ink);
  text-decoration: none;
  text-wrap: balance;
}

.count-list .count {
  margin-top: auto;
  padding-top: var(--sp-2);
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--graphite);
}

/* A long index — every year the corpus covers — wants a denser tile than a
   list of four courts does. Thirteen rows is the threshold at which the
   list stops being a menu and starts being an index. */
.count-list:has(> li:nth-child(13)) {
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: var(--sp-2);
}

.count-list:has(> li:nth-child(13)) > li { padding: var(--sp-3); }
.count-list:has(> li:nth-child(13)) a { font-size: var(--fs-md); }

/* ---------------------------------------------------------------------------
 * 10 · THE FIGURES BAND — homepage statistics
 * ---------------------------------------------------------------------------
 * A ledger, not a hero: hairline-divided cells over a rule-coloured ground,
 * uppercase micro-caps labels, and the numbers themselves large, serif and
 * tabular. This is the one place on the site where a figure is allowed to be
 * the biggest thing in view, because the figure IS the claim.
 * ------------------------------------------------------------------------ */

.stat-list {
  grid-column: wide;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 1px;
  margin: var(--sp-4) 0 var(--sp-5);
  padding: 0;
  background: var(--rule);
  border: 1px solid var(--rule);
}

.stat-list > div {
  background: var(--paper);
  padding: var(--sp-3) var(--sp-3) var(--sp-3);
}

.stat-list dt {
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-track);
  color: var(--graphite);
}

/* Figures in Plex Sans: tabular by default, so a column of counts aligns.
   (Eczar's figures are proportional and it has no tnum -- spec §2.4 asks for
   "tabular Plex Sans" here for exactly that reason.) */
.stat-list dd {
  margin: var(--sp-1) 0 0;
  font-family: var(--font-sans);
  font-size: var(--fs-xl);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* ---------------------------------------------------------------------------
 * 11 · THE CASE PAGE — the reading surface
 * ------------------------------------------------------------------------ */

.case-title {
  grid-column: doc;
  font-size: var(--fs-2xl);
  font-weight: 700;
  line-height: 1.1;
  margin: 0 0 var(--sp-3);
}

/* The document's own permanent address -- content, not chrome, so it is
   selectable and monospaced like any other identifier on the page. The
   citation itself lives only in the citation plate now (spec §2.3;
   chunk C addendum "show the citation once" removed the second,
   redundant `.case-cite` chip that used to sit beside this). */
.case-ids {
  grid-column: doc;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2) var(--sp-3);
  margin: 0 0 var(--sp-2) !important;
}

.case-slug {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--graphite);
  overflow-wrap: anywhere;
  -webkit-user-select: all;
  user-select: all;
}

/* Court · date · document type, under the title, closed by an ink keyline —
   the head of a report entry. */
.site-main:has(.case-body) > p.case-meta,
.site-main:has(.case-title) > p.case-meta {
  grid-column: doc;
  margin: 0 0 var(--sp-3);
  padding-bottom: var(--sp-3);
  border-bottom: 2px solid var(--ink);
  font-size: var(--fs-sm);
  color: var(--ink-2);
}

/* The judgment itself.
 *
 * Chunk B, brief step 1: `white-space: pre-wrap` is GONE. The server now
 * reflows the source PDF's hard-wrapped lines into real `<p>` elements
 * (`web/reflow.py`) before this element ever sees them, so this stylesheet
 * DOES control the measure here the way it controls every other block on
 * the site -- text wraps naturally at the `doc` band's width (~72
 * characters, spec §2.2; see --measure's comment above for how that
 * number was derived and verified). `overflow-wrap: break-word` stays as
 * a defence against a single unbroken token (a long citation string, a
 * URL) wider than the band, not as the thing deciding where ordinary
 * lines break.
 */
.case-body {
  grid-column: doc;
  overflow-wrap: break-word;
  hyphens: none;
  tab-size: 2;
  /* No rule of its own: p.case-meta above already closes the header block
     with an ink keyline, and a second hairline 40px below it read as an
     accident rather than as structure. */
  margin: var(--sp-4) 0 0;
  font-family: var(--font-serif);
  font-size: var(--fs-base);
  line-height: 1.65;
  color: var(--ink);
}

.case-body p {
  margin: 0 0 1.1rem;
  position: relative;
}

.case-body p:last-child {
  margin-bottom: 0;
}

/* A law-report running head (spec: "SCR running heads ... become a small
 * page marker `p. NNNN`"), pulled out of the body text by `web/reflow.py`
 * rather than left interrupting the sentence it fell inside. Deliberately
 * plain -- a small, muted, own-line note, not a full rail entry.
 */
.page-marker {
  margin: var(--sp-3) 0;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: 0.02em;
  color: var(--ink-2);
  text-align: right;
}

/* ---------------------------------------------------------------------------
 * 11a-1 · THE BINDING-MARGIN RAIL (spec §2.3, chunk B brief step 3)
 * ---------------------------------------------------------------------------
 * The Supreme Court Rules 2013 require a 4cm margin on filings; this rail
 * is that proportion (4.5rem) at desktop widths, holding the court's OWN
 * paragraph numbers (never an invented one -- `web/reflow.py` only emits
 * `id="para-N"` where the court's numbering was verified to continue) as
 * linkable pinpoints. Positioned absolutely into the flexible OUTER
 * gutter (`.site-main`'s `full-start` track, `minmax(var(--pad), 1fr)`),
 * never into `--doc-pad` -- that band is only ~1rem wide, nowhere near
 * enough room, and the outer gutter is always wider than 4.5rem at the
 * >=48rem breakpoint this rule is gated on (`--pad` is a MINIMUM, not a
 * fixed width, on every viewport this site is tested at).
 *
 * Mobile (brief step 3, "inline number on mobile"): `.para-rail` is a
 * normal inline-flex element ordered before the paragraph's own text,
 * not absolutely positioned -- there is no room for a real margin rail
 * below 48rem.
 *
 * The "Copy pinpoint" button stays visually quiet (opacity 0) until the
 * paragraph is hovered, focused-within, or the button itself receives
 * keyboard focus -- eleven-plus always-visible buttons down one judgment
 * page would be louder than the record itself. It is never `display:
 * none`: a screen reader and Tab both reach it regardless of hover state.
 * ------------------------------------------------------------------------ */

.para-rail {
  display: inline-flex;
  align-items: baseline;
  gap: var(--sp-2);
  margin-right: var(--sp-2);
}

.para-num {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--graphite);
  text-decoration: none;
}

.para-num:hover,
.para-num:focus-visible {
  text-decoration: underline;
}

.copy-pin {
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: 600;
  color: var(--graphite);
  background: none;
  border: 1px solid var(--control-border);
  border-radius: 2px;
  padding: 0 var(--sp-1);
  cursor: pointer;
  opacity: 0;
}

.case-body p:hover .copy-pin,
.case-body p:focus-within .copy-pin,
.copy-pin:focus-visible {
  opacity: 1;
}

@media (hover: none) {
  /* A touch device has no persistent hover state to reveal the button on
     -- show it plainly rather than have it be invisible until the very
     paragraph it belongs to is tapped into focus. */
  .copy-pin { opacity: 1; }
}

@media (min-width: 48rem) {
  .para-rail {
    position: absolute;
    top: 0.1em;
    left: -4.5rem;
    width: 4rem;
    margin-right: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--sp-1);
    text-align: right;
  }
}

/* The paragraph a visitor arrives at via a pinpoint link (spec §2.1, one
 * of the highlighter's four sanctioned places): the SAME ground `<mark>`
 * uses, so a reader who followed `#para-17` sees the same "someone has
 * marked this" cue as a search hit or a marked holding, not a different
 * one invented just for this. */
.case-body p:target {
  background: var(--hl-ground);
  color: var(--hl-text);
}

.case-body p:target .para-num,
.case-body p:target .copy-pin {
  color: inherit;
}

/* ---------------------------------------------------------------------------
 * 11a-2 · THE CITATION PLATE (spec §2.3)
 * ---------------------------------------------------------------------------
 * "Every citation is set the way the report sets it ... in Plex Mono
 * inside a 1px --rule box with a Copy citation control." `web/
 * citation_plate.py` supplies the citation text; this is purely its box.
 * ------------------------------------------------------------------------ */

.citation-plate {
  grid-column: doc;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin: var(--sp-3) 0 0;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--rule);
}

.citation-plate-text {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.01em;
  color: var(--ink);
  -webkit-user-select: all;
  user-select: all;
}

.copy-citation {
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-track);
  color: var(--ink);
  background: none;
  border: 1px solid var(--control-border);
  border-radius: 2px;
  padding: var(--sp-1) var(--sp-2);
  cursor: pointer;
  white-space: nowrap;
}

.copy-citation:hover {
  color: var(--on-ink);
  background: var(--ink);
  border-color: var(--ink);
}

/* ---------------------------------------------------------------------------
 * 11a-3 · THE `?hl=` LOZENGE (chunk B, brief step 4)
 * ---------------------------------------------------------------------------
 * "Highlighting "x" · Clear". Deliberately NOT painted with the
 * highlighter itself (--highlighter/--hl-ground/--hl-text) -- section 2's
 * own rule reserves those tokens for exactly four places (<mark>,
 * :target, the monogram, the link band; tests/test_brand_tokens.py's
 * check_highlighter_scope fails on a fifth), and this is a plain status
 * line ABOUT the highlighter, not a fifth place it is painted. Same
 * treatment as .date-precision-note just below it in the cascade.
 * ------------------------------------------------------------------------ */

.hl-lozenge {
  grid-column: doc;
  margin: var(--sp-3) 0 0;
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  color: var(--ink-2);
}

/* ---------------------------------------------------------------------------
 * 11a-4 · THE PRINT RUNNING HEADER (chunk B, brief step 5)
 * ---------------------------------------------------------------------------
 * Invisible on screen -- case.html emits it on every case page that has
 * a citation to show, but it carries nothing a screen reader should
 * announce (aria-hidden, see case.html) since the citation is already
 * on the page as the citation plate. Its ONLY job is to exist for
 * section 16's print rule to promote to `position: fixed`, which Chrome
 * repeats on every printed page -- see that section's own comment.
 * ------------------------------------------------------------------------ */

.print-running-header { display: none; }

/* ---------------------------------------------------------------------------
 * 11a · THE HEADNOTE
 * ---------------------------------------------------------------------------
 * Spec §2.5: Literata on --paper under a 2px ink rule.
 *
 * The official SCR headnote is this corpus's single biggest advantage over a
 * news write-up. Chunk B2 (`web/headnote.py`) now emits it as its own
 * element, pulled out of page 1's already-reflowed `<p>` blocks (see
 * `web/reflow.py`) rather than left as anonymous prose indistinguishable
 * from the rest of the judgment. Contract, current as of chunk B2:
 *
 *     <section class="case-headnote">
 *       <h2>Issue for consideration</h2><p>…</p>
 *       <h2>Held</h2><p>…</p>[<p>…</p> for a second Held passage]
 *     </section>
 *
 * Real `<p>` elements, never `white-space: pre-wrap` -- that rule described
 * a contract for the OLD single pre-wrapped record this section no longer
 * belongs to; keeping it here would reintroduce the source PDF's raw line
 * breaks into text this module has already reflowed into paragraphs.
 * ------------------------------------------------------------------------ */

.case-headnote {
  grid-column: doc;
  margin: var(--sp-4) 0 0;
  padding: var(--sp-3) 0 0;
  border-top: 2px solid var(--ink);
  font-family: var(--font-serif);
  font-size: var(--fs-base);
  line-height: 1.65;
  color: var(--ink);
}

.case-headnote > h2,
.case-headnote > h3,
.case-headnote .case-headnote-label {
  margin: 0 0 var(--sp-3);
  padding: 0;
  border: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-track);
  color: var(--graphite);
  white-space: normal;
}

.case-headnote p { margin: 0 0 var(--sp-3); color: var(--ink); }
.case-headnote p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------------------
 * 11a-5 · HOMEPAGE: ONE MARKED JUDGMENT, LAYERED RECENT CARDS, WHERE TO START
 * ---------------------------------------------------------------------------
 * Chunk C, brief step 2/3 (spec §2.4 points 3-4, the "Where to start"
 * shelf). No new colour and no shadow -- separation is the same 1px
 * --rule / 2px --ink keyline vocabulary already used everywhere else on
 * the site; `.case-headnote` itself is reused as-is inside both the
 * marked judgment and a recent card's expansion, so a Held: passage
 * reads identically wherever it appears.
 * ------------------------------------------------------------------------ */

.marked-judgment {
  grid-column: wide;
  margin: var(--sp-5) 0;
  padding: var(--sp-4);
  border: 1px solid var(--rule);
}

.marked-judgment-label {
  margin: 0 0 var(--sp-2);
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-track);
  color: var(--graphite);
}

.marked-judgment h2.marked-judgment-title {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: var(--fs-lg);
}

.marked-judgment-title a {
  color: var(--ink);
  text-decoration: none;
}

.marked-judgment-title a:hover {
  text-decoration: underline;
  text-underline-offset: .2em;
}

.marked-judgment .case-meta { margin: var(--sp-2) 0 0; }
.marked-judgment .case-headnote { grid-column: auto; }
.marked-judgment .citation-plate { grid-column: auto; }

.marked-judgment-open {
  margin: var(--sp-3) 0 0;
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
}

/* Layered recent cards -- native <details>, no JavaScript at all. A
   custom marker replaces the browser default (a plain triangle rather
   than each browser's own glyph) and rotates on [open] via `transform`,
   never an icon font or an image. */
.recent-cards { grid-column: wide; }

/* `.doc-list > li` is a 3-row named grid (title/meta/snip) built for a
   flat <li> whose title/meta/snippet are its own direct children -- a
   recent card's single child is one <details> element instead, so the
   named areas would go unused; reset to plain block flow. */
.recent-cards > li {
  display: block;
  padding: 0;
  border-bottom: 0;
  margin-bottom: var(--sp-3);
}

.recent-card {
  border: 1px solid var(--rule);
  padding: var(--sp-3);
}

.recent-card summary {
  cursor: pointer;
  list-style: none;
}

.recent-card summary::-webkit-details-marker { display: none; }

/* The collapsed summary's title is a live document address (see
   `document_href` in home_views' `_homepage_recent`), just not rendered
   as an <a> itself -- the whole <summary> is the click target for
   expand/collapse, and the actual link lives in `.recent-card-expand`.
   `span.doc-title`'s own rule (below, in section 9) is muted ink-2
   specifically for a document that has NO address; override back to
   full ink here so a card with a real address does not read as one
   without one. */
.recent-card summary .doc-title { color: var(--ink); }

.recent-card .case-meta { display: block; margin-top: var(--sp-1); }

.recent-card-cite {
  display: inline-block;
  margin-top: var(--sp-2);
}

.recent-card-toggle {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  margin-top: var(--sp-2);
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-track);
  color: var(--ink);
}

.recent-card-toggle::before {
  content: "\25B8"; /* ▸ */
  display: inline-block;
  transition: transform .15s ease;
}

.recent-card[open] .recent-card-toggle::before { transform: rotate(90deg); }

.recent-card-expand {
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--rule);
}

.recent-card-expand .case-headnote {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* "Where to start" shelf (chunk C, brief step 3). */
.where-to-start {
  grid-column: wide;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: var(--sp-4);
  margin: 0 0 var(--sp-3);
  padding: 0;
  list-style: none;
}

.where-to-start > li {
  padding: var(--sp-3);
  border: 1px solid var(--rule);
}

.where-to-start .case-meta { display: block; margin-top: var(--sp-1); }

.editors-note {
  margin: var(--sp-2) 0 0 !important;
  font-family: var(--font-serif);
  font-size: var(--fs-sm);
  color: var(--ink-2);
}

.editors-note-label {
  display: block;
  margin-bottom: var(--sp-1);
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-track);
  color: var(--graphite);
}

/* ---------------------------------------------------------------------------
 * 11b · LONG-DOCUMENT NAVIGATION
 * ---------------------------------------------------------------------------
 * A 900,000-character judgment runs to ~101 pages. Previous/Next are real
 * controls, so they look like controls; the page counter between them is set
 * in tabular mono so "Page 9 of 101" and "Page 78 of 101" occupy the same
 * width and the buttons do not shift as you page through.
 * ------------------------------------------------------------------------ */

.case-pager {
  grid-column: doc;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--sp-3);
  margin: var(--sp-5) 0 0;
  padding-top: var(--sp-3);
  border-top: 2px solid var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
}

.case-pager > span:first-child { justify-self: start; }
.case-pager > span:nth-child(2) {
  justify-self: center;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--graphite);
  white-space: nowrap;
}
.case-pager > span:last-child { justify-self: end; }

.case-pager a {
  display: inline-block;
  padding: var(--sp-2) var(--sp-3);
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  border: 1px solid var(--control-border);
  border-radius: 2px;
  white-space: nowrap;
}

.case-pager a:hover {
  color: var(--on-ink);
  background: var(--ink);
  border-color: var(--ink);
  text-decoration: none;
}

/* Measured at 320px: "← Previous", "Page 9 of 101" and "Next →" on one row
   pushed the document to 350px and gave the page a horizontal scrollbar.
   Below 30rem the counter takes its own row and the two controls split the
   width beneath it. */
@media (max-width: 30rem) {
  .case-pager {
    grid-template-columns: 1fr 1fr;
    row-gap: var(--sp-3);
  }
  .case-pager > span:nth-child(2) {
    grid-row: 1;
    grid-column: 1 / -1;
    justify-self: start;
  }
  .case-pager > span:first-child { grid-row: 2; grid-column: 1; }
  .case-pager > span:last-child { grid-row: 2; grid-column: 2; }
  .case-pager a { display: block; text-align: center; }
}

.case-jump {
  grid-column: doc;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin: var(--sp-3) 0 0;
  padding: var(--sp-3);
  border: 1px solid var(--rule);
}

.case-jump label {
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-track);
  color: var(--graphite);
}

.case-jump input {
  width: 6rem;
  padding: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--control-border);
  border-radius: 2px;
}

.case-jump button {
  padding: var(--sp-2) var(--sp-3);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--on-ink);
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 2px;
  cursor: pointer;
}

.case-jump button:hover { background: var(--ink-2); border-color: var(--ink-2); }

.case-foot {
  grid-column: text;
  margin: var(--sp-5) 0 0 !important;
  padding-top: var(--sp-3);
  border-top: 1px solid var(--rule);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  color: var(--graphite);
}

.site-main:has(.case-body) > .case-foot,
.site-main:has(.case-body) > .attribution { grid-column: doc; }

.attribution {
  grid-column: text;
  margin: var(--sp-3) 0 0 !important;
  font-size: var(--fs-xs) !important;
  font-style: italic;
  line-height: 1.5;
  color: var(--graphite) !important;
}

/* ---------------------------------------------------------------------------
 * 12 · STATES
 * ---------------------------------------------------------------------------
 * Three states, three treatments, never interchangeable:
 *
 *   .empty-state    an operational fact — nothing indexed, index unreachable,
 *                   no such page. Neutral. Designed, not apologetic.
 *   .pending-notice an outstanding operator/counsel commitment. Ink keyline.
 *   .counsel-review the text is real and stands; no lawyer has read it. Quiet
 *                   on purpose — a loud banner would read as a disclaimer
 *                   undermining the policy it sits under.
 *
 * In each, the leading <strong> becomes a micro-caps eyebrow rather than a
 * bolder run of the same sentence, so the state has a NAME before it has an
 * explanation. The name is text, not colour, so it survives a screen reader,
 * a monochrome print and a colour-blind reader alike.
 * ------------------------------------------------------------------------ */

.empty-state {
  margin: var(--sp-4) 0 !important;
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--rule);
  border-left: 4px solid var(--rule);
  font-family: var(--font-serif);
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--ink) !important;
}

.empty-state > strong:first-child {
  display: block;
  margin-bottom: var(--sp-1);
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-track);
  color: var(--graphite);
}

.pending-notice {
  margin: var(--sp-4) 0 !important;
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--rule);
  border-left: 4px solid var(--ink);
  font-family: var(--font-serif);
  font-size: var(--fs-sm);
  line-height: 1.6;
}

.pending-notice > strong:first-child {
  display: block;
  margin-bottom: var(--sp-1);
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-track);
  color: var(--ink);
}

/* --- The gated state -------------------------------------------------------
 * A judgment withheld under the redaction gate is a FEATURE of this corpus,
 * not a failure of it, and its page must not look like a 404. withheld.html
 * carries a .lede and, unlike case_not_found.html, no search form — which is
 * enough to tell the two apart without a template edit.
 *
 * The treatment is a formal one: a solid ink rule above the title, the title
 * given room, the explanation set as continuous serif prose at reading size.
 * No warning colour, no icon, no exclamation. This page is the site keeping a
 * promise, and it should read as a considered editorial position rather than
 * as something having gone wrong.
 * ------------------------------------------------------------------------ */

.site-main:has(> .lede) > h1 {
  padding-top: var(--sp-3);
  margin-bottom: var(--sp-3);
}

.site-main:has(> .lede):not(:has(form)) > h1 {
  border-top: 4px solid var(--ink);
}

.site-main:has(> .lede):not(:has(form)) > p:not([class]) {
  font-size: var(--fs-base);
  line-height: 1.65;
  color: var(--ink);
}

/* --- Compliance-text markers ----------------------------------------------
 * .missing-fact is a fact the operator has NOT supplied, rendered inline and
 * left visible on purpose. It must stay conspicuous: an invented address on a
 * statutory page turns a known omission into a false statement.
 * ------------------------------------------------------------------------ */

.missing-fact {
  display: inline-block;
  padding: 0 var(--sp-1);
  border: 1px dashed var(--ink);
  border-radius: 2px;
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 0.8125em;
  white-space: normal;
}

.missing-fact-note {
  font-family: var(--font-sans);
  font-size: var(--fs-sm) !important;
  color: var(--graphite) !important;
}

.counsel-review {
  margin-top: var(--sp-5) !important;
  padding-top: var(--sp-3);
  border-top: 1px solid var(--rule);
  font-family: var(--font-sans);
  font-size: var(--fs-xs) !important;
  line-height: 1.55;
  color: var(--graphite) !important;
}

.counsel-review > strong:first-child {
  display: block;
  margin-bottom: var(--sp-1);
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: var(--label-track);
}

.policy-date {
  font-family: var(--font-sans);
  font-size: var(--fs-sm) !important;
  font-style: normal;
  color: var(--graphite) !important;
  letter-spacing: 0.01em;
}

.attribution-notice {
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--rule);
  font-size: var(--fs-sm) !important;
  line-height: 1.6;
  color: var(--ink-2) !important;
}

.contact-block {
  margin: var(--sp-3) 0 var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--rule);
}

.contact-block dt {
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-track);
  color: var(--graphite);
  margin-top: var(--sp-3);
}

.contact-block > dt:first-child { margin-top: 0; }

.contact-block dd {
  margin: var(--sp-1) 0 0;
  color: var(--ink);
  overflow-wrap: anywhere;
}

/* ---------------------------------------------------------------------------
 * 13 · FORMS
 * ---------------------------------------------------------------------------
 * Every control boundary is --control-border (4.38:1). WCAG 1.4.11 wants 3:1
 * for a UI component; the decorative --rule that used to sit on the search
 * input measured 1.32:1 and could not be seen at all against white.
 * ------------------------------------------------------------------------ */

input, button, select, textarea { font-family: inherit; }

/* The /notify signup. Explicitly NOT search-shaped: no plate keyline, no
   oversized field. Two objects that both take typed text must not look alike
   when one is the product and the other is a mailing list. */
.site-main > form[action="/notify"] {
  margin: var(--sp-3) 0 0;
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
  border: 1px solid var(--rule);
  border-top: 2px solid var(--rule);
}

.site-main > form[action="/notify"] p { margin: 0 0 var(--sp-3); }
.site-main > form[action="/notify"] p:last-of-type { margin-bottom: var(--sp-3); }

.site-main > form[action="/notify"] label {
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  color: var(--ink-2);
}

.site-main > form[action="/notify"] input[type="email"],
.site-main > form[action="/notify"] input[type="text"] {
  width: 100%;
  max-width: 22rem;
  margin-top: var(--sp-1);
  padding: 0.6rem 0.7rem;
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--control-border);
  border-radius: 2px;
}

.site-main > form[action="/notify"] input[type="checkbox"] {
  width: 1.05rem;
  height: 1.05rem;
  margin-right: 0.35rem;
  accent-color: var(--ink);
  vertical-align: -0.15em;
}

.site-main > form[action="/notify"] > button[type="submit"] {
  padding: var(--sp-2) var(--sp-4);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--on-ink);
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 2px;
  cursor: pointer;
}

.site-main > form[action="/notify"] > button[type="submit"]:hover {
  background: var(--ink-2);
  border-color: var(--ink-2);
}

/* Honeypot on /notify (see home.html and notify.py). Hidden from sight AND,
   with aria-hidden + tabindex="-1" on the field itself, from assistive
   technology. Positioned off-screen rather than display:none — some automated
   form-fillers skip fields hidden that way, and a human perceives no
   difference either way, since nobody is meant to perceive it at all. */
.hp-field {
  position: absolute;
  left: -9999px;
  top: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---------------------------------------------------------------------------
 * 14 · DARK MODE
 * ---------------------------------------------------------------------------
 * Offered because this audience reads dense prose for an hour at a stretch,
 * often at night. Same mechanism as before (the reader's prefers-color-scheme,
 * no toggle, no JavaScript); values are brand spec §2.1's dark column,
 * verbatim, measured on --paper #111317:
 *
 *   ink    #ECEDEF 15.87:1    ink-2 #C3C7CD 10.95:1    graphite #9BA1A9 7.14:1
 *   rule   #2A2E35  1.36:1 (decorative)    control-border #8B94A1 6.06:1
 *   mark   ground #4A3F0A, text #FFF6C7 9.60:1, 2px underline #FFE872
 *
 * The monogram keeps its yellow block and ink glyphs in both themes: a marker
 * stroke is yellow on any paper. It is an SVG with its own fills.
 * ------------------------------------------------------------------------ */

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --paper: #111317;
    --ink: #ecedef;
    --ink-2: #c3c7cd;
    --graphite: #9ba1a9;
    --rule: #2a2e35;
    --control-border: #8b94a1;
    --hl-ground: #4a3f0a;
    --hl-text: #fff6c7;
  }

  mark {
    text-decoration: underline 2px var(--highlighter);
    text-underline-offset: 0.2em;
    text-decoration-skip-ink: none;
  }
}

/* ---------------------------------------------------------------------------
 * 15 · MOTION
 * ------------------------------------------------------------------------ */

.doc-list > li,
.count-list > li,
.pagination a,
.case-pager a,
.search-form button,
.case-jump button,
.hero-search button,
.hero-examples li a,
.result-pager a {
  transition: background-color 120ms ease-out, border-color 120ms ease-out,
    color 120ms ease-out;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------------------------------------------------------------------------
 * 16 · PRINT
 * ---------------------------------------------------------------------------
 * An advocate prints the judgment. Give them the record and nothing else
 * (chunk B, brief step 5):
 *   - no nav, footer, or buttons;
 *   - a running header carrying the citation, on every printed page;
 *   - paragraph numbers kept (the copy CONTROL beside each one is not --
 *     "copy to clipboard" means nothing on paper);
 *   - Literata 11pt, black on white;
 *   - a pinpoint link's own href never expanded after it;
 *   - the highlighter as a light grey underline, never the on-screen
 *     yellow fill (spec §2.1 reserves the yellow fill for screen; paper
 *     is monochrome by definition here, and a filled highlight wastes a
 *     reader's toner for no benefit an underline does not already give).
 *
 * `.print-running-header` (see case.html) is `display: none` on screen --
 * see section 11a-4 below -- and shown here as `position: fixed`, which
 * Chrome repeats on every printed page (the standard technique; no
 * `@page` margin-box support is needed because of it).
 * ------------------------------------------------------------------------ */

@media print {
  :root {
    --paper: #ffffff;
    --ink: #000000;
    --ink-2: #000000;
    --graphite: #333333;
  }

  /* "No nav, footer or buttons": the nav inside the header, and the
     WHOLE footer (its own nav plus the copyright line) -- the header
     element itself (just the lockup, once its nav is gone) stays, so a
     printed page still says whose corpus this is. */
  .site-nav,
  .site-footer,
  .search-form,
  .case-jump,
  .case-foot,
  .pagination,
  .hl-lozenge,
  .copy-citation,
  .copy-pin { display: none; }

  .site-header { border-color: #000; }
  .site-header::after { display: none; }

  .site-main { display: block; padding: 0; margin-top: 2.2em; }

  .print-running-header {
    display: block;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    padding-bottom: 0.3em;
    border-bottom: 1px solid #000;
    font-family: var(--font-mono);
    font-size: 9pt;
    color: #000;
  }

  .case-body, .case-headnote {
    font-family: var(--font-serif);
    font-size: 11pt;
    line-height: 1.45;
    border-color: #000;
    background: none;
    color: #000;
  }

  /* Paragraph numbers stay (the rail's absolute, negative-margin
     positioning assumes a screen viewport's flexible outer gutter, which
     a printed page's own margin does not reproduce) -- same inline
     treatment `.para-rail`'s own mobile fallback already uses. */
  .para-rail {
    position: static !important;
    display: inline-flex !important;
    margin-right: var(--sp-2);
  }

  a { text-decoration: none; color: #000; }

  /* A pinpoint's own href is never printed after it -- some print
     stylesheets append `" (" attr(href) ")"` after every link; this one
     never has, and this rule keeps it that way explicitly rather than by
     omission. */
  .case-body a[href]::after,
  .citation-plate a[href]::after { content: none !important; }

  mark {
    background: none;
    color: inherit;
    text-decoration: underline 2px #999999;
    text-underline-offset: 0.2em;
    text-decoration-skip-ink: none;
  }

  .doc-list > li, .count-list > li, .case-headnote { break-inside: avoid; }
}

/* ---------------------------------------------------------------------------
 * 17 · THE HOMEPAGE HERO
 * ---------------------------------------------------------------------------
 * The homepage used to contain exactly one form -- the email signup -- while
 * search, the entire product, was a 15px grey link in fourth place in the nav.
 * The field below is the first interactive element on the page.
 *
 * It is deliberately NOT the plated .search-form used on /search: a hero wants
 * one heavy object, not a panel inside a panel. What it does share is the type
 * (micro-caps label, reading serif in the field), the 54px control height and
 * the focus behaviour, so the two read as the same instrument in two settings.
 * Its 2px ink keyline (spec §2.4) is 17.13:1 light / 15.87:1 dark, well past
 * the 3:1 WCAG 1.4.11 asks of a control boundary.
 * ------------------------------------------------------------------------ */

.hero-search {
  grid-column: wide;
  margin: var(--sp-4) 0 var(--sp-3);
}

.hero-search label {
  display: block;
  margin-bottom: var(--sp-2);
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-track);
  color: var(--graphite);
}

.hero-search__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  max-width: 46rem;
}

.hero-search input[type="search"] {
  flex: 1 1 18rem;
  min-width: 0;
  min-height: 3.4rem;
  padding: 0 var(--sp-3);
  font-family: var(--font-serif);
  font-size: var(--fs-md);
  color: var(--ink);
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: 2px;
}

.hero-search input[type="search"]::placeholder {
  color: var(--graphite);
  opacity: 1;
}

.hero-search button {
  min-height: 3.4rem;
  padding: 0 var(--sp-4);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--on-ink);
  background: var(--ink);
  border: 2px solid var(--ink);
  border-radius: 2px;
  cursor: pointer;
}

.hero-search button:hover { background: var(--ink-2); border-color: var(--ink-2); }

/* Real queries against the real corpus -- they teach what the box accepts and
   give a visitor with no query of their own a way in. The chip's outline is
   --control-border (4.38:1), not a decorative rule: these are the second
   interactive thing on the page and their boundary should be seen. */
.hero-examples {
  grid-column: wide;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-5);
  padding: 0;
  list-style: none;
}

.hero-examples li a {
  display: inline-block;
  padding: var(--sp-1) var(--sp-3);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  color: var(--ink);
  text-decoration: none;
  border: 1px solid var(--control-border);
  border-radius: 2px;
}

.hero-examples li a:hover {
  color: var(--on-ink);
  background: var(--ink);
  border-color: var(--ink);
  text-decoration: none;
}

/* The sentence under the figures band that reconciles them (harvested =
   published + withheld). Pulled up tight against the band it explains. */
.stat-note {
  margin-top: calc(var(--sp-4) * -1);
  font-size: var(--fs-sm) !important;
  color: var(--ink-2) !important;
}

/* ---------------------------------------------------------------------------
 * 18 · SEARCH-RESULT FURNITURE
 * ---------------------------------------------------------------------------
 * The count, the sort control and the pager annotate the result list, so they
 * sit in the list's band and not in the prose band -- otherwise their left and
 * right edges disagree with the rows they belong to.
 * ------------------------------------------------------------------------ */

.result-count,
.sort-bar,
.result-pager { grid-column: wide; }

.result-count {
  margin-bottom: var(--sp-2) !important;
  font-family: var(--font-sans);
  font-size: var(--fs-sm) !important;
  color: var(--graphite) !important;
  font-variant-numeric: tabular-nums;
}

.result-count strong { color: var(--ink); font-weight: 600; }

/* Sort is a control, so it is set as one: micro-caps, with the active option
   carried by weight and ink rather than by colour alone. */
.sort-bar {
  margin: 0 0 var(--sp-3) !important;
  font-family: var(--font-sans);
  font-size: var(--fs-2xs) !important;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--label-track);
  color: var(--graphite) !important;
}

.sort-bar strong {
  color: var(--ink);
  border-bottom: 2px solid var(--ink);
  padding-bottom: var(--sp-1);
}

.sort-bar a { text-decoration: none; }

.result-pager {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-3) var(--sp-3);
  margin-top: var(--sp-4) !important;
  padding-top: var(--sp-3);
  border-top: 2px solid var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-sm) !important;
  color: var(--graphite) !important;
  font-variant-numeric: tabular-nums;
}

.result-pager span:first-child,
.result-pager span:last-child {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
}

.result-pager a {
  display: inline-block;
  padding: var(--sp-2) var(--sp-3);
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  border: 1px solid var(--control-border);
  border-radius: 2px;
  white-space: nowrap;
}

.result-pager a:hover {
  color: var(--on-ink);
  background: var(--ink);
  border-color: var(--ink);
  text-decoration: none;
}

/* ---------------------------------------------------------------------------
 * 19 · THE LINK BAND
 * ---------------------------------------------------------------------------
 * Spec §2.1: on hover a link's 1px underline becomes a 0.35em highlighter
 * band. An underline is painted BENEATH the text, so the letters stay ink on
 * top of the stroke. The current nav item keeps the band (spec §2.4). This
 * section is LAST on purpose: every component rule above that resets a link's
 * decoration has the same specificity as its entry here, so this one wins.
 * Links styled as controls (pagers, chips) opt out on their own :hover rule
 * with `text-decoration: none` at higher specificity.
 * ------------------------------------------------------------------------ */

a:hover,
.site-nav a:hover,
.site-nav a[aria-current="page"],
.footer-nav a:hover,
a.doc-title:hover,
.doc-list > li > a:first-child:hover,
.count-list a:hover,
.sort-bar a:hover {
  text-decoration-line: underline;
  text-decoration-color: var(--hl-ground);
  text-decoration-thickness: 0.35em;
  text-underline-offset: -0.1em;
  text-decoration-skip-ink: none;
}

/* Dark: the spec expresses the highlighter as a 2px #FFE872 underline on a
   deep amber ground (§2.1, dark column). A 0.35em band of that ground under
   pale text measures ~1.9:1 against the page and all but disappears, so on
   dark paper the band IS that 2px underline -- the same stroke a dark <mark>
   carries. */
@media (prefers-color-scheme: dark) {
  a:hover,
  .site-nav a:hover,
  .site-nav a[aria-current="page"],
  .footer-nav a:hover,
  a.doc-title:hover,
  .doc-list > li > a:first-child:hover,
  .count-list a:hover,
  .sort-bar a:hover {
    text-decoration-color: var(--highlighter);
    text-decoration-thickness: 2px;
    text-underline-offset: 0.2em;
  }
}
