/* Shared checklist page styles, used by /k1-checklist/ and /i129f-checklist/.

   Extracted 08/17/2026. The two pages had drifted into 252 identical lines across two
   page.css files, which is how a fix lands on one checklist and not the other. They are
   one component, so they are one stylesheet.

   This file is the UNION of what the two pages needed, not the intersection. A handful of
   selectors here match nothing on one page or the other (.post-picker, .post-panel,
   .post-meta, .stale-flag, .progress-note and .faq are k1-only today; .group-note and
   .radio-item are i129f-only). That is deliberate: they are checklist-page components, not
   page-specific ones, and a third checklist gets them without another round of copying.

   Each page's own page.css loads AFTER this file and carries only what genuinely differs. */

  .legal { padding-top: var(--space-6); padding-bottom: var(--space-3); }
  .print-logo { display: none; }
  .legal h1 { font-size: clamp(1.75rem, 2vw + 1.4rem, 2.25rem); margin-bottom: var(--space-2); }
  /* `.legal > p.lead`, NOT `.legal > .wrap > p.lead`. The container is a single
     `<section class="legal wrap">` carrying both classes, so the old child-combinator form
     needed two nested elements and matched nothing on either checklist. The lead had been
     rendering with only style.css's bare `p` rule since it was written: full Ink instead of
     Ink Muted, and no measure cap, so it ran the full 720px column.
     The print block was never affected, because it uses the descendant form `.legal .lead`,
     which does match. That is why the bug survived: the printed page was correct.
     Found and fixed 08/17/2026 during the two-stylesheet de-duplication. */
  .legal > p.lead {
    font-family: var(--font-body); font-size: 1.0625rem; line-height: 1.6;
    color: var(--ink-muted); max-width: 58ch; margin-bottom: var(--space-3);
  }
  .source-line {
    font-family: var(--font-mono); font-size: 0.75rem; color: var(--ink-faint);
    line-height: 1.6; margin-top: var(--space-3); margin-bottom: var(--space-4);
  }
  .source-line a { color: var(--accent); font-weight: 600; text-decoration-thickness: 1px; text-underline-offset: 2px; }
  @media (hover: hover) and (pointer: fine) {
    .source-line a:hover { color: var(--accent-hover); }
  }

  .tips-list {
    list-style: none; margin: 0 0 var(--space-4); padding: var(--space-3);
    border: 1px solid var(--border); background: var(--surface);
    display: flex; flex-direction: column; gap: var(--space-1);
  }
  .tips-list li {
    font-family: var(--font-body); font-size: 0.875rem; color: var(--ink-muted);
    line-height: 1.5; padding-left: 20px; position: relative;
  }
  .tips-list li::before {
    content: ''; position: absolute; left: 0; top: 6px; width: 8px; height: 8px;
    border-radius: 50%; background: var(--accent);
  }

  .post-picker {
    margin: 0 0 var(--space-4); padding: var(--space-3);
    border: 1px solid var(--border-strong); background: var(--surface);
  }
  .post-picker label { display: block; font-family: var(--font-mono); font-size: 0.75rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 8px; }
  .post-picker .picker-note { margin-top: 10px; font-family: var(--font-body); font-size: 0.8125rem; color: var(--ink-faint); line-height: 1.5; }

  /* Brand component: dropdown (brand.bonavault.com Components section) */
  .bv-select-wrap { position: relative; }
  .bv-select {
    width: 100%; font-family: var(--font-body); font-size: 0.9375rem;
    line-height: 1.5; min-height: calc(1.5em + var(--space-2) + 2px);
    padding: var(--space-1) var(--space-5) var(--space-1) var(--space-2); border: 1px solid var(--border-strong); border-radius: 0;
    background: var(--surface); color: var(--ink); outline: none; appearance: none; -webkit-appearance: none;
    cursor: pointer; box-shadow: 0 0 0 0 var(--accent);
    transition: box-shadow 220ms var(--ease), border-color 150ms var(--ease);
  }
  @media (hover: hover) and (pointer: fine) {
    .bv-select:hover { border-color: var(--ink); }
  }
  .bv-select:focus { box-shadow: 0 0 0 2px var(--accent); border-color: var(--border-strong); }
  .bv-select-wrap::after {
    content: ''; position: absolute; right: var(--space-3); top: 50%; width: 8px; height: 8px;
    border-right: 1px solid var(--ink-faint); border-bottom: 1px solid var(--ink-faint);
    transform: translateY(-65%) rotate(45deg); pointer-events: none;
    transition: border-color 150ms var(--ease);
  }
  .bv-select-wrap:has(.bv-select:focus)::after { border-color: var(--accent); }
  /* Focus changes the caret's color and nothing else, per the brand guideline. It used to turn
     over too, which read as "this menu is open" when the menu was merely focused, and drifted
     while it turned. Synced 07/31/2026.
     line-height and min-height are stated so the control's height does not depend on its
     content: this picker always has a selected option, but the rule is the system's, and
     letting it drift here is how the app and the site diverged from the spec before. */
  /* Hand-rolled caret, not a library chevron, per the brand guideline's custom-icon-language rule.
     border-radius: 0 stated explicitly: Safari keeps a faint native corner-rounding on <select>
     even with appearance:none reset, the one place the brand guideline's own dropdown spec was
     visibly wrong, fixed here and at the source. */

  .post-panel { display: none; }
  .post-panel.active { display: block; }

  .post-meta { padding: var(--space-3); border: 1px solid var(--border); background: var(--surface); margin-bottom: var(--space-3); }
  .post-meta h2 { font-size: 1.25rem; margin: 0 0 6px; }
  .post-meta .post-updated { font-family: var(--font-mono); font-size: 0.75rem; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.04em; }
  .post-meta .post-process { margin-top: 10px; font-size: 0.9375rem; color: var(--ink-muted); line-height: 1.55; }
  .post-meta .post-process strong { color: var(--ink); }

  .stale-flag {
    margin: 0 0 var(--space-3); padding: var(--space-2) var(--space-3);
    border: 1.5px solid var(--accent); background: var(--surface);
    font-family: var(--font-body); font-size: 0.875rem; color: var(--ink-muted); line-height: 1.5;
  }
  .stale-flag strong { color: var(--accent); }

  .checklist-toolbar {
    display: flex; align-items: center; flex-wrap: nowrap;
    gap: var(--space-3); justify-content: space-between;
    padding: var(--space-2) var(--space-1);
    margin: 0 calc(var(--space-1) * -1) var(--space-3);
    position: sticky; top: calc(var(--header-h) - 1px); z-index: 5;
    transition: top 220ms var(--ease);
  }
  /* Mobile-only, added by the same scroll JS that hides .site-header: drops the sticky offset to
     0 so the toolbar fills the header's vacated space instead of leaving a gap. Animates `top`,
     not `transform`, on purpose: a transform shift would apply even while the toolbar is still in
     normal document flow (hasn't reached its sticky point yet), yanking it up early and leaving a
     stray gap below it. `top` only affects a sticky element once it's actually stuck, so there's
     no premature jump regardless of scroll position when the header hides. */
  .checklist-toolbar.toolbar-pinned-top { top: 0; }
  .checklist-toolbar::before {
    content: ''; position: absolute; top: 0; bottom: 0; left: 50%; width: 100vw;
    transform: translateX(-50%); z-index: -1;
    background: var(--header-glass);
    /* Prefix FIRST, standard LAST, and that order is load-bearing. See the "build can delete a
       property the source declares" rule in the design guideline: a minifier that treats the two
       as one property keeps only the last declared, and Chrome does not honour
       -webkit-backdrop-filter on its own. This site has no build step today, so the order costs
       nothing here and stops being a latent bug the moment one is added. */
    -webkit-backdrop-filter: blur(16px) saturate(160%);
    backdrop-filter: blur(16px) saturate(160%);
    border-bottom: 1px solid var(--border);
    opacity: 0;
    transition: opacity 180ms var(--ease);
  }
  /* Only paint the glass once the bar is genuinely pinned. Painting it unconditionally meant the
     full-bleed panel and its border rendered at scroll position 0, while the toolbar was still in
     normal flow, reading as an arbitrary viewport-wide section divider aligned to nothing. */
  .checklist-toolbar.is-stuck::before { opacity: 1; }
  /* The offset comes from --header-h in style.css, minus 1px, so the toolbar
     overlaps the header edge by a hairline instead of abutting it. Abutting is what opens a
     seam: at a fractional device pixel ratio or a browser zoom that is not 100%, an offset that
     exactly equals the header height can round to one device pixel lower and show a 1px line of
     page content between the two. A 1px overlap can only ever round into the header, which is
     invisible because the toolbar paints its own glass over it. The glass background
     lives on a ::before sized to the full viewport (100vw, centered), not the toolbar's own box,
     because the toolbar's box is only as wide as the page's content column (.wrap, 720px): a glass
     fill scoped to that narrower box shows its own edges once something colorful scrolls behind it
     at an angle, a visible seam .site-header never has since it already spans edge to edge. The
     ::before fixes that by matching the header's full-bleed behavior while the actual content
     (label, bar, buttons) stays aligned to the normal content column via the parent's own padding.
     Uses the same Header Glass fill + blur as .site-header itself, per the brand guideline's rule
     that every sticky surface reads as glass, never a flat solid color. */
  .toolbar-actions { display: flex; gap: var(--space-2); flex: 0 0 auto; }
  .btn-icon {
    position: relative;
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; flex: 0 0 auto;
    background: transparent; color: var(--ink); border: 1px solid var(--border-strong);
    cursor: pointer;
    transition: background-color 150ms var(--ease), color 150ms var(--ease);
  }
  /* 44x44 minimum hit area per the brand guideline's icon-only-control rule, without growing
     the 36px visual box: the pseudo-element extends the tap target past the drawn border
     rather than resizing the button, the same fix already applied to the theme toggle. */
  .btn-icon::after {
    content: ''; position: absolute; top: 50%; left: 50%;
    width: 44px; height: 44px; transform: translate(-50%, -50%);
  }
  @media (hover: hover) and (pointer: fine) {
    .btn-icon:hover { background: var(--ink); color: var(--paper); }
  }
  .btn-icon svg { width: 16px; height: 16px; flex: 0 0 auto; }

  /* Brand component: coverage bar (brand.bonavault.com Components section) */
  .coverage-wrap { flex: 1 1 240px; min-width: 200px; max-width: 360px; }
  .coverage-label { display: flex; justify-content: space-between; font-family: var(--font-mono); font-size: 0.75rem; line-height: 1; color: var(--ink-faint); margin-bottom: var(--space-1); }
  /* --fill is the initial value only; checklist.js overwrites it via setProperty on every
     tick. It lived on the element as style="--fill:0" until 08/17/2026, when it moved here so
     the page carries no inline style and style-src can drop 'unsafe-inline'. */
  .coverage { height: 6px; width: 100%; background: var(--border); position: relative; overflow: hidden; --fill: 0; }
  /* Scales a full-width bar instead of animating its width: width is a layout property, so the
     old version relaid out the bar on every tick. --fill is a unitless 0-1 ratio, not a
     percentage, because scaleX() takes a number. */
  .coverage .fill {
    height: 100%; width: 100%; background: var(--accent);
    transform: scaleX(var(--fill, 0)); transform-origin: left center;
    transition: transform 300ms var(--ease);
  }

  .checklist-group { border: none; margin: 0; min-width: 0; padding: var(--space-4) 0; border-top: 1px solid var(--border); }
  .checklist-group:first-of-type { border-top: none; padding-top: var(--space-2); }
  .group-title { display: block; width: 100%; padding: 0; font-size: 1.0625rem; font-weight: 700; font-family: var(--font-body); color: var(--ink); margin: 0 0 6px 0; text-wrap: initial; }
  .group-note { font-weight: 400; color: var(--ink-faint); font-family: var(--font-mono); font-size: 0.75rem; letter-spacing: 0.04em; text-transform: uppercase; }

  /* `.post-source` reused inside a checklist group, where it names the document that group's
     items come from. Its own margin-top is sized for sitting under the post picker with air
     around it; inside a fieldset that reads as a gap between the title and its own citation,
     so the offset is tightened here rather than changed at the source, which the K-1 page's
     per-post usage still depends on. */
  .checklist-group .post-source { margin: 0 0 var(--space-2) 0; }

  /* Brand component: list / item row (brand.bonavault.com Components section), adapted so the
     secondary line carries a full explanatory sentence (item-hint) instead of the guideline's
     short trailing item-meta tag, since these checklist items need real explanations, not a
     one-word category. */
  .item-list { display: flex; flex-direction: column; }
  .item-row {
    position: relative; display: grid; grid-template-columns: auto 1fr; align-items: flex-start; gap: var(--space-2);
    padding: 10px var(--space-1); margin: 0 calc(var(--space-1) * -1);
    cursor: pointer; -webkit-tap-highlight-color: transparent;
    transition: background-color 150ms var(--ease);
  }
  /* The divider sits BETWEEN rows, as a top border on every row after the first, rather than
     as a bottom border on every row but the last. Same rendering, but it survives insertion:
     with border-bottom the divider belongs to the row above, so adding a row makes that
     divider appear instantly while the new row is still fading in, and you watch a line arrive
     into empty space. As a top border it is part of the new row and animates in with it.
     Expressed as an adjacent-sibling rule so there is no first/last bookkeeping to get wrong. */
  .item-row + .item-row { border-top: 1px solid var(--border); }
  .item-row input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
  /* 1px, not 1.5px: at 1.5 the control read heavy against the 1px dividers the rest of the list
     is built from, and it read heavier still once optional boxes went dashed, because dashes at
     that weight render as chunky blocks. Thinned everywhere rather than only on the dashed ones,
     so that weight carries no meaning and style alone separates optional from required. AJ's
     call 08/19/2026, chosen against a variant that thinned only the optional boxes. */
  .item-row .check {
    width: 18px; height: 18px; margin-top: 2px; flex: none; border: 1px solid var(--border-strong); background: var(--surface);
    display: flex; align-items: center; justify-content: center;
    transition: background-color 150ms var(--ease), border-color 150ms var(--ease), transform 120ms var(--ease);
  }
  /* Optional means "if applicable": checkable and remembered like anything else, it just does
     not count toward progress. Dashed says provisional; it does not say unavailable. That is a
     deliberate swap agreed with bonavault-app on 08/19/2026, where dashed previously meant a row
     nobody can tick and now light grey carries that instead. The two surfaces must stay in step.
     Both selectors are required: optionality is marked on the fieldset where items group cleanly
     (i129f, aos) and on the input where they interleave (k1), per the guideline's rule that it is
     marked at whatever level the structure defines. A rule with one selector silently skips a
     whole page. Colour is untouched: dashed and faint would be two signals for one idea. */
  .checklist-group[data-progress="optional"] .item-row .check,
  .item-row input[data-progress="optional"] + .check {
    border-style: dashed;
  }
  .item-row .check svg { width: 12px; height: 12px; }
  .item-row .check .check-path { stroke-dasharray: 12; stroke-dashoffset: 12; }
  .item-row input:checked ~ .check { background: var(--accent); border-color: var(--accent); }
  .item-row input:checked ~ .check .check-path { stroke-dashoffset: 0; transition: stroke-dashoffset 260ms var(--ease) 20ms; }
  .item-row input:active ~ .check { transform: scale(0.88); }
  @media (hover: hover) and (pointer: fine) {
    .item-row:hover { background: var(--surface); }
  }
  .item-row:has(input:focus-visible) { box-shadow: inset 0 0 0 2px var(--accent); }
  /* The radio variant, for a group where the choices are mutually exclusive rather than
     cumulative: round box, no tick, a filled dot instead. The check svg is hidden rather than
     omitted from the markup so one row template serves both variants. */
  .item-row.radio-item .check { border-radius: 50%; }
  .item-row.radio-item .check svg { display: none; }
  .item-row.radio-item .check::after {
    content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--accent);
    opacity: 0; transform: scale(0.4); transition: opacity 180ms var(--ease), transform 180ms var(--ease);
  }
  .item-row.radio-item input:checked ~ .check { background: var(--surface); border-color: var(--accent); }
  .item-row.radio-item input:checked ~ .check::after { opacity: 1; transform: scale(1); }
  .item-copy { display: flex; flex-direction: column; gap: 3px; }
  .item-row .item-label { font-family: var(--font-body); font-size: 0.9375rem; color: var(--ink-muted); line-height: 1.5; }
  .item-row .item-hint { font-family: var(--font-body); font-size: 0.8125rem; color: var(--ink-faint); line-height: 1.5; }
  .item-row input:checked ~ .item-copy .item-label { color: var(--ink-faint); }

  .scope-note {
    margin-top: var(--space-4); padding-top: var(--space-3); border-top: 1px solid var(--border);
    font-size: 0.875rem; color: var(--ink-faint); line-height: 1.6; max-width: 58ch;
  }
  .post-source {
    margin-top: var(--space-3); font-family: var(--font-mono); font-size: 0.75rem; color: var(--ink-faint); line-height: 1.6;
  }
  .post-source a { color: var(--accent); font-weight: 600; text-decoration-thickness: 1px; text-underline-offset: 2px; }
  @media (hover: hover) and (pointer: fine) {
    .post-source a:hover { color: var(--accent-hover); }
  }

  /* Sits directly under the toolbar, deliberately far from the signup block at the end of the
     page. The two must never read as one offer: the email does not back up a checklist, and
     putting a storage warning next to a signup field implies exactly that. */
  .storage-note {
    margin: calc(var(--space-1) * -1) 0 var(--space-3);
    font-family: var(--font-body); font-size: 0.8125rem;
    color: var(--ink-faint); line-height: 1.5;
  }

  /* Same voice as .storage-note and sits directly under the coverage bar. Was an inline style
     attribute until 08/17/2026, which is why its margin is a literal -8px rather than the
     negative space token .storage-note uses: kept byte-identical in the move so the extraction
     changed nothing visually. Worth reconciling to calc(var(--space-1) * -1) on the next touch. */
  .progress-note {
    margin: -8px 0 var(--space-3);
    font-family: var(--font-body); font-size: 0.8125rem;
    color: var(--ink-faint); line-height: 1.5;
  }

  /* Sits after the post panels because it answers what people ask once the documents are
     gathered, not while they're gathering them. Outside the panels on purpose: neither question
     is post-specific, so duplicating it into all nine would be nine copies of one answer. */
  .faq { margin-top: var(--space-5); padding-top: var(--space-4); border-top: 1px solid var(--border); }
  .faq h2 { font-size: 1.25rem; margin: 0 0 var(--space-3); }
  .faq h3 { font-size: 1rem; margin: 0; }
  .faq-item + .faq-item { border-top: 1px solid var(--border); }

  /* Native <details>, so it works with no JS and keyboard/screen-reader behavior comes for free.
     The chevron is .nav-caret's, rotating on open, because that is already this system's signal
     for "this is open" (the Tools dropdown). Deliberately NOT the .bv-select caret, which never
     turns: that one is a select, whose open state CSS cannot see, so a flip there would be a lie.
     Here the open state is real and expressed in the DOM, so the rotation is honest. */
  .faq-item > summary {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
    padding: var(--space-3) 0; cursor: pointer; list-style: none;
    -webkit-tap-highlight-color: transparent;
  }
  .faq-item > summary::-webkit-details-marker { display: none; }
  .faq-item > summary:focus-visible { box-shadow: inset 0 0 0 2px var(--accent); }
  /* Hover: a Border Strong hairline under the label, plus the caret stepping Ink Faint to Ink.
     AJ's call 08/09/2026, made against all three alternatives rendered in a browser.

     The honest note on it, so nobody "corrects" this later into something already rejected: this
     extends .nav-link's pattern rather than matching it, because that pattern pairs the hairline
     with an Ink Faint to Ink colour step and a full-Ink serif heading has nowhere to step to. The
     caret carries that half instead.

     What was tried and rejected, so it is not cycled through again:
     - Surface fill, twice. It is .item-row's documented precedent and it is the closest
       structural sibling, but --surface is a PANEL fill in this system (.post-meta, .tips-list,
       .post-picker, .checklist-cta all sit in it permanently with a border), so a row that
       briefly takes it reads as a static panel flickering into existence. Fine on a dense
       checkbox row, wrong under a 60px serif heading.
     - Caret step alone. Correct by precedent (.upload-zone:hover svg) and too quiet for a
       full-width target.

     The hairline is transparent by default so hovering moves no layout, and it sits on the h3
     rather than the summary so it tracks the label instead of the full row. Nothing in this
     section bleeds past the content column: the section rule, the dividers and this underline
     all resolve against the same two edges, which is the alignment bug the fill version had. */
  /* 1px, not .nav-link's 2px. That weight is built for 15px sans nav text in the header; under a
     serif heading it renders as the heaviest line in this section, against 1px dividers on either
     side of it. */
  .faq-item > summary h3 {
    border-bottom: 1px solid transparent;
    transition: border-color 150ms var(--ease);
  }
  @media (hover: hover) and (pointer: fine) {
    .faq-item > summary:hover h3 { border-bottom-color: var(--border-strong); }
    .faq-item > summary:hover .faq-caret { color: var(--ink); }
  }
  /* 16px on a 24-unit viewBox at stroke 1.6, matching .btn-icon svg in the toolbar above rather
     than .nav-caret in the header. The nav caret is 10px on a 10-unit viewBox at stroke 1.4,
     which renders a 1.4px stroke: on this row it was both the smallest glyph on the page and the
     heaviest-stroked one, since the toolbar's 16px icons resolve to ~1.07px. Scaling the 10-unit
     caret up would have made that worse, taking the stroke to 2.24px. Same drawn shape, drawn on
     the grid the rest of this page's icons use. */
  .faq-caret {
    width: 16px; height: 16px; flex: 0 0 auto; color: var(--ink-faint);
    transition: transform 200ms var(--ease), color 150ms var(--ease);
  }
  .faq-item[open] > summary .faq-caret { transform: rotate(180deg); }
  .faq-answer { padding-bottom: var(--space-3); }
  .faq p { font-family: var(--font-body); font-size: 0.9375rem; color: var(--ink-muted); line-height: 1.6; max-width: 62ch; }
  .faq p + p { margin-top: var(--space-2); }
  .faq .faq-source { font-family: var(--font-mono); font-size: 0.75rem; color: var(--ink-faint); line-height: 1.6; margin-top: var(--space-2); }
  .faq .faq-source a { color: var(--accent); font-weight: 600; text-decoration-thickness: 1px; text-underline-offset: 2px; }
  @media (hover: hover) and (pointer: fine) {
    .faq .faq-source a:hover { color: var(--accent-hover); }
  }

  /* The two checklists are one chronological sequence, not peer pages: whoever finishes the
     petition list needs the interview list six to ten months later. */
  .next-stage {
    margin-top: var(--space-5); padding-top: var(--space-3);
    border-top: 1px solid var(--border);
  }
  .next-stage-label {
    display: block; font-family: var(--font-mono); font-size: 0.6875rem; font-weight: 600;
    letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint);
    margin-bottom: var(--space-1);
  }
  .next-stage p { font-size: 1.0625rem; line-height: 1.4; }
  .next-stage a { color: var(--accent); font-weight: 700; text-decoration-thickness: 1px; text-underline-offset: 2px; }
  @media (hover: hover) and (pointer: fine) {
    .next-stage a:hover { color: var(--accent-hover); }
  }
  .next-stage-note { margin-top: var(--space-1); font-size: 0.875rem; color: var(--ink-faint); line-height: 1.5; max-width: 58ch; }

  .checklist-cta {
    margin-top: var(--space-5); padding: var(--space-4);
    border: 1px solid var(--border-strong); background: var(--surface);
  }
  .checklist-cta p { font-size: 0.9375rem; color: var(--ink-muted); line-height: 1.55; }
  .checklist-cta p + p { margin-top: var(--space-2); }
  .checklist-cta .cta-lead {
    margin-top: var(--space-4); padding-top: var(--space-3);
    border-top: 1px solid var(--border);
    color: var(--ink); font-weight: 700;
  }
  .checklist-cta .signup-form { margin-top: var(--space-2); }
  .checklist-cta .cta-link { margin-top: var(--space-3); }
  /* Scoped to the standalone action link only. As a blanket rule on the block it also caught
     the consent checkbox's "privacy note" link, which is an inline prose link and renders at
     400 inside the identical markup on the homepage. Same component, two weights. */
  .checklist-cta .cta-link a { font-weight: 700; }
  .checklist-cta a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
  @media (hover: hover) and (pointer: fine) {
    .checklist-cta a:hover { color: var(--accent-hover); }
  }

  @media (max-width: 640px) {
    .coverage-wrap { max-width: none; }
  }

  @media print {
    @page { margin: 12mm; }
    .site-header, .site-footer, .checklist-toolbar, .checklist-cta, .post-picker, .progress-note,
    .storage-note, .next-stage, .faq { display: none !important; }
    body { background: #fff; color: #000; font-size: 9.5pt; line-height: 1.3; }
    .legal { padding-top: 0; }
    .print-logo { display: flex; align-items: center; gap: 5pt; margin-bottom: 6pt; }
    .print-logo span { font-family: Georgia, serif; font-weight: 700; font-size: 9.5pt; color: #000; }
    .legal h1 { font-size: 14pt; margin-bottom: 3pt; }
    /* Written as `.legal > p.lead`, matching the screen rule's specificity (0,2,1). The old
       `.legal .lead` form here is (0,2,0) and LOSES to it, which did not matter while the screen
       selector was broken and matched nothing: this print rule was unopposed and correct. The
       moment the screen selector was fixed on 08/17/2026 it began overriding print's font-size
       and imposing its 58ch cap on paper. Both are restored here.
       max-width is explicitly none: paper is not a reading column. */
    .legal > p.lead {
      font-size: 8.5pt; margin-bottom: 4pt; max-width: none;
      /* line-height and font-family are reset to the print body's, not restated. Every
         declaration the screen rule makes has to be answered here now that it applies: it sets
         line-height 1.6 against print's body 1.3, which is a third more leading on every line
         of the lead. Inherit rather than a literal so this tracks the body rule if it moves. */
      line-height: inherit; font-family: inherit;
    }
    .legal h1, .legal .lead, .source-line, .scope-note, .post-source { color: #000 !important; }
    .source-line { font-size: 7pt; margin-top: 3pt; margin-bottom: 5pt; }
    .tips-list { padding: 4pt 6pt; margin-bottom: 5pt; gap: 1.5pt; border-color: #ccc; background: #fff !important; }
    .tips-list li { font-size: 6.5pt; color: #000 !important; padding-left: 9pt; }
    .tips-list li::before { width: 4pt; height: 4pt; top: 3pt; background: #000; }
    .post-meta { border-color: #ccc; padding: 5pt 6pt; margin-bottom: 5pt; }
    .post-meta h2 { font-size: 10pt; }
    .post-meta .post-updated, .post-meta .post-process { color: #000 !important; font-size: 7pt; }
    .stale-flag { border-color: #000; padding: 4pt 6pt; margin-bottom: 5pt; font-size: 7pt; }
    .stale-flag strong { color: #000 !important; }
    .checklist-group { border-top-color: #ccc; break-inside: avoid; padding: 4pt 0; }
    .checklist-group:first-of-type { padding-top: 2pt; }
    .group-title { font-size: 9pt; margin-bottom: 1pt; }
    .group-title, .group-note { color: #000; }
    .group-note { font-size: 6.5pt; }
    /* The badge marks an item as conditional. That matters more on paper than on screen,
       since a printed checklist is what someone carries to the interview, so it prints as
       black ink on a black hairline rather than being dropped. */
    .badge { color: #000 !important; border-color: #000 !important; font-size: 6.5pt; padding: 1px 4px; }
    .item-row { align-items: center; break-inside: avoid; padding: 2pt 0; gap: 6pt; border-bottom: none; margin: 0; }
    .item-copy { gap: 0; }
    .item-row .check {
      width: 12pt; height: 12pt; margin-top: 0; border: 1.2pt solid #000;
      background: transparent !important;
    }
    .item-row input:checked ~ .check { background: transparent !important; border-color: #000 !important; }
    .item-row input:checked ~ .check .check-path { stroke-dashoffset: 12 !important; }
    .item-row .item-label { color: #000 !important; text-decoration: none !important; font-size: 9pt; line-height: 1.25; }
    .item-row .item-hint { display: none !important; }
    .scope-note { margin-top: 5pt; padding-top: 4pt; font-size: 7pt; }
    /* k1 only: the picker's panels are hidden on screen and only the active one prints. Harmless
       on a checklist that has no panels, since neither selector matches anything there. */
    .post-panel { display: block !important; }
    .post-panel:not(.active) { display: none !important; }
    /* !important rather than a selector list. At (0,0,1) this rule was losing to
       .source-line a and .post-source a at (0,2,0), and to style.css's .legal p a at
       (0,2,1), all of which set var(--accent), so every link on the printed sheet had
       been rendering accent red and the intent stated here had never once taken effect.
       A selector list would need extending every time a component adds a link.
       Found 08/17/2026 by rendering the live page through printToPDF and looking at it. */
    a { color: #000 !important; text-decoration: none !important; }
  }

  /* Reduced motion removes the animation, not the behavior. This block used to also force
     .toolbar-pinned-top back to the header offset, which defeated the class entirely: that class
     is added by header-scroll.js when the mobile header hides, and its whole job is top:0 so the
     toolbar fills the space the header just vacated. Overriding it meant a reduced-motion user on
     a phone got a 77px empty band under the toolbar whenever the header hid. Killing the
     transitions is the correct and sufficient accommodation. */
  @media (prefers-reduced-motion: reduce) {
    .checklist-toolbar { transition: none !important; }
    .checklist-toolbar::before { transition: none !important; }
    .faq-caret { transition: none !important; }
    .faq-item > summary h3 { transition: none !important; }
  }
