/* air.ten7.com — TEN7 Brand Guidelines 2021, matching care.ten7.com.
   Same palette, same three-font stack, same card-on-khaki layout. */

:root{
  /* Brand palette */
  --t7-dark-purple:#1D0446;
  --t7-electric:#5F2FE1;
  --t7-electric-2:#6330F4;
  --t7-medium:#270066;
  --t7-coral:#FB9D61;
  --t7-paper:#FBF7F3;
  --t7-lavender:#7F6B97;
  --t7-muted:#635579;          /* darkened dusty-lavender; AA on white, paper, lilac, khaki */
  --t7-lilac:#ECE6FF;
  --t7-mimosa:#FFE2CF;
  --t7-khaki:#F4EEE9;
  --t7-warm-gray:#CEC8C3;

  /* Brand fonts first, then the Google alternates this site loads, then system. */
  --t7-sans:"Founders Grotesk","Work Sans",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --t7-serif:"Tiempos Text","Source Serif Pro",Georgia,"Times New Roman",serif;
  --t7-mono:"Replica Mono","Roboto Mono",ui-monospace,"SF Mono",Menlo,monospace;
  /* Labels and eyebrows only — never body copy. Falls back to the sans stack
     rather than to a system default, so a page that hasn't loaded Rubik yet
     still gets the right weight and tracking from Founders/Work Sans. */
  --t7-label:"Replica LL","Rubik","Work Sans",sans-serif;

  /* Readability pass (1B). The palette above already carries every colour the
     handoff names, under this repo's own names, so nothing is duplicated here —
     only the type scale, spacing grid and rail width it adds.

     Sizes are rem so a reader's own browser text-size setting scales the site;
     `html` stays at 100% for the same reason. The px values in the comments are
     what each step resolves to at a default root. */
  --t7-step--1:0.9375rem;   /* 15px — metadata, contents items */
  --t7-step-0:1.1875rem;    /* 19px — body prose */
  --t7-step-1:1.125rem;     /* 18px — test question */
  --t7-step-2:1.75rem;      /* 28px — h2 */
  --t7-step-3:2.5rem;       /* 40px — h1 */

  --t7-space-1:0.5rem;  --t7-space-2:1rem;    --t7-space-3:1.375rem;
  --t7-space-4:2rem;    --t7-space-5:2.75rem; --t7-space-6:3.5rem;

  --t7-toc-width:232px;

  /* Squared geometry: 0 everywhere except the outer page card. See
     docs/readiness-design-system.md. Deliberately *not* the handoff's 3/6/8px
     radii — this site was squared off on purpose and the design-system doc
     says so. */
  --t7-radius:0;
  --t7-radius-shell:0;
  /* Kept as a token so nothing that still names it breaks, but it is no
     longer a shadow: the shell is a drawn line now, not a lifted plane. */
  --t7-shadow:none;

  /* The traffic light. The brand has no green, so one is introduced that sits with
     dark purple; amber borrows coral and mimosa; red uses the brand's error berry.
     Used on the dashboard and wherever this site still shows a four-way status
     (pass/warn/fail/pending) rather than the three-band check pattern below. */
  --air-good:#1B6F52;      --air-good-bg:#E7F3ED;  --air-good-line:#B6DCC9;
  /* Darkened from #A2560F, which read 4.40 on mimosa — the one ground it is
     most often set against — and so missed AA by a tenth. This clears 4.96
     there and 5.74 on paper, and is indistinguishable at a glance. */
  --air-warn:#95500E;      --air-warn-bg:var(--t7-mimosa); --air-warn-line:var(--t7-coral);
  --air-bad:#B00050;       --air-bad-bg:#FCE7EF;   --air-bad-line:#F0A9C6;

  /* --- The check pattern: three bands, not five colours ---
     A pass is deliberately unfilled — no green, nothing to do gets no ink — so
     there is no "pass fill" token to match problem/needs-work's. Every name
     here points at a brand token already defined above; nothing here is a new
     colour, only a new name for when an old one means "this row's band." */
  --status-problem-fill:    var(--t7-coral);
  --status-problem-surface: var(--t7-mimosa);
  --status-needs-surface:   var(--t7-mimosa);
  --status-needs-border:    var(--t7-coral);
  --status-pass-surface:    var(--t7-lilac);
  --status-pass-mark:       var(--t7-electric);
  --status-ink:             var(--t7-dark-purple);   /* text on coral or mimosa: always this, never white */

  /* --- Direction, not band: did this go up or down? ---
     The check pattern above answers "what band is this in", and its three
     surfaces are the answer. These answer a different question — a check that
     went from failing to partial is an improvement, and colouring it by where
     it landed would say the opposite — so they are a second set rather than a
     reuse of the first. The brand has no green and no red, so both are
     introduced here, once, in oklch: the pairs are picked for contrast on the
     ground each is used against, and `-on-dark` exists because the light-
     background pair falls below AA on the domain page's purple hero.

     Never the only signal. Every use is paired with a glyph and a word. */
  --status-pass:         oklch(0.48 0.12 155);   /* text, and the up glyph on paper */
  --status-pass-bar:     oklch(0.55 0.12 155);   /* the 4px row rail */
  --status-pass-bg:      oklch(0.94 0.04 155);   /* PASSING chip */
  --status-pass-ink:     oklch(0.40 0.10 155);
  --status-pass-on-dark: oklch(0.82 0.15 155);
  --status-fail:         oklch(0.50 0.18 25);
  --status-fail-bar:     oklch(0.55 0.18 25);
  --status-fail-bg:      oklch(0.94 0.035 25);
  --status-fail-ink:     oklch(0.42 0.16 25);
  --status-fail-on-dark: oklch(0.80 0.12 25);

  /* --- The expanded panel's evidence half --- */
  --evidence-bg:            var(--t7-dark-purple);
  --evidence-well:          var(--t7-medium);
  --evidence-ink:           var(--t7-warm-gray);      /* on dark only */
  --evidence-ink-strong:    #FFFFFF;
  --evidence-label:         var(--t7-mimosa);

  --rail-width: 6px;
  --bar-track:  var(--t7-lilac);
}

*,*::before,*::after{box-sizing:border-box}
/* 100%, never a px value: a reader who has set their browser's default text
   size to large gets a larger site, which is the whole point of the unit. */
html{font-size:100%;-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--t7-khaki);color:var(--t7-dark-purple);
  font-family:var(--t7-sans);font-size:1.0625rem;line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
a{color:var(--t7-electric)}
/* Every focusable element, one ring: 2px Electric Purple at 2px offset. The
   list is explicit rather than `*:focus-visible` so a details/summary and a
   bare [tabindex] are covered too — a single invisible tab stop is the whole
   failure this prevents. */
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,
textarea:focus-visible,summary:focus-visible,details:focus-visible,
[tabindex]:focus-visible{
  outline:2px solid var(--t7-electric);outline-offset:2px;border-radius:0}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* Skip link — the first focusable element on every page. Off-canvas rather
   than display:none, because a hidden element is not focusable and a skip link
   nobody can reach by keyboard is decoration. */
.skip-link{position:absolute;left:var(--t7-space-2);top:-3rem;z-index:100;
  padding:0.625rem var(--t7-space-2);min-height:44px;display:inline-flex;
  align-items:center;background:var(--t7-medium);color:var(--t7-paper);
  font-family:var(--t7-label);font-weight:700;font-size:0.875rem;
  text-decoration:none}
.skip-link:focus{top:var(--t7-space-2)}

/* Nothing on this site needs animation to be understood, so a reader who has
   asked for less gets none of it — including the smooth scroll the contents
   rail would otherwise trigger. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;
    animation-iteration-count:1 !important;transition-duration:.01ms !important;
    scroll-behavior:auto !important}
  html{scroll-behavior:auto}
}
@media (prefers-reduced-motion:no-preference){
  html{scroll-behavior:smooth}
}

/* Sans, not the serif this site used before. The 1B handoff specifies Work
   Sans for H1/H2/H3 and its mockup shows it throughout; the serif is still the
   brand's display face and is still loaded, so reverting is this one rule.

   H2 carries far more space above it than below, which is what makes a heading
   read as belonging to the text under it rather than floating between two
   blocks — finding 03 in the audit. */
h1,h2,h3,h4{font-family:var(--t7-sans);font-weight:600;letter-spacing:-.01em}
h1,.page-title{font-size:var(--t7-step-3);line-height:1.12;color:var(--t7-electric)}
/* Below ~430px a 40px headline starts breaking long words; this is the only
   place the scale flexes, and it flexes down, never up. */
@media (max-width:480px){h1,.page-title{font-size:2rem}}
h2{font-size:var(--t7-step-2);line-height:1.2;color:var(--t7-dark-purple);
  margin:var(--t7-space-5) 0 var(--t7-space-2)}
h2:first-child{margin-top:0}
h3{font-size:1.375rem;line-height:1.3;color:var(--t7-dark-purple);
  margin:var(--t7-space-4) 0 var(--t7-space-1)}

/* The card, exactly as care.ten7.com sets it. */
.card{
  position:relative;max-width:760px;margin:4vh auto;padding:26px 22px 46px;
  background:var(--t7-paper);border-radius:var(--t7-radius-shell);
  border:1px solid rgba(29,4,70,.12);
  overflow:clip;
}
.card--wide{max-width:1080px}

/* Below this, the viewport is too narrow to show the shadow's spread on both
   sides — cropped rather than gone. Drop it outright and match the body to the
   card, so the edge disappears instead of looking clipped. */
@media (max-width:820px){
  body{background:var(--t7-paper)}
  .card{border-left:0;border-right:0}
  .card > .topbar{margin-left:-22px;margin-right:-22px}
}
@media (max-width:1140px){
  body:has(.card--wide){background:var(--t7-paper)}
  .card--wide{border-left:0;border-right:0}
}

/* ------------------------------------------------------------------- topbar */
.topbar{display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin-bottom:26px}
/* The header, everywhere the report already draws it: paper ground, a line
   under it, running the full width of the shell rather than stopping inside
   its padding. The negative margins take it back out to the card's edges —
   `.card` is `overflow:clip`, so it meets them rather than spilling past. The
   report's own header does this through its band and needs none of it. */
.card > .topbar{margin:-26px -22px 26px;padding:18px 22px;
  background:var(--t7-paper);border-bottom:1px solid var(--t7-warm-gray)}
/* Where the page's own header follows immediately, the two are one block and
   the gap between them is a seam rather than spacing. */
.card > .topbar:has(+ .qr-head){margin-bottom:0}
.card > .topbar:has(+ .dv-hero){margin-bottom:0}
.logo-link{display:inline-flex;align-items:center;min-height:44px;
  text-decoration:none}
.logo-link:focus-visible{outline:2px solid var(--t7-electric);outline-offset:2px;
  border-radius:0}

/* ------------------------------------------------- the Readiness Index mark */
/* Work Sans named outright rather than var(--t7-sans), which leads with
   Founders Grotesk. The mark's -.012em tracking is specified against Work Sans;
   Founders wants 0, and CSS cannot ask which one actually loaded. Pinning it
   means everyone sees the same mark instead of a lucky few seeing a better one
   with the wrong tracking. */
.sitemark{display:inline-flex;align-items:center;gap:12px}
.sitemark__glyph{width:34px;height:34px;flex:0 0 auto;display:block}
.sitemark__type{font-family:"Work Sans",system-ui,-apple-system,"Segoe UI",Roboto,
  sans-serif;font-size:21px;line-height:1;letter-spacing:-.012em;white-space:nowrap}
.sitemark__name{font-weight:700;color:var(--t7-dark-purple)}
.sitemark__index{font-weight:700;color:var(--t7-electric)}
/* Hover moves one word and nothing else. The glyph never changes, and there is
   no lift or scale — this is a mark, not a button. */
.logo-link:hover .sitemark__index{color:var(--t7-electric-2)}

/* The large lockup: covers, OG images, report headers. */
.sitemark--lg{gap:20px}
.sitemark--lg .sitemark__glyph{width:64px;height:64px}
.sitemark--lg .sitemark__type{font-size:42px;letter-spacing:-.02em}

/* On Medium #270066 or Dark Purple #1D0446. The glyph swaps file, not fill —
   see readinessindex-logo-on-dark.svg — and the whole wordmark goes paper white,
   matching the plate's own paper background rather than splitting into two
   tones the way the on-light mark does. */
.sitemark--on-dark .sitemark__name,
.sitemark--on-dark .sitemark__index{color:var(--t7-paper)}
.logo-link:hover .sitemark--on-dark .sitemark__index{color:#fff}
.logo-link:has(.sitemark--on-dark):focus-visible{outline-color:var(--t7-mimosa)}

/* Below the nav breakpoint the type drops and the glyph stands alone. The
   aria-label lives on the link, so the name survives the words disappearing. */
@media (max-width:560px){
  .sitemark__type{display:none}
}
/* `.topbar nav` used to live here, and the only <nav> inside a topbar is the
   site nav — so it was a lower-specificity duplicate of `.sitenav` that beat
   it anyway. (0,1,1) against (0,1,0): the gap, the tracking and the typeface
   the rule below asks for were all being overridden by a rule that wanted the
   same element. The nav has been rendering in Replica Mono while a rule two
   dozen lines down asked for Replica. Deleted rather than out-specified — the
   fix for two rules fighting over one element is one rule. */

/* The site nav reads as navigation rather than as small print: the brand's own
   deep purple, bold, and tracked in rather than out. Two classes deliberately:
   a lone `.sitenav` is (0,1,0) and loses to anything with an element in it,
   which is the specificity trap the account menu hit; `.topbar .sitenav` is
   (0,2,0) and wins on class count. */
/* 44px tall targets. The text size does not change — the box around it grows,
   which is what the rule is actually about. */
.topbar .sitenav a{display:inline-flex;align-items:center;min-height:44px;
  color:var(--t7-dark-purple);font-weight:700;letter-spacing:.04em;
  text-decoration:none}
.topbar .sitenav a:hover{color:var(--t7-electric);text-decoration:underline}
/* "Where I am" is marked by the rule under it rather than by a shade: the
   deep purple above leaves no room for a darker one that anybody would
   actually see, and an underline is a difference rather than a nuance. */
.topbar .sitenav a.is-current{color:var(--t7-dark-purple);text-decoration:underline;
  text-underline-offset:4px}

.sitenav{display:flex;align-items:center;gap:.975rem;font-family:var(--t7-label);
  font-size:11px;font-weight:500;text-transform:uppercase;letter-spacing:.06em}

/* --- the nav is a row on a wide screen and a panel on a narrow one ---
   One list, two layouts. Wide: the <details> is transparent — the summary is
   gone and the nav shows whatever the disclosure state happens to be, because
   `display` on the child overrides the UA's rule for a closed <details>.
   Narrow: five destinations will not fit on a line and wrapping them makes
   three ragged ones, so they go behind a hamburger. */
/* flex, not the <details> default of block: as a flex item of .topbar a block
   details collapsed to zero width and pushed every link off the right edge,
   each one wrapping inside its own box. */
.sitenav-menu{position:relative;display:flex;align-items:center;flex:0 0 auto}
.sitenav-menu > summary{display:none}
.sitenav-menu > .sitenav{display:flex}
.sitenav-menu > summary::-webkit-details-marker{display:none}
/* A closed <details> does not merely hide its children any more. Current Chrome
   wraps them in ::details-content and gives that content-visibility:hidden, so
   the nav measured zero wide and every link sat outside the viewport, wrapping
   inside its own box. Overriding the child's `display` — which was enough when
   the UA rule was display:none on the children themselves — does nothing to a
   collapsed wrapper. Browsers without the pseudo-element ignore this block and
   are already handled by the rule above. */
@media (min-width:821px){
  .sitenav-menu::details-content{display:contents;content-visibility:visible}
}

@media (max-width:820px){
  .sitenav-menu > summary{display:inline-flex;align-items:center;gap:.5rem;
    cursor:pointer;list-style:none;padding:.45rem .7rem;border-radius:0;
    font-family:var(--t7-mono);font-size:11px;text-transform:uppercase;
    letter-spacing:.12em;color:var(--t7-muted);
    border:1px solid var(--t7-warm-gray);background:#fff}
  .sitenav-menu > summary:hover{color:var(--t7-electric);
    border-color:var(--t7-electric)}
  .sitenav-menu > summary:focus-visible{outline:2px solid var(--t7-electric);
    outline-offset:2px}
  .sitenav-menu:not([open]) > .sitenav{display:none}

  /* The panel: anchored to the right edge under the button, above everything,
     and wide enough that no destination wraps inside it either. */
  .sitenav-menu[open] > .sitenav{position:absolute;right:0;top:calc(100% + 8px);
    z-index:40;flex-direction:column;align-items:stretch;gap:0;min-width:13rem;
    background:#fff;border:1px solid var(--t7-warm-gray);border-radius:0;
    padding:.35rem;box-shadow:6px 6px 0 rgba(29,4,70,.14)}
  .sitenav-menu[open] > .sitenav > a{padding:.6rem .7rem;border-radius:0;
    opacity:1;color:var(--t7-dark-purple)}
  .sitenav-menu[open] > .sitenav > a:hover{background:var(--t7-lilac)}
  .sitenav-menu[open] > .sitenav > a.is-current{background:var(--t7-lilac);
    color:var(--t7-electric)}
}

.sitenav-bars{display:inline-grid;gap:3px;width:14px}
.sitenav-bars span{display:block;height:2px;border-radius:0;
  background:currentColor}
.sitenav-menu[open] .sitenav-toggle__word::after{content:"";}
.sitenav__signin{border:1px solid var(--t7-warm-gray);padding:.4rem .9rem !important}
.sitenav__signin:hover{border-color:var(--t7-electric)}
.sitenav a{display:inline-flex;align-items:center;gap:.45rem;color:var(--t7-muted);
  text-decoration:none;opacity:.55;transition:opacity .15s,color .15s}
.sitenav a:hover{opacity:.9;color:var(--t7-electric);text-decoration:none}
.sitenav a.is-current{color:var(--t7-dark-purple);opacity:1;font-weight:600}

.eyebrow{font-family:var(--t7-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:12px;color:var(--t7-muted);margin:0 0 14px;font-weight:500}

/* ------------------------------------------------------------------ landing */
.tagline{font-family:var(--t7-serif);font-style:italic;font-size:1.2rem;
  color:var(--t7-muted);margin:0 0 2.2rem}
/* Homepage side padding: Figma shows 49px each side inside the 1080px card,
   roughly double the global 22px. The topbar is the one exception — its visual
   inset is already correct at ~22px in the design — so compensate by matching
   its bleed to the wider padding so it still reaches the card's own edge. */
body[data-page-kind="home"] .card--wide{padding-left:49px;padding-right:49px}
body[data-page-kind="home"] .card--wide > .topbar{margin-left:-49px;margin-right:-49px}
/* --- Home hero: one question, then the box, on one axis. ---
   It was a two-column grid with the form in a bordered card beside the
   headline, which put a second thing on the same line as the only thing to do
   and gave the box half a page to be prominent in. Centered on one column
   instead, so the eye goes straight down the middle from the question to the
   field to the button. */
.home-hero{padding:34px 0 4px;margin:0 0 48px;text-align:center}
.home-hero h1{margin:0;font-size:clamp(36px,6.5vw,64px);line-height:1.02;
  letter-spacing:-.02em;text-wrap:balance}
.home-hero__lede{margin:14px auto 0;font-size:19px;line-height:1.55;
  max-width:44ch;color:var(--t7-muted)}
/* Stacked, which is what plain `.air-form` already does: the button sits
   under the box, where the eye is after typing. Only the sizing is set here,
   with two classes so it beats the one-class-one-element rules in `.air-form`
   below rather than arguing with them. */
.home-hero__form{margin:28px auto 0;max-width:620px;text-align:left}
.home-hero__form input[type=text]{font-size:19px;padding:16px 18px;
  border:2px solid var(--t7-dark-purple)}
.home-hero__form input:focus-visible{outline:3px solid var(--t7-electric);
  outline-offset:2px}
.home-hero__form .btn{padding-block:15px;font-size:17px}


/* Stacked, not side by side: the box is the whole width of the thought, and the
   button sits under it where the eye already is after typing. */
.air-form{display:flex;flex-direction:column;gap:10px}
.air-form input[type=text]{
  width:100%;min-width:0;font:inherit;font-size:17px;line-height:1.2;
  padding:14px 16px;border:1px solid var(--t7-warm-gray);border-radius:0;
  background:var(--t7-paper);color:var(--t7-dark-purple)}
.air-form input::placeholder{color:var(--t7-muted)}
.air-form input:focus{outline:none;border-color:var(--t7-electric)}
.air-form input[aria-invalid=true]{border-color:var(--air-bad)}
.air-form .btn{width:100%}
/* Side by side on a wide page, the input growing to fill the row — the
   opposite call from the home hero's stacked form, for a box that's the
   width of the whole page rather than one narrow card. */
.air-form--inline{flex-direction:row;align-items:stretch;gap:12px}
.air-form--inline input[type=text]{flex:1 1 auto}
.air-form--inline .btn{width:auto}
@media (max-width:640px){.air-form--inline{flex-direction:column}
  .air-form--inline .btn{width:100%}}

/* --- The framework, as cards. ---
   A plain reference stat, not the check pattern: nothing here was scanned,
   only the Index's own fixed weights. It was a single stacked list of nine
   rows, which gave dimension 1 and the unscored families — the free scan and the
   unscored tier — exactly the same weight as the seven in between.

   Three shapes now, and the shape is the argument: Primary Indicators across
   the top because it is also the scan somebody can run in twenty seconds, the
   seven scored dimensions in a grid because they are peers, and the leading
   tier beneath on its own because it is measured beside the hundred rather
   than inside it. */
.home-dims__head{margin:6px 0 0;font-family:var(--t7-serif);
  font-size:clamp(24px,4vw,34px);line-height:1.15}
.home-dim{display:flex;gap:14px;align-items:flex-start;padding:18px 20px;
  background:#fff;border:1px solid var(--t7-warm-gray);text-decoration:none;
  color:inherit}
.home-dim:hover{border-color:var(--t7-electric)}
.home-dim__num{flex:0 0 auto;font-family:var(--t7-mono);font-size:12px;
  color:var(--t7-muted);padding-top:3px}
.home-dim__body{display:flex;flex-direction:column;gap:4px;min-width:0;flex:1 1 auto}
.home-dim__title{font-weight:600;font-size:17px;color:var(--t7-dark-purple)}
.home-dim__blurb{font-size:15px;line-height:1.45;color:var(--t7-muted)}
.home-dim__stat{flex:0 0 auto;font-family:var(--t7-mono);font-size:13px;
  font-weight:700;text-transform:uppercase;letter-spacing:.06em;
  color:var(--t7-dark-purple);padding-top:3px;white-space:nowrap}
/* The one that is also the free scan, so it carries the lilac the rest do not
   and sits full width above them. The 6px top border is the accent the Figma
   design specifies to set this card visually apart from the other six; the
   1px base border still runs on the remaining three sides via the shared rule. */
.home-dim--primary{background:var(--t7-lilac);border-color:var(--t7-dark-purple);
  border-top-width:6px;margin:0 0 14px}
.home-dim--primary .home-dim__blurb{color:var(--t7-dark-purple)}
.home-dims{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;
  margin:0 0 14px}
.home-leading{display:flex;gap:14px;align-items:flex-start;padding:18px 20px;
  background:var(--t7-paper);border:1px dashed var(--t7-warm-gray);
  text-decoration:none;color:inherit;margin:0 0 20px}
.home-leading:hover{border-color:var(--t7-electric)}
.home-leading__mark{flex:0 0 auto;color:var(--t7-muted);padding-top:2px}
.home-dims__foot{margin:0 0 20px;font-family:var(--t7-mono);font-size:12px}
@media (max-width:700px){
  .home-dims{grid-template-columns:1fr}
  /* The point tally wraps under the name rather than squeezing it to three
     words a line. */
  .home-dim,.home-leading{flex-wrap:wrap}
  .home-dim__stat{padding-top:0;width:100%}
}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;
  font:inherit;font-weight:600;line-height:1;border-radius:0;text-decoration:none;
  padding:15px 26px 11px;   /* top-heavy: optically centers against the descender space */
  cursor:pointer;border:2px solid transparent;
  transition:transform .08s,background .15s,border-color .15s}
.btn:active{transform:scale(.97)}
.btn-primary{background:var(--t7-coral);color:var(--t7-dark-purple)}
.btn-primary:hover{background:#ffae78}
.btn-outline{background:transparent;color:var(--t7-electric);border-color:var(--t7-electric)}
/* The two variants the check-pattern redesign adds. primary/outline predate it
   and keep their names and their (different) meanings — outline is an
   electric-purple secondary action, quiet is a lower-emphasis neutral one; they
   are not the same button with a different name. */
.btn-dark{background:var(--t7-medium);color:#fff}
.btn-dark:hover{background:#31007a}
.btn-quiet{background:var(--t7-paper);color:var(--t7-dark-purple);
  border-color:var(--t7-warm-gray)}
.btn-quiet:hover{background:#fff;border-color:var(--t7-dark-purple)}
.btn-outline:hover{background:var(--t7-lilac)}
.btn-ghost{background:transparent;color:var(--t7-electric);padding-left:6px;padding-right:6px}
.btn-ghost:hover{text-decoration:underline}
.air-form .btn{flex:0 0 auto;align-self:center}

.error{color:var(--air-bad);margin:1rem 0 0;font-weight:500;font-size:15px}

/* ------------------------------------------------------------------ site foot */
/* Every page, the dashboard included — the license line is the point of it, so
   it stays legible rather than shrinking to a copyright afterthought. */
.site-foot{max-width:760px;margin:2.4rem auto 4vh;padding:0 22px;text-align:center;
  color:var(--t7-muted);font-size:13px}
.site-foot-license{margin:0 auto;font-size:12px;line-height:1.35;max-width:56ch}
.site-foot-license a{color:var(--t7-electric);text-decoration:none}
.site-foot-license a:hover{text-decoration:underline}
/* A taller hit area without a taller footer. Vertical padding on an inline
   element grows the box you can click but does not touch the line box, so the
   three lines sit exactly where they always have — the separators, the
   spacing and the absence of underlines are all as they were. */
.site-foot-license a{padding-block:0.75rem}
/* Quieter than the license line above it: this answers "is this the build I
   just deployed", which nobody needs unless they are asking. The footer's own
   face, a size down — a monospaced build number reads as something to act on,
   and this is not. */
.site-foot-build{margin:.7rem auto 0;font-size:10px;line-height:1.35;
  color:var(--t7-muted);opacity:.75}

/* ------------------------------------------------------------------- thanks */
.thanks{padding:1rem 0 1rem}
.confetti{font-size:.85em;margin-left:.15em}
.thanks h1{font-size:clamp(28px,5.5vw,44px);line-height:1.1;margin:0 0 1rem}
.thanks .lede{font-size:18px;color:var(--t7-dark-purple);max-width:56ch;margin:0 0 2.4rem}
.thanks h2{font-family:var(--t7-mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:12px;color:var(--t7-muted);font-weight:500;margin:0 0 .8rem}
.thanks p{max-width:60ch}
.promise{background:var(--air-good-bg);border:1px solid var(--air-good-line);
  border-radius:var(--t7-radius);padding:20px 22px;margin-bottom:2.4rem}
.promise p{margin:0 0 .7rem;font-size:15.5px;color:var(--t7-dark-purple)}
.promise p:last-child{margin-bottom:0}
.who{border-top:1px solid var(--t7-warm-gray);padding-top:1.8rem}
.who p{margin:0 0 1rem;font-size:15.5px;color:var(--t7-muted)}
.who-cta{margin:1.4rem 0 0}
.back-to-result{margin:2.4rem 0 0;padding-top:1.4rem;
  border-top:1px solid var(--t7-warm-gray);font-size:13.5px;color:var(--t7-muted)}
.back-to-result a{font-family:var(--t7-mono);font-size:12.5px;word-break:break-all}

/* ------------------------------------------------------------------- result */
.result-head h1{font-size:clamp(24px,4.4vw,34px);margin:.2rem 0 .4rem;
  word-break:break-word}

/* --- QuickResult: the first contact scan's redesigned header, verdict,
   sign-in CTA and fixes list (design handoff: first-contact-scan-1a). Each
   block bleeds edge-to-edge inside .card's own padding, which is why every
   one cancels it with a matching negative margin. --- */
/* The same ground as the header above it. A second colour starting an inch
   below the nav read as the nav's own background bleeding down and stopping
   somewhere arbitrary; the whole top of the page is one block now, and the
   rule under the header is what separates them. */
.qr-head{margin:0 -22px;padding:36px 40px 32px;background:var(--t7-paper);
  border-bottom:1px solid var(--t7-warm-gray);display:flex;flex-direction:column;gap:26px}
.qr-head__meta{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;
  gap:4px;font-family:var(--t7-mono);font-size:11px;color:var(--t7-muted)}
.qr-head__meta .is-stale{color:var(--air-bad);font-weight:600}

.qr-scale{display:flex;flex-direction:column}
.qr-scale__markerrow{position:relative;height:30px}
.qr-scale__marker{position:absolute;transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:3px}
.qr-scale__pill{background:var(--t7-medium);color:#fff;font-size:12px;font-weight:600;
  padding:3px 8px;white-space:nowrap}
.qr-scale__stem{width:2px;height:8px;background:var(--t7-medium);display:block}
.qr-scale__track{display:flex;height:12px;border:1px solid var(--t7-dark-purple)}
.qr-scale__seg--earned{background:var(--t7-medium)}
.qr-scale__seg--reachable{background:var(--t7-lilac)}
.qr-scale__seg--unreachable{background:repeating-linear-gradient(135deg,
  var(--t7-paper) 0 5px, var(--t7-khaki) 5px 10px)}
.qr-scale__bands{display:flex;gap:2px;margin-top:4px}
.qr-scale__band{display:flex;flex-direction:column;border-top:3px solid var(--t7-warm-gray);
  padding-top:6px;min-width:0;overflow:hidden}
.qr-scale__bandname{display:block;font-family:var(--t7-label);font-size:12px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--t7-muted)}
.qr-scale__bandrange{font-family:var(--t7-mono);font-size:11px;color:var(--t7-muted)}
.qr-scale__band--active{border-top-color:var(--t7-coral)}
.qr-scale__band--active .qr-scale__bandname{color:var(--t7-dark-purple);font-weight:600}
.qr-scale__notewrap{display:flex;margin-top:10px}
.qr-scale__note{margin:0;border-left:1px dashed var(--t7-dark-purple);
  padding-left:10px;font-size:13px;color:var(--t7-dark-purple)}

.qr-verdict{margin:0 -22px;padding:32px 40px;display:flex;flex-direction:column;gap:10px;
  border-bottom:1px solid var(--t7-warm-gray)}
.qr-verdict__headline{margin:0;font-family:var(--t7-serif);font-size:clamp(22px,3.4vw,30px);
  line-height:1.15;font-weight:400}
.qr-verdict__body{margin:0;font-size:15px;line-height:1.55;max-width:64ch}

.qr-cta{margin:0 -22px;padding:32px 40px;background:var(--t7-lilac);
  border-bottom:1px solid var(--t7-warm-gray);display:flex;gap:36px;align-items:center}
.qr-cta__main{flex:1;display:flex;flex-direction:column;gap:8px;min-width:0}
.qr-cta__title{margin:0;font-size:22px;font-weight:600;letter-spacing:-.01em}
.qr-cta__bullets{margin:0;padding-left:18px;font-size:14px;line-height:1.7}
.qr-cta__aside{width:300px;flex:none;display:flex;flex-direction:column;gap:10px;
  align-items:stretch}
.qr-cta__btn{width:100%;font-size:22px;padding:25px 36px 19px}
.qr-cta__btn:hover{background:var(--t7-mimosa)}

.qr-fixes{margin:0 -22px;padding:32px 40px;display:flex;flex-direction:column;gap:14px}
.ds-quickfixes__head{display:flex;justify-content:space-between;align-items:baseline;gap:12px}
.ds-quickfixes__head .ds-eyebrow{margin:0}
.ds-quickfixes__table{border:1px solid var(--status-needs-border);border-left-width:4px}
.ds-quickfixes__clean{margin:0;font-size:15px;color:var(--t7-dark-purple)}
.ds-checkrow__pts--zero{background:var(--t7-khaki);border-color:var(--t7-khaki);
  color:var(--t7-muted)}

.ds-quickpasses{border:1px solid var(--t7-warm-gray);border-left:4px solid var(--t7-lilac)}
.ds-quickpasses__bar{display:flex;justify-content:space-between;align-items:center;
  gap:12px;padding:12px 20px;font-size:14px;cursor:pointer;list-style:none;
  background:var(--t7-lilac)}
.ds-quickpasses__bar::-webkit-details-marker{display:none}
.ds-quickpasses__toggle{font-family:var(--t7-mono);font-size:12px;font-weight:700;
  color:var(--t7-electric);white-space:nowrap}
.ds-quickpasses__toggle::before{content:"Show them"}
.ds-quickpasses[open] .ds-quickpasses__toggle::before{content:"Hide them"}
.ds-quickpasses__rows{border-top:1px solid var(--t7-warm-gray)}

.ds-heldbar{margin:0 0 12px;background:var(--t7-dark-purple);color:var(--t7-lilac);
  padding:14px 20px;display:flex;flex-wrap:wrap;justify-content:space-between;
  align-items:center;gap:12px;font-size:14px}
.ds-heldbar a{color:var(--t7-coral);white-space:nowrap}

@media (max-width:820px){
  .qr-head,.qr-verdict,.qr-cta,.qr-fixes{padding-left:22px;padding-right:22px}
  .qr-head .fs-identity__row{flex-direction:column;gap:14px}
  .qr-head .fs-identity__score{text-align:left}
  .qr-cta{flex-direction:column;align-items:stretch}
  .qr-cta__aside{width:auto}
  .qr-scale__bandrange{display:none}
}
@media (max-width:480px){
  .qr-scale__bandname{font-size:9.5px;letter-spacing:.03em}
}

.waiting{text-align:center;padding:3rem 0}
.waiting h2{margin:1.4rem 0 .5rem;font-size:1.5rem}
.waiting p{color:var(--t7-muted);margin:0 auto .6rem;max-width:28rem;font-size:15px}
.spinner{width:44px;height:44px;margin:0 auto;border:4px solid var(--t7-lilac);
  border-top-color:var(--t7-electric);border-radius:50%;animation:spin 1s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.spinner{animation:none}}

/* --- ProgressPanel — the full scan running under the score card while she
   reads. Non-blocking by construction: it only ever grows downward inside
   its own container, id="gate-section" — see result.js, which swaps this
   container's innerHTML in place on completion rather than reloading the
   page, so nothing above it can move. --- */
.ds-progresspanel{border:1px solid var(--t7-warm-gray);background:var(--t7-paper);
  padding:22px 24px;margin:0 0 28px;display:flex;flex-direction:column;gap:14px}
.ds-progresspanel__head{display:flex;flex-wrap:wrap;align-items:baseline;
  justify-content:space-between;gap:10px}
.ds-progresspanel__head h2{margin:0;font-family:var(--t7-serif);font-size:20px;
  color:var(--t7-dark-purple)}
.ds-progresspanel__bars{display:flex;flex-direction:column;gap:10px}
.ds-progresspanel__bar{display:flex;flex-direction:column;gap:5px}
.ds-progresspanel__bar .ds-sharebar{height:8px}
.ds-progresspanel__chips{display:flex;flex-wrap:wrap;gap:6px}
.ds-progresschip{font-family:var(--t7-mono);font-size:11.5px;padding:4px 9px;
  border:1px solid var(--t7-warm-gray);background:#fff;color:var(--t7-muted)}
.ds-progresschip--now{border-color:var(--t7-electric);color:var(--t7-electric);
  font-weight:700}
.ds-progresschip--done{background:var(--t7-lilac);border-color:var(--t7-lilac);
  color:var(--t7-dark-purple)}
@media (prefers-reduced-motion:no-preference){
  .ds-progresschip--now{animation:pulse 1.4s ease-in-out infinite}
}
@keyframes pulse{50%{opacity:.55}}
@media (prefers-reduced-motion:reduce){.spinner{animation-duration:3s}}
.small{font-size:13px}

.captured h2{font-family:var(--t7-mono);text-transform:uppercase;
  letter-spacing:.14em;font-size:12px;color:var(--t7-muted);font-weight:500;
  margin:0 0 14px}
.detail-panel .found{background:#fff;border:1px solid var(--t7-warm-gray);
  border-radius:0;padding:10px 12px;color:var(--t7-dark-purple)}
.detail-panel .evidence{font-family:var(--t7-mono);font-size:13px;
  color:var(--t7-muted);word-break:break-word}
/* --- the evidence under a finding --- */
/* Monospaced on purpose: these are measurements, and they should not read as
   more prose. The heading of each item is the thing measured, the facts are
   what was true of it. */
.evidence-block{margin-top:.7rem}
.evidence-head{font-family:var(--t7-mono);text-transform:uppercase;
  letter-spacing:.12em;font-size:10.5px;color:var(--t7-muted);font-weight:500;
  margin:0 0 .35rem}
.evidence-common{font-family:var(--t7-mono);font-size:12.5px;color:var(--t7-muted);
  margin:0 0 .4rem}
.evidence-list{margin:0;font-family:var(--t7-mono);font-size:12.5px;line-height:1.5}
.evidence-list dt{color:var(--t7-dark-purple);word-break:break-all;margin-top:.45rem}
.evidence-list dt:first-child{margin-top:0}
.evidence-list dt a{color:var(--t7-electric)}
.evidence-list dd{margin:.1rem 0 0;padding:0 0 0 .9rem;color:var(--t7-muted);
  border-left:2px solid var(--t7-warm-gray)}
.evidence-list .fact,.evidence-common .fact{display:block;word-break:break-word}
.evidence-list .fact .k,.evidence-common .fact .k{color:var(--t7-dark-purple);opacity:.62}
.evidence-list .fact .k::after,.evidence-common .fact .k::after{content:":\0020"}
.evidence-more{font-family:var(--t7-mono);font-size:11.5px;color:var(--t7-muted);
  margin:.5rem 0 0}
.stale-note{background:var(--air-warn-bg);border:1.5px solid var(--air-warn-line);
  border-radius:var(--t7-radius);padding:14px 18px;margin:1.4rem 0 0;
  font-size:15px;color:var(--t7-dark-purple)}
.stale-note strong{color:var(--air-warn)}

/* --------------------------------------------------------------- methodology */
/* The Index document itself. Long, dense, and meant to be read end to end or
   jumped into from an anchor, so it gets a measure and a table of contents rather
   than the full width of the card. Chrome only, restyled to the design system —
   the document it wraps still comes from docs/AI-READINESS-INDEX.md alone; see
   app.py::methodology_page. */
.doc-meta{display:flex;flex-wrap:wrap;gap:0;border:1px solid var(--t7-warm-gray);
  margin:10px 0 24px}
.doc-meta__cell{flex:1 1 200px;padding:14px 16px;background:#fff;
  border-right:1px solid var(--t7-warm-gray)}
.doc-meta__cell:last-child{border-right:0}
.doc-meta__cell .ds-monostat{display:block;margin-bottom:3px}
.doc-meta__cell div{font-family:var(--t7-mono);font-size:15px;color:var(--t7-dark-purple)}
.doc-layout{display:grid;grid-template-columns:15rem minmax(0,1fr);gap:2.6rem;
  align-items:start}
@media (max-width:900px){
  .doc-layout{grid-template-columns:1fr;gap:1.4rem}
  .doc-toc{position:static !important;max-height:none !important;border-bottom:1px solid var(--t7-warm-gray);padding-bottom:1rem}
}
.doc-toc{position:sticky;top:1.5rem;max-height:calc(100vh - 3rem);overflow:auto;
  font-size:13.5px;line-height:1.35}
.doc-toc .toc-head{font-family:var(--t7-label);font-size:10px;font-weight:700;
  text-transform:uppercase;letter-spacing:.1em;color:var(--t7-muted);margin:0 0 .7rem}
.doc-toc ol{list-style:none;margin:0 0 1.1rem;padding-left:14px;
  border-left:2px solid var(--t7-warm-gray)}
.doc-toc li{margin:0 0 .45rem}
.doc-toc li.lvl-1{margin-top:1rem;font-weight:600}
.doc-toc li.lvl-1:first-child{margin-top:0}
.doc-toc a{color:var(--t7-muted);text-decoration:none}
.doc-toc a:hover{color:var(--t7-electric);text-decoration:underline}

/* The measure is the container, not a column inside it. These pages sit in a
   1080px card that was holding a 74ch column with a third of itself empty —
   which reads as an unfinished layout rather than as a considered measure. */
/* Prose. 19px at 1.7, and the measure is the container — the handoff's
   line-length cap was dropped at the client's direction, so there is
   deliberately no `max-width` and no `ch` anywhere in this block. Do not add
   one back "just for the legal pages". */
.doc,.prose{max-width:none;font-size:var(--t7-step-0);line-height:1.7;
  color:var(--t7-dark-purple)}
.doc p,.prose p{margin:0 0 var(--t7-space-2)}
/* Colour alone is not a sufficient signal (WCAG 1.4.1), so every inline link in
   running text is underlined. Scoped to prose: a nav or a button is identifiable
   by its position and shape and does not need one. */
.doc a,.prose a{color:var(--t7-electric);text-decoration:underline;
  text-underline-offset:2px}
.doc a:hover,.prose a:hover{color:var(--t7-electric-2)}
.doc h1{font-size:clamp(26px,4.2vw,38px);line-height:1.12;margin:2.6rem 0 1rem}
.doc h1:first-child{margin-top:0}
/* No rule above the heading. A line drawn between every section reads as an
   <hr> between paragraphs, and a heading that is already bigger, heavier and
   preceded by a clear run of space is doing that job without one. */
.doc h2{margin:var(--t7-space-5) 0 var(--t7-space-2)}
.doc h3{font-family:var(--t7-sans);font-size:19px;font-weight:700;
  margin:2.1rem 0 .6rem;letter-spacing:0}
.doc h4{font-family:var(--t7-mono);font-size:12.5px;text-transform:uppercase;
  letter-spacing:.1em;color:var(--t7-muted);font-weight:500;margin:1.7rem 0 .5rem}
.doc p,.doc ul,.doc ol{margin:0 0 1rem}
.doc li{margin:0 0 .4rem}
.doc a{color:var(--t7-electric)}
.doc strong{font-weight:600}
.doc code{font-family:var(--t7-mono);font-size:.86em;background:var(--t7-khaki);
  border-radius:0;padding:1px 5px;word-break:break-word}
.doc pre{background:var(--t7-dark-purple);color:var(--t7-paper);border-radius:0;
  padding:16px 18px;overflow-x:auto;font-size:12.5px;line-height:1.55;margin:0 0 1.2rem}
.doc pre code{background:none;color:inherit;padding:0;font-size:inherit}
.doc blockquote{margin:0 0 1rem;padding-left:1rem;
  border-left:3px solid var(--t7-coral);color:var(--t7-muted)}
/* A rule in the source becomes the break it was standing in for. Removing it
   outright would join two sections that the author meant to separate. */
.doc hr{border:0;height:0;margin:2.6rem 0}
/* Wide tables scroll inside themselves rather than pushing the page sideways. */
.doc table{width:100%;border-collapse:collapse;font-size:15px;margin:0 0 1.2rem;
  table-layout:fixed}
.doc th,.doc td{text-align:left;padding:7px 12px 7px 0;
  border-bottom:1px solid var(--t7-warm-gray)}
.doc th{font-family:var(--t7-mono);font-size:10.5px;text-transform:uppercase;
  letter-spacing:.1em;color:var(--t7-muted);font-weight:500}
/* The grade bands table's own cells, recolored in place — see
   report/spec.py::_badge_grade_cells. Same five tones report/dials.py's
   GRADE_BANDS already names (b0 = Not ready ... b4 = Exemplary); Gated is a
   sixth, separate tone because the document itself calls it "a separate
   fact, not a grade". */
.grade-badge{display:inline-block;font-family:var(--t7-label);font-size:11px;
  font-weight:700;letter-spacing:.06em;text-transform:uppercase;padding:3px 9px}
.grade-badge--b0{background:var(--air-bad-bg);color:var(--air-bad)}
.grade-badge--b1{background:#FCE7EF;color:#B0004F}
.grade-badge--b2{background:var(--air-warn-bg);color:var(--air-warn)}
.grade-badge--b3{background:#E7F3ED;color:#2C7A5B}
.grade-badge--b4{background:var(--air-good-bg);color:var(--air-good)}
.grade-badge--gated{background:var(--t7-coral);color:var(--t7-dark-purple)}

/* ---------------------------------------------------------------- licensing */
/* The two loose paragraphs on the licence page. They were inline styles
   carrying their own 62ch cap and their own size, which is how they survived a
   change to every rule around them — a named class is the point. */
.page-lede{color:var(--t7-muted);max-width:none;margin:0 0 2.4rem;font-size:17px;
  line-height:1.6}
.page-foot{color:var(--t7-muted);max-width:none;font-size:15px;line-height:1.6}

.license-block{max-width:none;padding:0 0 2.2rem}
.license-block + .license-block{padding-top:.4rem}
.license-kind{font-family:var(--t7-mono);text-transform:uppercase;letter-spacing:.1em;
  font-size:11px;font-weight:600;margin:0 0 .5rem}
.license-open{color:var(--air-good)}
.license-closed{color:var(--t7-muted)}
.license-block h2{font-size:23px;margin:0 0 .8rem}
.license-block p{font-size:17px;color:var(--t7-muted);margin:0 0 .8rem;line-height:1.6}
.license-block strong{color:var(--t7-dark-purple)}
.license-links{font-size:15px}

/* ------------------------------------------------------------- all 51 checks */
.check-group{margin-bottom:2.2rem}
.check-id{font-family:var(--t7-mono);font-size:12px;color:var(--t7-muted);
  white-space:nowrap}
.q-cell{white-space:normal !important}
.detail-panel .cite{font-size:13px;color:var(--t7-muted);margin:.5rem 0 0}
.badge-quick{display:inline-block;font-family:var(--t7-mono);font-size:10px;
  font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--air-warn);
  background:var(--t7-mimosa);border-radius:0;padding:2px 9px 1px;white-space:nowrap}

/* The dark block is for the form: it is the one thing on the page we want somebody
   to fill in, and the contrast earns it. Once they have, the block holds their
   report instead — links and prose, which read better on paper than in reverse.
   Medium purple, not dark-purple, so the inputs (dark-purple on electric) still
   read as a step down rather than blending into the same field. */
.capture{background:var(--t7-medium);color:var(--t7-paper);
  border-radius:var(--t7-radius);padding:34px 36px 38px;
  display:flex;flex-direction:column;gap:22px}
.capture__intro{display:flex;flex-direction:column;gap:8px}
.capture__lede{margin:0;font-family:var(--t7-serif);font-weight:400;
  font-size:clamp(20px,3vw,26px);line-height:1.25;color:#fff;max-width:680px}

.captured{background:var(--t7-paper);color:var(--t7-dark-purple);
  border:1.5px solid var(--t7-warm-gray);border-radius:var(--t7-radius);
  padding:26px 24px}
.captured h2{color:var(--t7-muted)}
.captured p{color:var(--t7-muted);font-size:15.5px;margin:0;max-width:52ch}
.captured strong{color:var(--t7-dark-purple)}
.report-list{list-style:none;margin:0 0 1rem;padding:0}
.report-list li{margin:0 0 .5rem;display:flex;flex-wrap:wrap;gap:.6rem;
  align-items:baseline}
.report-list a{color:var(--t7-electric);font-weight:600}
.report-list .rscore{font-family:var(--t7-mono);font-size:13px;
  color:var(--t7-dark-purple);font-weight:600}
.lead__fields{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:18px 22px;margin-bottom:1.4rem}
.lead .row{display:flex;flex-direction:column;gap:7px}
.lead label{display:block;font-family:var(--t7-label);text-transform:uppercase;
  letter-spacing:.1em;font-size:10px;font-weight:700;color:var(--t7-lilac)}
.lead .opt{color:var(--t7-muted);text-transform:none;letter-spacing:0;font-weight:400}
.lead input{width:100%;box-sizing:border-box;font:inherit;font-size:16px;
  padding:13px 15px;border:1px solid var(--t7-electric);border-radius:0;
  background:var(--t7-dark-purple);color:#fff}
.lead input::placeholder{color:var(--t7-muted)}
.lead input:focus{outline:none;border-color:var(--t7-coral)}
.lead .hint{color:var(--t7-lilac);font-size:14px;line-height:1.6;margin:.4rem 0 0;
  max-width:52ch}
.lead .hint--fine{color:var(--evidence-ink);font-size:13px}
.lead .error{color:var(--t7-coral)}
.lead .hint a{color:var(--evidence-label);font-weight:600;text-decoration:underline}
.lead__cta{display:flex;flex-wrap:wrap;align-items:center;gap:20px;margin-top:6px}
.lead__cta .hint{margin:0;max-width:420px}
.failed h2{margin-top:0;font-size:1.4rem}

/* ------------------------------------------------------------- prose pages */
/* Named for the embed documentation once, which is gone; these rules were
   never its own. They dress every `.doc` page — the terms, the privacy policy,
   the crawler policy, the methodology.

   This block is later in the file than the canonical `.doc` rules above and at
   the same specificity, so anything declared twice is settled here rather than
   there. Two that were: an `h2` size that undid the heading scale, and a `p`
   capped at 56ch — which is why the prose pages read as a half-width column
   inside a 1080px card however the rule above was set. */
.doc pre{background:var(--t7-dark-purple);color:#e7ddff;padding:16px 18px;
  border-radius:0;overflow-x:auto;font-family:var(--t7-mono);font-size:13.5px;
  line-height:1.6}
.doc code{font-family:var(--t7-mono);font-size:.92em}
.doc p code{background:var(--t7-lilac);padding:.1em .4em;border-radius:0;
  color:var(--t7-medium)}
.doc .hint{color:var(--t7-muted);font-size:14px}

/* ---------------------------------------------------------------- dashboard */
.dash-wrap{max-width:1080px;margin:0 auto;padding:0}

/* --- the signed-in account menu (partials/ds_accountmenu.html) --- */
.acctmenu{position:relative}
.acctmenu__trigger{cursor:pointer;font-family:var(--t7-label);font-size:11px;
  font-weight:500;text-transform:uppercase;letter-spacing:.1em;color:var(--t7-dark-purple);
  padding:.45rem .8rem;border:1px solid var(--t7-warm-gray);border-radius:0;background:none;
  display:inline-flex;align-items:center;gap:.45rem;max-width:100%}
.acctmenu__label{max-width:190px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  min-width:0}
/* text-overflow only ever fires if the box is allowed to get smaller than its
   content. Inside a flex row both the menu and its button default to
   min-width:auto, which is the content's width — so a long address pushed the
   nav wider instead of ellipsing, which is the bug this fixes. */
.acctmenu{min-width:0}
.acctmenu__trigger{min-width:0;max-width:100%}
.acctmenu__caret{font-size:.8em;color:var(--t7-electric);transition:transform .12s ease}
.acctmenu__trigger:hover{border-color:var(--t7-electric)}
.acctmenu.is-open .acctmenu__trigger{border-color:var(--t7-electric);background:var(--t7-lilac)}
.acctmenu.is-open .acctmenu__caret{transform:rotate(180deg)}
.acctmenu__panel{position:absolute;right:0;top:calc(100% + .4rem);z-index:20;width:272px;
  background:var(--t7-paper);border:1px solid var(--t7-dark-purple);border-radius:0;
  box-shadow:6px 6px 0 rgba(29,4,70,.14);padding:.3rem;
  display:flex;flex-direction:column}
.acctmenu__panel[hidden]{display:none}
/* Two classes, not one: this panel sits inside `.topbar nav` (two type
   selectors plus a class, specificity 0,1,2), which beats a single class
   outright regardless of source order — `.acctmenu__panel .acctmenu__item`
   is 0,2,0 and wins on class count alone. */
.acctmenu__panel .acctmenu__item{display:block;width:100%;text-align:left;
  font-family:var(--t7-sans);font-size:15px;font-weight:600;padding:11px .7rem;border:0;
  border-radius:0;background:none;color:var(--t7-dark-purple);text-decoration:none;
  cursor:pointer;text-transform:none;letter-spacing:normal}
.acctmenu__panel .acctmenu__item:hover,.acctmenu__panel .acctmenu__item:focus-visible{
  background:var(--t7-lilac);color:var(--t7-electric)}
.acctmenu__panel .acctmenu__item:focus-visible{
  outline:2px solid var(--t7-electric);outline-offset:2px}
/* The rule moved off the form and onto the group around it, so Superuser
   Control sits below the line with Sign out rather than above it with the
   things somebody opens in the course of their work. Left on the form, the
   two would have had a rule between them. */
.acctmenu__panel form{margin:0}
.acctmenu__panel .acctmenu__foot{display:flex;flex-direction:column;
  border-top:1px solid var(--t7-warm-gray);margin-top:.3rem;padding-top:.3rem}
.acctmenu__panel .acctmenu__signout{color:var(--t7-electric)}
@media (max-width:900px){
  .acctmenu__panel{position:fixed;left:0;right:0;width:auto;border-left:0;border-right:0;
    box-shadow:none;border-bottom:1px solid var(--t7-dark-purple)}
}

.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(8.5rem,1fr));
  gap:12px;margin-bottom:2.2rem}
.tile{background:#fff;border:2px solid var(--t7-warm-gray);
  border-radius:var(--t7-radius);padding:16px}
.tile:first-child{background:var(--t7-dark-purple);border-color:var(--t7-dark-purple);
  color:#fff}
.tile .n{font-weight:700;font-size:clamp(22px,4vw,30px);line-height:1}
.tile .l{font-family:var(--t7-mono);text-transform:uppercase;letter-spacing:.1em;
  font-size:11px;color:var(--t7-muted);margin-top:6px}
.tile:first-child .l{color:var(--t7-coral)}
.metrics.tiles{margin-bottom:2.2rem;grid-template-columns:repeat(5,minmax(0,1fr));
  gap:8px}
.metrics .tile{padding:10px 12px}
.metrics .tile:first-child{background:#fff;border-color:var(--t7-warm-gray);color:inherit}
.metrics .tile:first-child .l{color:var(--t7-muted)}
.metrics .tile .n{font-size:clamp(15px,2vw,20px)}
.metrics .tile .l{font-size:9.5px;letter-spacing:.06em}

.group{margin-bottom:2.2rem}
.group-head{display:flex;align-items:baseline;gap:.6rem;flex-wrap:wrap;
  margin-bottom:.5rem}
.group-head h2{font-family:var(--t7-mono);text-transform:uppercase;
  letter-spacing:.12em;font-size:12px;color:var(--t7-muted);font-weight:500;margin:0}
.group-count{font-family:var(--t7-mono);font-size:11px;color:var(--t7-warm-gray)}
.group-head .blurb{flex:1 1 100%;color:var(--t7-muted);font-size:13px;margin:0}

/* --- the prospects table: dense, one row per domain --- */
/* table-layout:fixed plus each instance's own <colgroup> (control/index.html)
   is what keeps the warm/known/anonymous tables' columns lined up with each
   other, the same reasoning as table.scans above. */
table.prospects{width:100%;border-collapse:collapse;font-size:14px;background:#fff;
  border:2px solid var(--t7-warm-gray);border-radius:0;overflow:hidden;
  table-layout:fixed}
table.prospects td,table.prospects th{overflow:hidden;text-overflow:ellipsis}
table.prospects > thead th{font-family:var(--t7-mono);text-transform:uppercase;
  letter-spacing:.07em;font-size:10px;color:var(--t7-muted);font-weight:500;
  text-align:left;padding:.5rem .6rem;background:var(--t7-khaki);
  border-bottom:1px solid var(--t7-warm-gray);white-space:nowrap}
/* Both row kinds, not just .p-row. A client's extra domains are .p-detail rows
   carrying the same nine cells as the row above them, so leaving them out of
   this left-aligned their scores and deltas inside a right-aligned column —
   the two numeric columns visibly out of line with every row around them,
   while every other column looked fine. Tabular figures matter here for the
   same reason: proportional digits put "80" and "53" on different centres. */
table.prospects > thead th.num,
table.prospects > tbody > tr.p-row > td.num,
table.prospects > tbody > tr.p-detail > td.num{
  text-align:right;font-variant-numeric:tabular-nums}
table.prospects > tbody > tr.p-row > td{padding:.4rem .6rem;
  border-bottom:1px solid var(--t7-khaki);vertical-align:baseline;white-space:nowrap}
/* Plain rows — the key/value and timeline tables that carry no expander — get the
   same cells, so every row on every page reads as one thing. */
table.prospects > tbody > tr:not(.p-row):not(.p-detail) > td,
table.prospects > tbody > tr:not(.p-row):not(.p-detail) > th{padding:.4rem .6rem;
  border-bottom:1px solid var(--t7-khaki);vertical-align:baseline;text-align:left}
table.prospects > tbody > tr > th{font-family:var(--t7-mono);text-transform:uppercase;
  letter-spacing:.07em;font-size:10px;color:var(--t7-muted);font-weight:500;
  white-space:nowrap;width:9rem}
table.prospects > tbody > tr:last-child > td,
table.prospects > tbody > tr:last-child > th{border-bottom:0}
tr.p-row:hover td{background:var(--t7-paper)}
.c-expand{width:3.2rem;padding-right:0 !important}
.row-toggle{display:inline-block}
.row-toggle>summary{cursor:pointer;list-style:none;width:2.2rem;height:2.2rem;
  display:grid;place-items:center;color:var(--t7-electric);font-size:1.44rem;
  border-radius:0}
.row-toggle>summary::-webkit-details-marker{display:none}
.row-toggle>summary::before{content:"\25b8"}
.row-toggle[open]>summary::before{content:"\25be"}
.row-toggle>summary:hover{background:var(--t7-lilac)}
.c-client{font-weight:600}
.c-domain{font-weight:500}
.c-sub{display:block;font-family:var(--t7-mono);font-size:10.5px;
  color:var(--t7-muted);font-weight:400;letter-spacing:.02em;margin-top:1px}
.c-sub.inline{display:inline;margin:0 0 0 .3rem}
.c-none{color:var(--t7-warm-gray)}
.c-when{font-family:var(--t7-mono);font-size:12px;color:var(--t7-muted)}

/* The delete control stays out of the way until you are on the row, and comes
   back for keyboard focus — otherwise it is unreachable without a mouse. */
.c-kill{width:1.8rem;padding-left:0 !important;text-align:right}
.c-kill form{margin:0;line-height:0}
.kill{display:inline-grid;place-items:center;width:1.5rem;height:1.5rem;padding:0;
  border:0;border-radius:0;background:none;color:var(--t7-warm-gray);cursor:pointer;
  opacity:0;transition:opacity .12s,color .12s,background .12s}
tr.p-row:hover .kill{opacity:1}
.kill:focus-visible{opacity:1}
.kill:hover{color:var(--air-bad);background:var(--air-bad-bg)}

/* The detail row stays hidden until its toggle is opened. :has keeps this in CSS;
   where it is unsupported the panel is simply always visible, which is not a
   failure — just less tidy. */
tr.p-detail{display:none}
tr.p-row:has(.row-toggle[open])+tr.p-detail{display:table-row}
tr.p-detail>td{padding:0 !important;background:var(--t7-paper)}
.detail-panel{padding:.6rem .6rem .8rem 2.2rem}
/* `table-layout:fixed` plus an explicit <colgroup> in every instance of this
   table (control/index.html) is what makes them line up with each other —
   auto layout sizes each table from its own content alone, so one client's
   domain table and the next one's landed their Score/Pages/Actions columns
   at different x positions, and the same was true client to client and
   organization to organization. Fixed widths make every instance compute the
   same column positions regardless of what it holds. */
table.scans{width:100%;border-collapse:collapse;font-size:13px;margin:0;
  table-layout:fixed}
table.scans th,table.scans td{text-align:left;padding:.35rem .5rem;
  border-bottom:1px solid var(--t7-khaki);white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
table.scans th{font-family:var(--t7-mono);text-transform:uppercase;
  letter-spacing:.07em;font-size:10px;color:var(--t7-muted);font-weight:500}
table.scans td.num,table.scans th.num{text-align:right;
  font-variant-numeric:tabular-nums}
/* The actions cells hold two or three icon buttons in a row, not text — the
   ellipsis clipping every other column wants was clipping the last icon
   right off the end of the column instead. */
table.scans td.c-act,table.scans td.c-actions{overflow:visible}
table.scans tr:last-child td{border-bottom:0}
/* The scan-history table nested inside a prospect's expand panel carries no
   header of its own (the prospect row's own header above it is the header —
   see control/index.html) and leads with a blank, unbordered spacer column
   sized to match that row's Expand+Prospect columns, so its own first real
   column (When) starts exactly where that row's Last-activity column does. */
table.scans td.c-spacer{border-bottom:0}

.pager{display:flex;align-items:center;gap:1rem;margin-top:.6rem;
  font-family:var(--t7-mono);font-size:11px;text-transform:uppercase;
  letter-spacing:.08em}
.pager a{color:var(--t7-electric);text-decoration:none}
.pager a:hover{text-decoration:underline}
.pager .off{color:var(--t7-warm-gray)}
.pager .of{color:var(--t7-muted);margin-left:auto}

.pill{display:inline-block;padding:2px 9px 1px;border-radius:0;
  font-family:var(--t7-mono);font-size:10.5px;font-weight:500;
  text-transform:uppercase;letter-spacing:.06em}
.pill.green{background:var(--air-good-bg);color:var(--air-good)}
.pill.amber{background:var(--t7-mimosa);color:var(--air-warn)}
.pill.red,.pill.gated{background:var(--air-bad-bg);color:var(--air-bad)}
.pill.pending,.pill.running{background:var(--t7-lilac);color:var(--t7-medium)}
.pill.anonymous{background:var(--t7-khaki);color:var(--t7-muted)}
.pill.known{background:var(--t7-lilac);color:var(--t7-medium)}
.pill.warm{background:var(--t7-mimosa);color:var(--air-warn)}
.empty{color:var(--t7-muted);font-size:14px;padding:.4rem 0}
/* Movement since the previous scan of the same kind. Reads next to the number it
   qualifies, so it never needs a column of its own. */
.delta{font-family:var(--t7-mono);font-size:11px;font-weight:600;white-space:nowrap}
.delta.up{color:var(--air-good)}
.delta.down{color:var(--air-bad)}
form.rescan{display:inline}
.c-actions{white-space:nowrap}
.scan-actions{display:flex;flex-wrap:wrap;gap:.7rem;margin-top:1.5rem}
.linkbtn{background:none;border:0;color:var(--t7-electric);font:inherit;
  cursor:pointer;padding:0}
.linkbtn:hover{text-decoration:underline}
.form-card{background:#fff;border:2px solid var(--t7-warm-gray);
  border-radius:var(--t7-radius);padding:24px;max-width:38rem}
.form-card--wide{max-width:none}
.form-card .row{margin-bottom:1.1rem}
.form-card label{display:block;font-family:var(--t7-mono);text-transform:uppercase;
  letter-spacing:.08em;font-size:11px;color:var(--t7-muted);margin-bottom:5px}
.form-card .opt{text-transform:none;letter-spacing:0}
.form-card input,.form-card select,.form-card textarea{width:100%;font:inherit;
  font-size:16px;padding:9px 11px;border:1.5px solid var(--t7-warm-gray);
  border-radius:0;background:var(--t7-paper);color:var(--t7-dark-purple);
  font-family:inherit}
.form-card input:focus,.form-card select:focus,.form-card textarea:focus{
  outline:none;border-color:var(--t7-electric)}
.form-card .check{display:flex;gap:.6rem;align-items:flex-start}
.form-card .check input{width:auto;margin-top:.3rem}
.form-card .check label{text-transform:none;letter-spacing:0;font-size:14.5px;
  color:var(--t7-dark-purple);font-family:var(--t7-sans)}
.form-card .hint{color:var(--t7-muted);font-size:13px;margin:.35rem 0 0;max-width:52ch}
.login{max-width:24rem;margin:8vh auto}

/* ------------------------------------------------------------ email editor */
.banner{border-radius:0;padding:.8rem 1rem;margin:0 0 1rem;font-size:15px;
  border:2px solid}
.banner.ok{background:var(--air-good-bg);border-color:var(--air-good-line);
  color:var(--air-good)}
.banner.bad{background:var(--air-bad-bg);border-color:var(--air-bad-line);
  color:var(--air-bad)}
/* One tab per email template, driven by the registry rather than a fixed list,
   so the strip grows on its own. Wraps rather than scrolls: five names fit on a
   laptop and a horizontal scroller hides the ones that do not. */
.emailtabs{display:flex;flex-wrap:wrap;gap:.4rem;margin:0 0 1.2rem}
.emailtabs__tab{font-family:var(--t7-mono);font-size:12px;letter-spacing:.06em;
  text-transform:uppercase;padding:.45rem .7rem;border:1px solid var(--t7-warm-gray);
  color:var(--t7-muted);text-decoration:none}
.emailtabs__tab--on{background:var(--t7-dark-purple);border-color:var(--t7-dark-purple);
  color:var(--t7-paper)}
/* The rendered email is a whole document with its own table layout and inline
   styles. In an iframe it cannot inherit from this stylesheet and lie about
   what a mail client will show. */
.emailtabs__frame{width:100%;height:520px;border:2px solid var(--t7-warm-gray);
  background:#fff}
.emailedit__edited{font-family:var(--t7-mono);font-size:10.5px;
  text-transform:uppercase;letter-spacing:.08em;color:var(--air-warn)}
.emailedit__hint{margin:.3rem 0 0;font-size:13px;color:var(--t7-muted)}
.emailedit__subject{margin:0 0 .6rem;font-size:15px}
.emailedit__text pre{white-space:pre-wrap;font-size:13px;
  background:var(--t7-khaki);padding:.8rem;margin:.6rem 0 0}
.email-grid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);
  gap:1.6rem;align-items:start}
@media (max-width:900px){.email-grid{grid-template-columns:1fr}}
.preview-mail{background:#fff;border:2px solid var(--t7-warm-gray);
  border-radius:var(--t7-radius);overflow:hidden}
.mail-head{padding:14px 16px;border-bottom:1px solid var(--t7-khaki);
  background:var(--t7-khaki);font-size:14px}
.mail-head div{margin-bottom:.2rem}
.mail-head .l{display:inline-block;width:4.2rem;font-family:var(--t7-mono);
  font-size:10.5px;text-transform:uppercase;letter-spacing:.08em;color:var(--t7-muted)}
.mail-body{padding:16px;font-size:15px;line-height:1.6}
.mail-body p{margin:0 0 .9rem;max-width:52ch}
.mail-body p:last-child{margin-bottom:0}

.cta-save{text-align:center;margin:0 0 2.2rem}
.cta-save form{display:inline}
.cta-save.saved{font-family:var(--t7-mono);font-size:13px;color:var(--t7-muted)}

/* ------------------------------------------------------------ sending status */
.sending{border:2px solid var(--t7-warm-gray);border-radius:var(--t7-radius);
  padding:18px 20px;margin:0 0 1.8rem;background:#fff}
.sending.is-on{border-color:var(--air-good-line);background:var(--air-good-bg)}
.sending.is-off{border-color:var(--t7-coral);background:var(--t7-mimosa)}
.sending-head{display:flex;align-items:flex-start;gap:.9rem;flex-wrap:wrap}
.sending-head>div{flex:1 1 18rem;min-width:0}
.sending-head strong{display:block;font-size:16px;margin-bottom:.2rem}
.sending-head p{margin:0;font-size:14px;color:var(--t7-muted);max-width:52ch}
.sending .dot{flex:0 0 auto;width:11px;height:11px;border-radius:50%;margin-top:.42rem}
.sending.is-on .dot{background:var(--air-good)}
.sending.is-off .dot{background:var(--t7-coral)}
code.copyable{display:inline-block;font-family:var(--t7-mono);font-size:12.5px;
  background:#fff;border:1px solid var(--t7-warm-gray);border-radius:0;
  padding:.15rem .45rem;word-break:break-all;user-select:all}

/* ------------------------------------------------------------------ census */
/* The Census pages are tables of other people's numbers, so they get the
   prospects table rather than a second table style — one dense row per thing is
   already the house pattern. What is added here is the furniture around them:
   the caveats, the figures, and the source blocks. */

/* Plain rows carry `.num` too. The rule above only reaches thead and .p-row,
   which would leave a column of scores ragged-left under a right-aligned head. */
table.prospects > tbody > tr:not(.p-row):not(.p-detail) > td.num{
  text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}

/* A long population table is wider than a phone. Scroll the table, never the
   page — a body that scrolls sideways loses the reader's place in the prose. */
.table-scroll{overflow-x:auto;margin:0 0 1.2rem;-webkit-overflow-scrolling:touch}

.lede-muted{color:var(--t7-muted);max-width:66ch;margin:0 0 1rem;font-size:16px}
.census-h2{font-size:20px;margin:2.4rem 0 .8rem}
.census-h3{font-size:15px;margin:1.8rem 0 .6rem}
.census-section{margin:0 0 1rem}
.census-list{color:var(--t7-muted);max-width:66ch;margin:0 0 1rem;padding-left:1.1rem}
.census-list li{margin:0 0 .5rem}
.census-note{color:var(--t7-muted);max-width:66ch;font-size:13px;
  margin:.4rem 0 1.4rem;line-height:1.5}
.census-stat-line{color:var(--t7-muted);font-size:14px;margin:0 0 1.6rem}
.cell-note{color:var(--t7-muted);font-size:12px;line-height:1.35;
  display:inline-block;max-width:44ch;white-space:normal}
.hash{font-family:var(--t7-mono);font-size:11px;color:var(--t7-muted)}

/* The three states a census year can be in. Said in a band rather than a
   sentence buried in prose, because "this is partial" is the one thing a reader
   must not miss on the way to a headline number. */
.census-banner{border-radius:0;padding:.9rem 1.1rem;margin:0 0 1.6rem;
  font-size:14px;border:1px solid}
.census-banner p{margin:0;max-width:70ch}
.census-banner--planned{background:var(--t7-lilac);border-color:#CFC0FF;
  color:var(--t7-medium)}
.census-banner--partial{background:var(--air-warn-bg);
  border-color:var(--air-warn-line);color:var(--air-warn)}

.pill--done{background:var(--air-good-bg);color:var(--air-good)}
.pill--partial{background:var(--t7-mimosa);color:var(--air-warn)}
.pill--planned{background:var(--t7-lilac);color:var(--t7-medium)}

.census-source{background:var(--t7-khaki);border-radius:0;padding:1rem 1.2rem;
  margin:1.4rem 0}
.census-source h2{margin-top:0}
.census-dl{margin:0;display:grid;grid-template-columns:11rem minmax(0,1fr);
  gap:.35rem 1rem;font-size:14px}
.census-dl dt{font-family:var(--t7-mono);text-transform:uppercase;
  letter-spacing:.07em;font-size:10px;color:var(--t7-muted);padding-top:.25rem}
.census-dl dd{margin:0;color:var(--t7-dark-purple)}

.census-basis{background:var(--t7-lilac);border-left:3px solid var(--t7-electric);
  border-radius:0;padding:.8rem 1rem;margin:0 0 1rem;font-size:14px;
  color:var(--t7-medium);max-width:70ch}

.census-figures{display:flex;flex-wrap:wrap;gap:1.6rem;margin:0 0 1.6rem}
.census-figures .figure{display:flex;flex-direction:column;gap:.2rem}
.figure-n{font-size:26px;font-weight:600;color:var(--t7-dark-purple);
  font-variant-numeric:tabular-nums;line-height:1.1}
.figure-label{font-family:var(--t7-mono);text-transform:uppercase;
  letter-spacing:.09em;font-size:10px;color:var(--t7-muted)}

/* Four hundred rows: let them wrap rather than forcing a horizontal scroll of
   mostly whitespace. */
.census-population td{white-space:normal}

@media (max-width:640px){
  .census-dl{grid-template-columns:1fr;gap:.1rem .5rem}
  .census-dl dd{margin:0 0 .6rem}
  .census-figures{gap:1.1rem}
}

/* --------------------------------------------------------------- the dials */
/* Eight rings beside the headline number. The total says how bad it is; these
   say where, and a column of percentages is a table people skim past. A ring
   somebody can see is filled or empty is not.

   Fixed order, never sorted by score: the third ring is always extraction, so a
   reader learns the layout once. */
.dials{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:1rem .6rem;align-content:center}
.dial{display:flex;flex-direction:column;align-items:center;gap:.3rem;
  text-decoration:none;padding:.35rem .1rem;border-radius:0}
.dial:hover{background:var(--t7-khaki)}
.dial svg{width:100%;max-width:96px;height:auto;aspect-ratio:1;
  transform:rotate(-90deg)}
.dial__track{fill:none;stroke:var(--t7-warm-gray);stroke-opacity:.5;stroke-width:3.5}
.dial__arc{fill:none;stroke-width:3.5;stroke-linecap:round;
  transition:stroke-dasharray .5s ease}
.dial__num{transform:rotate(90deg);transform-origin:20px 20px;
  font-family:var(--t7-sans);font-size:14px;font-weight:700;
  fill:var(--t7-dark-purple)}
.dial__label{font-family:var(--t7-mono);font-size:10px;text-transform:uppercase;
  letter-spacing:.06em;color:var(--t7-medium);text-align:center;line-height:1.2;
  font-weight:500}
.dial--good .dial__arc{stroke:var(--air-good)}
.dial--warn .dial__arc{stroke:var(--air-warn)}
.dial--bad  .dial__arc{stroke:var(--air-bad)}
.dial--na   .dial__num{fill:var(--t7-muted)}

/* The headline and the dials, side by side and equally weighted. Below 760px
   they stack, because eight rings and a paragraph will not share a phone. */
/* A third and two thirds. The number is one fact and the eight dimensions are
   eight, and the space each gets should say so. */
.verdict-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,2fr);
  gap:1.4rem;align-items:stretch;margin:0 0 1rem}
@media (max-width:760px){
  .verdict-row{grid-template-columns:1fr}
}

/* ------------------------------------------------------ what to do about it */
/* Sixty-eight findings sorted by dimension is a list of everything wrong, which
   is the least useful order. These three are the ones that move the number
   most, and a failed gate jumps the queue whatever it scores on paper. */
.next-three{margin:0 0 1.8rem}
.next-three ol{list-style:none;counter-reset:step;margin:0;padding:0;
  display:grid;gap:.6rem}
.next-three li{counter-increment:step;display:grid;
  grid-template-columns:2rem minmax(0,1fr) auto;gap:.8rem;align-items:baseline;
  background:#fff;border:1px solid var(--t7-warm-gray);border-radius:0;
  padding:.8rem 1rem}
.next-three li::before{content:counter(step);font-family:var(--t7-serif);
  font-size:1.5rem;font-weight:700;color:var(--t7-electric);line-height:1}
.next-three h4{margin:0 0 .2rem;font-size:15px}
.next-three .why{margin:0;font-size:13px;color:var(--t7-muted);max-width:62ch}
.next-three .worth{font-family:var(--t7-mono);font-size:11px;white-space:nowrap;
  color:var(--t7-electric);text-align:right}
.next-three .worth b{display:block;font-size:16px;color:var(--t7-dark-purple)}
@media (max-width:640px){
  .next-three li{grid-template-columns:1.6rem minmax(0,1fr)}
  .next-three .worth{grid-column:2;text-align:left}
  .next-three .worth b{display:inline}
}

/* The headline block. Named scorebox rather than verdict because .verdict is
   already the quick scan's traffic light and this is the full report's purple
   panel — the same markup the client report carries, so a census subject and a
   paying client read the same picture of the same measurement. */
/* Lilac, with the type dark enough to read at a glance. It used to be dark
   purple on paper, which made the box shout louder than the eight dials beside
   it — and the whole point of the pair is that neither outranks the other. */
.scorebox{display:flex;flex-direction:column;justify-content:center;gap:.5rem;
  background:var(--t7-lilac);color:var(--t7-dark-purple);
  border:1px solid #CFC0FF;border-radius:var(--t7-radius);padding:24px 26px}
.scorebox .num{font-family:var(--t7-serif);font-size:clamp(2.6rem,6vw,3.6rem);
  font-weight:700;line-height:1;white-space:nowrap;color:var(--t7-dark-purple)}
.scorebox .num span{font-size:1.1rem;color:var(--t7-medium);opacity:.75}
.scorebox--good .num{color:var(--air-good)}
.scorebox--warn .num{color:var(--air-warn)}
.scorebox--bad .num{color:var(--air-bad)}
.scorebox strong{display:block;font-family:var(--t7-serif);font-size:1.3rem;
  line-height:1.25;color:var(--t7-dark-purple);margin-bottom:.3rem}
.scorebox p{margin:0;color:var(--t7-medium);font-size:15px}
.scorebox .basis{margin-top:.5rem;font-size:12.5px;color:var(--t7-muted);
  max-width:52ch}


/* ------------------------------------------------------------- the score bar */
/* The hundred points, left to right, under the box and the dials. The dials say
   how each dimension did; this says how much of the score each one was ever
   able to decide — a dimension at 100% worth three points looks identical to
   one worth twenty-two on a ring, and nothing like it here. */
.scorebar{display:flex;gap:3px;height:34px;margin:0 0 .5rem;
  border-radius:0;overflow:hidden}
.scorebar__slice{position:relative;display:block;min-width:0;
  background:var(--t7-khaki);border-radius:0;overflow:hidden;
  text-decoration:none;transition:filter .15s}
.scorebar__slice:hover{filter:brightness(.94)}
.scorebar__fill{position:absolute;inset:0 auto 0 0;display:block;
  transition:width .5s ease}
.scorebar__slice--good .scorebar__fill{background:var(--air-good)}
.scorebar__slice--warn .scorebar__fill{background:var(--air-warn)}
.scorebar__slice--bad  .scorebar__fill{background:var(--air-bad)}
.scorebar__slice--na   .scorebar__fill{background:var(--t7-warm-gray)}
.scorebar__tick{position:absolute;inset:auto 0 2px 0;text-align:center;
  font-family:var(--t7-mono);font-size:9px;color:var(--t7-dark-purple);
  opacity:.55;pointer-events:none}
.scorebar__legend{margin:0 0 1.8rem;font-size:12px;color:var(--t7-muted);
  max-width:70ch}
@media (max-width:560px){
  .scorebar{height:26px;gap:2px}
  .scorebar__tick{display:none}
}

/* ------------------------------------------------------------ the grade scale */
/* The same hundred as the bar above, read the other way: that one is where the
   points live, this is what a total of them is called. They share an axis on
   purpose, so a reader can see how far along the same hundred a score sits.
   Widths are the band widths — "Not ready" really is two fifths of the scale,
   and a scale that showed five equal blocks would say otherwise. */
.gradescale{display:flex;gap:2px;margin:0 0 .5rem;border-radius:0;
  overflow:hidden}
.gradescale__band{position:relative;display:flex;flex-direction:column;
  justify-content:center;min-width:0;padding:.3rem .4rem;border-radius:0;
  text-decoration:none;opacity:.45;transition:opacity .15s;
  background:var(--t7-khaki)}
.gradescale__band:hover{opacity:.8}
/* The band this site is in, and only that one, at full strength. Five bands all
   equally lit would be a legend; one lit is a reading. */
.gradescale__band.is-here{opacity:1;box-shadow:inset 0 0 0 2px currentColor}
.gradescale__name{font-family:var(--t7-mono);font-size:9.5px;
  text-transform:uppercase;letter-spacing:.06em;line-height:1.2;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gradescale__range{font-size:9px;opacity:.75;line-height:1.2}
.gradescale__band--b0{background:var(--air-bad-bg);color:var(--air-bad)}
.gradescale__band--b1{background:#FCE7EF;color:#B0004F}
.gradescale__band--b2{background:var(--air-warn-bg);color:var(--air-warn)}
.gradescale__band--b3{background:#E7F3ED;color:#2C7A5B}
.gradescale__band--b4{background:var(--air-good-bg);color:var(--air-good)}
@media (max-width:560px){
  .gradescale__range{display:none}
  .gradescale__name{font-size:8.5px}
}

/* ------------------------------------------------------------ sortable tables */
/* Added by sorttable.js once it has run, so a table without JavaScript never
   advertises a control that is not there. */
th.is-sortable{cursor:pointer;user-select:none;position:relative;
  padding-right:1.1rem !important}
th.is-sortable:hover{color:var(--t7-electric)}
th.is-sortable:focus-visible{outline:2px solid var(--t7-electric);
  outline-offset:-2px}
/* A faint marker on every sortable column and a solid one on the sorted column:
   the first says "you can", the second says "you did". */
th.is-sortable::after{content:"\2195";position:absolute;right:.35rem;
  opacity:.3;font-size:.9em}
th.is-sortable[aria-sort="ascending"]::after{content:"\2191";opacity:1;
  color:var(--t7-electric)}
th.is-sortable[aria-sort="descending"]::after{content:"\2193";opacity:1;
  color:var(--t7-electric)}

/* ============================================================
   DESIGN SYSTEM — the check-pattern redesign (readiness-design-system.md)
   ============================================================ */

/* --------------------------------------------------------------- Layer 1: primitives */

.status-chip{display:inline-block;font-family:var(--t7-mono);font-size:11px;
  font-weight:700;letter-spacing:.06em;padding:4px 8px;border-radius:0;
  white-space:nowrap}
.status-chip--problem{background:var(--status-problem-fill);color:var(--status-ink)}
.status-chip--needs-work{background:var(--status-needs-surface);
  border:1px solid var(--status-needs-border);color:var(--status-ink)}
.status-chip--pass{background:none;color:var(--t7-muted);font-weight:500}
.ds-checkrow__pts{display:inline-block;font-family:var(--t7-mono);font-size:12px;
  font-weight:700;letter-spacing:.02em;padding:4px 8px;border-radius:0;
  white-space:nowrap;background:var(--status-needs-surface);
  border:1px solid var(--status-needs-border);color:var(--status-ink)}
.tag-chip{display:inline-block;font-family:var(--t7-mono);font-size:11px;
  font-weight:700;letter-spacing:.06em;padding:4px 8px;border-radius:0;
  white-space:nowrap;background:var(--t7-lilac);color:var(--t7-electric)}

.ds-eyebrow{font-family:var(--t7-label);font-size:11px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase}
.ds-eyebrow--muted{color:var(--t7-muted)}       /* AA-safe at this size; see below */
.ds-eyebrow--on-dark{color:var(--evidence-label)}
.ds-eyebrow--ink{color:var(--status-ink)}
.ds-eyebrow--coral{color:var(--t7-coral)}
/* The handoff's own contrast rule ("#7F6B97 only at 13px+") would fail against
   its Eyebrow spec ("10-11px, muted = #7F6B97") if followed literally — an
   eyebrow is always below 13px by definition. --t7-muted is this codebase's
   existing darkened stand-in, already AA-checked at small sizes on Paper,
   White, Lilac and Khaki; using it here is honouring the contrast rule, not
   deviating from the design. */

.ds-sharebar{background:var(--bar-track);overflow:hidden}
.ds-sharebar__fill{height:100%;transition:width .3s var(--t7-ease,ease)}
.ds-sharebar__fill--good{background:var(--status-pass-mark)}
.ds-sharebar__fill--weak{background:var(--status-problem-fill)}
.ds-sharebar__fill--neutral{background:var(--t7-lavender)}

.ds-spreadbar{position:relative;height:8px;background:var(--t7-lilac)}
.ds-spreadbar__iqr{position:absolute;top:0;bottom:0;background:var(--t7-warm-gray)}
.ds-spreadbar__median{position:absolute;top:-2px;bottom:-2px;width:3px;
  background:var(--t7-electric);transform:translateX(-1.5px)}

.ds-monostat{font-family:var(--t7-mono);font-size:12px;color:var(--t7-muted)}
.ds-monostat__v--ink{color:var(--t7-dark-purple);font-weight:700}
.ds-monostat__v--alarm{color:var(--status-problem-fill);font-weight:700}
.ds-monostat__v--muted{color:var(--t7-muted)}

.ds-filterchips{display:flex;flex-wrap:wrap;gap:8px;font-family:var(--t7-mono);
  font-size:12px}
.ds-filterchip{display:inline-block;padding:6px 11px;border:1px solid var(--t7-warm-gray);
  background:var(--t7-paper);color:var(--t7-dark-purple);border-radius:0;
  text-decoration:none}
.ds-filterchip:hover{border-color:var(--t7-electric);text-decoration:none}
.ds-filterchip.is-active{background:var(--t7-dark-purple);border-color:var(--t7-dark-purple);
  color:var(--t7-paper);font-weight:700}
.ds-filterchip__count{opacity:.75}

/* --------------------------------------------------------------- Layer 2: surfaces */

.ds-scoreblock{display:flex;flex-direction:column;gap:.35rem}
.ds-scoreblock--dark{background:var(--t7-medium);color:#fff;padding:26px 28px}
.ds-scoreblock--paper{background:var(--t7-paper);color:var(--t7-dark-purple);
  border:1px solid var(--t7-warm-gray);padding:26px 28px}
.ds-scoreblock__num{font-family:var(--t7-serif);font-size:clamp(2.6rem,6vw,3.4rem);
  font-weight:700;line-height:1;white-space:nowrap}
.ds-scoreblock__num span{font-family:var(--t7-mono);font-size:15px;font-weight:400;
  margin-left:.25em}
.ds-scoreblock--dark .ds-scoreblock__num span{color:var(--t7-warm-gray)}
.ds-scoreblock--paper .ds-scoreblock__num span{color:var(--t7-muted)}
.ds-scoreblock__sub{font-family:var(--t7-label);font-size:11px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase}
.ds-scoreblock--dark .ds-scoreblock__sub{color:var(--t7-mimosa)}
.ds-scoreblock--paper .ds-scoreblock__sub{color:var(--t7-muted)}
.ds-scoreblock__note{font-family:var(--t7-mono);font-size:12px;line-height:1.7}
.ds-scoreblock--dark .ds-scoreblock__note{color:var(--t7-warm-gray)}
.ds-scoreblock--paper .ds-scoreblock__note{color:var(--t7-muted)}

/* The verdict aside's own note, under the score block rather than inside it —
   the case for the full scan, argued next to the number it is qualifying. */
.ds-aside-note{margin:0;font-size:14px;line-height:1.6;color:var(--t7-dark-purple)}

/* ------------------------------------------------------- reference-page composition */
/* Shared by every page that leads with a plain hero (eyebrow, h1, blurb, a
   mono meta line) beside a dark ScoreBlock, rather than the bordered
   VerdictBlock a findings page uses — the Readiness Report and the census
   pages all read the same way here. */
.ds-hero{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:30px;
  align-items:start;margin:0 0 34px}
.ds-hero__main{display:flex;flex-direction:column;gap:9px}
/* The cap belongs to the two-column hero, not to the block. Inside `.ds-hero`
   the main column runs beside a 300px panel and wants a measure; used on its
   own — which is how the reference pages use it, and how the census pages use
   it whenever there is no panel to sit beside — that same cap is just a
   two-thirds column with the rest of the container left empty. */
.ds-hero__main p{margin:0;font-size:17px;line-height:1.6;max-width:none}
.ds-hero > .ds-hero__main p{max-width:620px}
.ds-hero__meta{font-family:var(--t7-mono);font-size:13px;color:var(--t7-muted)}
@media (max-width:760px){.ds-hero{grid-template-columns:1fr}}

.ds-dims{margin:0 0 34px}
.ds-dims__head{display:flex;flex-wrap:wrap;align-items:baseline;
  justify-content:space-between;gap:12px;margin:0 0 10px}
.ds-dims__head .ds-monostat{color:var(--t7-muted)}

.ds-fixes{margin:0 0 34px;display:flex;flex-direction:column;gap:16px}
.ds-fixes>p{margin:0;font-size:16px;line-height:1.6;max-width:680px}

.ds-refintro{margin:0 0 20px}
.ds-refintro p{margin:0 0 1rem;max-width:none;font-size:17px;line-height:1.65}
.ds-refintro h2{font-size:clamp(22px,3.1vw,29px);line-height:1.2;margin:2.4rem 0 .8rem}

.ds-refqueue{margin:0 0 34px;display:flex;flex-direction:column;gap:14px}
.ds-refqueue__head{display:flex;flex-wrap:wrap;align-items:flex-end;
  justify-content:space-between;gap:14px}
.ds-refqueue__head p{margin:0;font-size:16px;line-height:1.6;max-width:620px}

.ds-footline{border-top:1px solid var(--t7-warm-gray);padding-top:18px;margin-top:8px}

/* CensusCard — The Census's hero aside: a status card for the in-progress
   year, no score to show. Sits in the same 300px `.ds-hero` slot the
   weightbox/scoreblock occupy elsewhere; it brings its own border since
   `.ds-hero` itself is unstyled. */
.ds-censuscard{border:1px solid var(--t7-warm-gray);background:#fff;
  display:flex;flex-direction:column}
.ds-censuscard__head{display:flex;flex-wrap:wrap;align-items:center;
  justify-content:space-between;gap:10px;padding:16px 20px;
  background:var(--t7-mimosa);border-bottom:1px solid var(--t7-warm-gray)}
.ds-censuscard__head h2{margin:0;font-family:var(--t7-serif);font-size:24px;
  line-height:1;color:var(--t7-dark-purple)}
.ds-censuscard__body{padding:18px 20px;display:flex;flex-direction:column;gap:12px}
.ds-censuscard__progress{display:flex;flex-direction:column;gap:7px}
.ds-censuscard__stats{display:flex;flex-direction:column;gap:5px;
  font-family:var(--t7-mono);font-size:13px;line-height:1.6;color:var(--t7-dark-purple)}
.ds-censuscard__cta{width:100%}

/* CohortTable — the census index's population table: which five groups get
   scanned, how many sites, and the spread of scores each cohort carries so
   far. Same shape as landing's `.home-cats` (khaki head, lilac dividers,
   dark-purple foot) but its own rules — the column count and content differ
   enough that sharing one grid-template would fight itself.

   Every column — header and data alike — is left-justified, on both the
   plain and `--wide` variants. A numeric column right-aligned against a
   left-aligned one made the header and the row above/below it read as two
   unrelated tables sharing a border; keep new columns left-aligned too. */
.ds-cohorttable{border:1px solid var(--t7-warm-gray);background:#fff;margin:0 0 34px}
.ds-cohorttable__head,.ds-cohorttable__row{display:grid;
  grid-template-columns:minmax(0,1.3fr) minmax(0,1fr) 120px 160px;
  gap:16px;align-items:center;padding:14px 20px}
.ds-cohorttable__head{padding:11px 20px;background:var(--t7-khaki);
  border-bottom:1px solid var(--t7-warm-gray);font-family:var(--t7-label);
  font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--t7-muted)}
.ds-cohorttable__row{border-bottom:1px solid var(--t7-lilac);
  text-decoration:none;color:inherit}
.ds-cohorttable__row:last-of-type{border-bottom:0}
.ds-cohorttable__row:hover{background:var(--t7-paper)}
.ds-cohorttable__name{display:flex;flex-direction:column;gap:3px;min-width:0}
.ds-cohorttable__title{font-weight:700;font-size:14px;font-family:var(--t7-mono);
  color:var(--t7-dark-purple)}
.ds-cohorttable__desc{font-size:13px;line-height:1.4;color:var(--t7-muted)}
.ds-cohorttable__source{font-size:13px;line-height:1.4;color:var(--t7-dark-purple)}
.ds-cohorttable__num{text-align:left;font-family:var(--t7-mono);font-size:13px}
.ds-cohorttable__score{display:flex;flex-direction:column;gap:5px;align-items:stretch;
  text-align:left}
.ds-cohorttable__score .ds-spreadbar{width:100%}
.ds-cohorttable__foot{background:var(--t7-dark-purple);padding:15px 20px;
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px}
.ds-cohorttable__foot .ds-monostat{color:var(--t7-lilac)}
.ds-cohorttable__foot a{color:var(--t7-mimosa);font-family:var(--t7-mono);font-size:12px}
.ds-cohorttable__row--total{background:var(--t7-lilac);font-weight:600;cursor:default}
.ds-cohorttable__row--total:hover{background:var(--t7-lilac)}
/* The spread bar's own track is the same lilac as this row's background —
   identical colors, so the track disappeared entirely and only the grey
   IQR box and median line still read. White reads brighter here than the
   paper ground the rest of the page uses, which is the contrast this row
   needs against its own lilac background. */
.ds-cohorttable__row--total .ds-spreadbar{background:#fff}
@media (max-width:760px){
  .ds-censuscard__head h2{font-size:20px}
  .ds-cohorttable__head{display:none}
  .ds-cohorttable__row{grid-template-columns:1fr;gap:6px}
  .ds-cohorttable__score{align-items:flex-start}
}

/* CheckUsCards — "How to check us"'s 2x2 grid of outbound links. tone: the
   default rail (electric) marks the two documents this project stakes its
   claims on; `--ref` (lavender) marks the two operational references. */
.ds-checkuscards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:12px;margin:0 0 34px}
.ds-checkuscard{background:#fff;border:1px solid var(--t7-warm-gray);
  border-left:var(--rail-width) solid var(--t7-electric);
  padding:18px 20px;display:flex;flex-direction:column;gap:6px}
.ds-checkuscard--ref{border-left-color:var(--t7-lavender)}
.ds-checkuscard__title{font-size:16px;font-weight:600}
.ds-checkuscard__title a{color:var(--t7-dark-purple)}
.ds-checkuscard__body{margin:0;font-size:15px;line-height:1.55;color:var(--t7-muted)}
@media (max-width:600px){.ds-checkuscards{grid-template-columns:1fr}}

/* CensusBand — the closing "scanned without asking" note, dark and full
   width so the opt-out path reads as a real offer, not fine print. */
.ds-censusband{background:var(--t7-medium);padding:26px 28px;margin:0 0 8px}
.ds-censusband__body{display:flex;flex-direction:column;gap:6px}
.ds-censusband__body p{margin:0;font-size:16px;line-height:1.6;color:#fff}
.ds-censusband__body a{color:var(--t7-mimosa);text-decoration:underline}

/* CohortTable's wide variant — Census 2026 swaps the score column for a
   Median-and-spread column plus a separate Gated one, so it needs its own
   five-column template rather than the four-column one The Census uses. */
.ds-cohorttable--wide .ds-cohorttable__head,
.ds-cohorttable--wide .ds-cohorttable__row{
  grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr) minmax(0,200px) 90px 100px}
.ds-cohorttable__spread{display:flex;flex-direction:column;gap:5px;text-align:left}
.ds-cohorttable__foot-median{color:#fff;font-weight:700}
@media (max-width:760px){
  .ds-cohorttable--wide .ds-cohorttable__row{grid-template-columns:1fr}
}

/* FailBand — Census 2026's "checks almost nobody passes," tiered by how
   universal the failure is. tone only colours the header strip and dot;
   the row grid and bar are shared regardless of tier. */
.ds-failband{border:1px solid var(--t7-warm-gray);background:#fff;margin:0 0 14px}
.ds-failband--coral{border-color:var(--t7-coral)}
.ds-failband__head{display:flex;flex-wrap:wrap;align-items:center;
  justify-content:space-between;gap:10px;padding:12px 18px}
.ds-failband--coral .ds-failband__head{background:var(--t7-coral)}
.ds-failband--mimosa .ds-failband__head{background:var(--t7-mimosa)}
.ds-failband--lilac .ds-failband__head{background:var(--t7-lilac)}
.ds-failband__label{display:inline-flex;align-items:center;gap:9px;
  font-family:var(--t7-label);font-size:11px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--t7-dark-purple)}
.ds-failband__dot{width:9px;height:9px;background:var(--t7-dark-purple);flex:0 0 auto}
.ds-failband--lilac .ds-failband__dot{background:var(--t7-electric)}
.ds-failband__cols,.ds-failband__row{display:grid;
  grid-template-columns:88px minmax(0,1fr) 180px 84px 76px;
  gap:16px;align-items:center;padding:11px 18px}
.ds-failband__cols{background:var(--t7-khaki);border-top:1px solid var(--t7-warm-gray);
  border-bottom:1px solid var(--t7-warm-gray);font-family:var(--t7-label);
  font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--t7-muted)}
.ds-failband__cols span:nth-child(n+3),.ds-failband__row span:nth-child(n+3){text-align:right}
.ds-failband__row{border-bottom:1px solid var(--t7-lilac);text-decoration:none;color:inherit}
.ds-failband__row:last-of-type{border-bottom:0}
.ds-failband__row:hover{background:var(--t7-paper)}
.ds-failband__row>span:nth-child(2){font-size:15px;line-height:1.35;color:var(--t7-dark-purple)}
.ds-failband__bar{display:flex;align-items:center;gap:10px;text-align:left!important}
.ds-failband__bar .ds-sharebar{flex:1}
@media (max-width:760px){
  .ds-failband__cols{display:none}
  .ds-failband__row{grid-template-columns:1fr;gap:6px;text-align:left!important}
  .ds-failband__row span:nth-child(n+3){text-align:left}
}

/* CensusData — the closing "published in full" section: file cards beside a
   dark citation box, same 1fr/aside shape as `.ds-hero` but its own rules
   since the aside here is a bordered block, not a bare 300px slot. */
.ds-censusdata{display:grid;grid-template-columns:minmax(0,1fr) 340px;
  gap:30px;align-items:start;margin:0 0 34px}
.ds-filecards{display:flex;flex-direction:column;gap:10px}
.ds-filecard{display:grid;grid-template-columns:150px minmax(0,1fr);gap:18px;
  align-items:start;background:#fff;border:1px solid var(--t7-warm-gray);
  padding:15px 18px;text-decoration:none}
.ds-filecard:hover{background:var(--t7-paper)}
.ds-filecard__name{font-family:var(--t7-mono);font-size:14px;font-weight:700;
  color:var(--t7-electric)}
.ds-filecard__body{font-size:15px;line-height:1.55;color:var(--t7-dark-purple)}
.ds-citebox{background:var(--t7-dark-purple);padding:22px 24px;
  display:flex;flex-direction:column;gap:12px}
.ds-citebox__cite{margin:0;font-family:var(--t7-mono);font-size:13px;
  line-height:1.8;color:var(--t7-lilac)}
.ds-citebox__meta{font-family:var(--t7-mono);font-size:12px;line-height:1.8;
  color:var(--t7-warm-gray);border-top:1px solid var(--t7-medium);padding-top:12px}
.ds-citebox__meta strong{color:#fff}
.ds-citebox__links{margin:0;font-size:14px;line-height:1.6;color:var(--t7-lilac)}
.ds-citebox__links a{color:var(--t7-mimosa);text-decoration:underline}
@media (max-width:760px){.ds-censusdata{grid-template-columns:1fr}
  .ds-filecard{grid-template-columns:1fr;gap:6px}}

/* StandingCard — a cohort page's hero aside: the median plus where it sits
   among the other cohorts this year. Sits in `.ds-hero`'s 300px slot like
   CensusCard/WeightBox do; its own rules since neither of those fit a
   "number + comparison" shape. */
.ds-standingcard{background:var(--t7-medium);color:#fff;padding:22px 24px;
  display:flex;flex-direction:column;gap:9px}
.ds-standingcard__num{display:flex;align-items:baseline;gap:7px;
  font-family:var(--t7-serif);font-size:44px;line-height:.95;color:#fff}
.ds-standingcard__num span{font-family:var(--t7-mono);font-size:14px;
  color:var(--t7-warm-gray);font-weight:400}
.ds-standingcard__note{font-family:var(--t7-mono);font-size:12px;line-height:1.8;
  color:var(--t7-warm-gray);padding-top:4px}

/* ProvBox — "where this list came from": a bordered card with a khaki header
   strip, reused verbatim across cohort pages via the same key/value shape
   `.ds-receipt` already renders, just under its own header. */
.ds-provbox{border:1px solid var(--t7-warm-gray);background:#fff;margin:0 0 20px}
.ds-provbox__head{padding:12px 20px;background:var(--t7-khaki);
  border-bottom:1px solid var(--t7-warm-gray)}
.ds-provbox__body{padding:4px 20px 18px}
.ds-provbox__note{margin:0;font-size:14px;line-height:1.65;color:var(--t7-dark-purple);
  border-top:1px solid var(--t7-warm-gray);padding:14px 20px 0;max-width:860px}

/* ShapeTiles — the cohort's median/spread/gated count, at a glance. */
.ds-shapetiles{display:flex;flex-wrap:wrap;border:1px solid var(--t7-warm-gray);
  margin:0 0 20px}
.ds-shapetile{flex:1 1 180px;padding:18px 20px;background:#fff;
  border-right:1px solid var(--t7-warm-gray)}
.ds-shapetile:last-child{border-right:0}
.ds-shapetile--warn{background:var(--t7-mimosa)}
.ds-shapetile__n{font-family:var(--t7-serif);font-size:28px;line-height:1;
  color:var(--t7-dark-purple)}
.ds-shapetile__label{display:block;padding-top:6px;font-family:var(--t7-label);
  font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--t7-muted)}

/* BarTable — a two-shape reusable table for "Grades" (chip + bar + counts)
   and "By dimension" (name + bar + mean): same head/row/num plumbing, two
   grid-template modifiers since the column counts differ. */
.ds-bartable{border:1px solid var(--t7-warm-gray);background:#fff;margin:0 0 20px}
.ds-bartable__head,.ds-bartable__row{display:grid;gap:16px;align-items:center;
  padding:12px 18px}
.ds-bartable__head{background:var(--t7-khaki);border-bottom:1px solid var(--t7-warm-gray);
  font-family:var(--t7-label);font-size:10px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--t7-muted)}
.ds-bartable__row{border-bottom:1px solid var(--t7-lilac)}
.ds-bartable__row:last-of-type{border-bottom:0}
.ds-bartable--grades .ds-bartable__head,.ds-bartable--grades .ds-bartable__row{
  grid-template-columns:150px minmax(0,1fr) 60px 64px}
.ds-bartable--dims .ds-bartable__head,.ds-bartable--dims .ds-bartable__row{
  grid-template-columns:minmax(0,1fr) 220px 70px}
.ds-bartable__num{text-align:right;font-family:var(--t7-mono);font-size:13px}
.ds-bartable__name{display:flex;flex-direction:column;gap:3px;min-width:0}
.ds-bartable__blurb{font-size:12px;color:var(--t7-muted)}
@media (max-width:640px){
  .ds-bartable__head{display:none}
  .ds-bartable--grades .ds-bartable__row,.ds-bartable--dims .ds-bartable__row{
    grid-template-columns:1fr;gap:6px;text-align:left}
  .ds-bartable__num{text-align:left}
}

.ds-verdict{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);
  border:1px solid var(--t7-warm-gray);margin:0 0 1.6rem}
.ds-verdict--problem,.ds-verdict--needs-work{border-color:var(--t7-coral)}
.ds-verdict--pass{border-color:var(--t7-warm-gray)}
.ds-verdict__cell{padding:28px 30px;display:flex;flex-direction:column;gap:13px}
.ds-verdict__cell--main{background:var(--t7-mimosa)}
.ds-verdict--pass .ds-verdict__cell--main{background:var(--t7-lilac)}
.ds-verdict__cell--aside{background:var(--t7-paper);gap:11px;
  border-left:1px solid var(--t7-warm-gray)}
.ds-verdict--problem .ds-verdict__cell--aside,
.ds-verdict--needs-work .ds-verdict__cell--aside{border-left-color:var(--t7-coral)}
.ds-verdict__sentence{margin:0;font-family:var(--t7-serif);font-size:clamp(22px,3.4vw,32px);
  line-height:1.18;text-wrap:pretty;color:var(--t7-dark-purple)}
.ds-verdict__body{margin:0;font-size:16px;line-height:1.6;max-width:560px;
  color:var(--t7-dark-purple)}
.ds-verdict__action{margin:0;font-size:15px;font-weight:600}
@media (max-width:760px){.ds-verdict{grid-template-columns:1fr}
  .ds-verdict__cell--aside{border-left:0;border-top:1px solid var(--t7-warm-gray)}}

.ds-panelpair{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  border:1px solid var(--t7-warm-gray);margin:0 0 1.6rem}
.ds-panelpair__cell{padding:24px 26px;display:flex;flex-direction:column;gap:10px}
.ds-panelpair__cell--white{background:var(--t7-paper)}
.ds-panelpair__cell--lilac{background:var(--t7-lilac);border-left:1px solid var(--t7-warm-gray)}
.ds-panelpair__cell--mimosa{background:var(--t7-mimosa);border-left:1px solid var(--t7-coral)}
.ds-panelpair__body{font-size:15px;line-height:1.6;color:var(--t7-dark-purple)}
@media (max-width:760px){.ds-panelpair{grid-template-columns:1fr}
  .ds-panelpair__cell--lilac,.ds-panelpair__cell--mimosa{border-left:0;
    border-top:1px solid var(--t7-warm-gray)}}

/* --- ScanCTA — one wide box, called from inside each public page's own
   <main> (never the home page, which already has its own hero form) so it
   sits inside that page's own card and shadow, not after it. The same
   white the home hero's card uses, not the paper tone the rest of a
   reference page sits on. --- */
/* The footer offer. Khaki with a rule along the top, so it reads as a band
   under the page rather than as the page's last section — which is how it read
   on /privacy and /terms, arriving with no heading straight after the final
   clause. */
.ds-scancta{border:0;border-top:1px solid var(--t7-warm-gray);
  background:var(--t7-khaki);padding:var(--t7-space-4) var(--t7-space-4)
  var(--t7-space-4);margin:var(--t7-space-5) 0 0;display:flex;
  flex-direction:column;gap:0.75rem;text-align:center}
.ds-scancta__head{margin:0;font-size:1.25rem;line-height:1.25;
  color:var(--t7-electric)}
.ds-scancta__lede{margin:0;font-size:var(--t7-step--1);color:var(--t7-dark-purple)}
.ds-scancta__label{font-size:var(--t7-step--1);font-weight:600;
  color:var(--t7-dark-purple)}
.ds-scancta__form-wrap{margin:0 auto;width:100%;max-width:620px;text-align:left}
/* The label sits above the row rather than inside it, so the input and the
   button keep their own line and both keep a 44px target. */
.ds-scancta .air-form--inline{flex-wrap:wrap}
.ds-scancta .air-form--inline input,
.ds-scancta .air-form--inline .btn{min-height:44px}

.ds-callout{border-radius:0;padding:16px 18px;margin:0 0 1.6rem;
  display:flex;flex-direction:column;gap:6px}
.ds-callout--warn{background:var(--t7-mimosa);border-left:var(--rail-width) solid var(--t7-coral)}
.ds-callout--note{background:var(--t7-lilac);border-left:var(--rail-width) solid var(--t7-electric)}
.ds-callout__title{margin:0;font-weight:600;font-size:16px;color:var(--t7-dark-purple)}
.ds-callout__body{font-size:15px;line-height:1.55;color:var(--t7-dark-purple)}

.ds-evidence{background:var(--evidence-bg);color:var(--evidence-ink-strong);
  padding:24px 26px;display:flex;flex-direction:column;gap:16px;height:100%}
.ds-evidence--paper{background:var(--t7-paper);color:var(--t7-dark-purple);
  border:1px solid var(--t7-warm-gray)}
.ds-evidence__body{display:flex;flex-direction:column;gap:16px}
.ds-evidence__url-block{display:flex;flex-direction:column;gap:6px}
.ds-evidence__source{font-family:var(--t7-sans);font-size:1.0625rem;font-weight:600;
  color:var(--evidence-ink-strong);line-height:1.45}
/* The source title is the link now, so it has to look like one. */
.ds-evidence__source a{color:inherit;text-decoration:underline;
  text-underline-offset:2px}
.ds-evidence__source a:hover{color:var(--t7-electric-2)}
.ds-evidence--paper .ds-evidence__source{color:var(--t7-dark-purple)}
.ds-evidence--paper .ds-evidence__source a{color:var(--t7-electric)}
.ds-evidence__url{font-family:var(--t7-mono);font-size:13px;word-break:break-all}
.ds-evidence__url a{color:var(--t7-lilac);text-decoration:underline}
.ds-evidence--paper .ds-evidence__url a{color:var(--t7-electric)}
.ds-evidence__urlnote{font-family:var(--t7-mono);font-size:12px;color:var(--evidence-ink)}
.ds-evidence__well{font-family:var(--t7-mono);font-size:13px;line-height:1.9;
  background:var(--evidence-well);padding:14px 16px;color:var(--evidence-ink);
  white-space:pre-wrap;overflow-wrap:anywhere}
.ds-evidence--paper .ds-evidence__well{background:#fff;border:1px solid var(--t7-warm-gray);
  color:var(--t7-muted)}
.ds-evidence__fix-block{display:flex;flex-direction:column;gap:8px}
.ds-evidence__fix{font-family:var(--t7-mono);font-size:13px;line-height:1.8;
  background:var(--evidence-well);border-left:3px solid var(--t7-coral);
  padding:12px 14px;color:var(--evidence-ink-strong);white-space:pre-wrap;
  overflow-wrap:anywhere}
.ds-evidence__metrics{display:flex;flex-wrap:wrap;gap:22px;padding-top:12px;
  border-top:1px solid var(--evidence-well)}
.ds-evidence--paper .ds-evidence__metrics{border-top-color:var(--t7-warm-gray)}
.ds-evidence__footer{display:flex;flex-wrap:wrap;gap:22px;padding-top:12px;
  margin-top:auto;border-top:1px solid var(--evidence-well)}
.ds-evidence--paper .ds-evidence__footer{border-top-color:var(--t7-warm-gray)}
.ds-evidence .ds-monostat,.ds-evidence .ds-monostat__v--ink{color:var(--evidence-ink)}
.ds-evidence .ds-monostat__v--ink{color:var(--evidence-ink-strong)}
.ds-evidence--paper .ds-monostat,.ds-evidence--paper .ds-monostat__v--ink{color:var(--t7-muted)}
.ds-evidence--paper .ds-monostat__v--ink{color:var(--t7-dark-purple)}

/* --------------------------------------------------------------- Layer 3: the check pattern */

/* --- CheckRow --- */
.ds-checkrow{border-bottom:1px solid var(--t7-warm-gray);background:var(--t7-paper)}
.ds-checkrow:last-child{border-bottom:0}
/* 48px floor on the row itself, not just its padding: a disclosure is a touch
   target and the audit's finding 06 puts the minimum at 44. */
.ds-checkrow__summary{display:grid;grid-template-columns:5.75rem 1fr auto;gap:20px;
  align-items:start;padding:16px 22px;cursor:pointer;list-style:none;
  min-height:48px;align-content:center}
.ds-checkrow__summary::-webkit-details-marker{display:none}
.ds-checkrow__summary::before{content:"\25b8";color:var(--t7-electric);
  position:absolute;margin-left:-.75rem;margin-top:-.05rem;font-size:1.4rem}
.ds-checkrow[open] .ds-checkrow__summary::before{content:"\25be"}
.ds-checkrow:hover{background:#fff}
.ds-checkrow--flat{display:grid;grid-template-columns:5.75rem 1fr auto;gap:20px;
  align-items:center;padding:12px 22px}
.ds-checkrow__id{font-family:var(--t7-mono);font-size:13px;color:var(--t7-muted);
  padding-top:2px}
.ds-checkrow__main{display:flex;flex-direction:column;gap:5px;min-width:0}
.ds-checkrow__question{font-weight:600;font-size:16px;line-height:1.35}
.ds-checkrow--flat .ds-checkrow__question{font-weight:500;font-size:15px}
.ds-checkrow__finding{font-size:14px;line-height:1.45;color:var(--t7-muted)}
.ds-checkrow__side{display:flex;align-items:center;gap:12px;white-space:nowrap}
.ds-checkrow--withpts.ds-checkrow__summary,
.ds-checkrow--withpts .ds-checkrow__summary,
.ds-checkrow--withpts.ds-checkrow--flat{grid-template-columns:5.75rem 4rem 1fr auto}
.ds-checkrow__weight{padding-top:1px;white-space:nowrap}
/* The points badge. A bordered object rather than a run of mono text, so the
   figure reads as its own field at a glance instead of trailing the id. */
.ds-pts{display:inline-block;font-family:var(--t7-label);font-weight:700;
  font-size:0.8125rem;letter-spacing:.04em;white-space:nowrap;
  padding:0.25rem 0.5rem;border:1px solid var(--t7-electric);
  color:var(--t7-electric);line-height:1.15}
/* Not a point value, so it does not borrow the point value's colour. */
.ds-pts--unscored{border-color:var(--t7-warm-gray);color:var(--t7-dark-purple)}

/* A zero-height target that only exists to give a second anchor id somewhere to
   land. `scroll-margin-top` keeps the row it names clear of the top edge. */
.ds-anchor{display:block;height:0;overflow:hidden;scroll-margin-top:var(--t7-space-5)}
.ds-checkrow{scroll-margin-top:var(--t7-space-5)}

/* Below this, the fixed id/points columns leave too little room for the
   question to read as a sentence — the id (and points, and the chip) move
   to their own compact row above the title instead of squeezing beside it. */
@media (max-width:640px){
  .ds-checkrow__summary,.ds-checkrow--flat{
    grid-template-columns:auto auto 1fr auto !important;
    grid-template-areas:"id weight . side" "main main main main";
    row-gap:6px}
  .ds-checkrow__id{grid-area:id}
  .ds-checkrow__weight{grid-area:weight}
  .ds-checkrow__main{grid-area:main}
  .ds-checkrow__side{grid-area:side;justify-self:end}
}

/* --- CheckPanel --- */
.ds-checkpanel{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);
  background:#fff;border-top:1px solid var(--t7-warm-gray)}
.ds-checkpanel__read{padding:24px 26px;display:flex;flex-direction:column;gap:18px;
  border-right:1px solid var(--t7-warm-gray);
  border-left:var(--rail-width) solid var(--status-problem-fill)}
.ds-checkpanel--needs-work .ds-checkpanel__read{border-left-color:var(--status-needs-border)}
.ds-checkpanel--pass .ds-checkpanel__read{border-left-color:var(--status-pass-mark)}
.ds-checkpanel__verdict{margin:0;font-weight:600;font-size:20px;line-height:1.3;
  text-wrap:pretty}
.ds-checkpanel__why{margin:0;font-size:15px;line-height:1.6}
.ds-checkpanel__move{display:flex;flex-direction:column;gap:8px;
  border-left:3px solid var(--t7-electric);padding-left:14px}
.ds-checkpanel__move p{margin:0;font-size:15px;line-height:1.6}
.ds-checkpanel__movelink{font-size:14px;font-weight:600}
@media (max-width:1000px){
  .ds-checkpanel{grid-template-columns:1fr}
  .ds-checkpanel__read{border-right:0;border-bottom:1px solid var(--t7-warm-gray)}
}

/* --- the four detail variants --- */
.ds-detail{display:flex;flex-direction:column;gap:8px}
.ds-detail__note{margin:0;font-size:13px;color:var(--t7-muted)}
.ds-detail__row{display:grid;grid-template-columns:auto 1fr auto;gap:12px;
  align-items:center;padding:9px 12px;background:var(--t7-paper);
  border:1px solid var(--t7-warm-gray)}
.ds-detail--signals .ds-detail__row{grid-template-columns:auto 1fr auto}
.ds-detail__what{font-size:14px;line-height:1.4}
.ds-detail--checklist .ds-detail__row{grid-template-columns:12px 1fr}
.ds-detail__mark{width:10px;height:10px}
.ds-detail__row--done{background:var(--t7-paper)}
.ds-detail__row--done .ds-detail__mark{background:var(--status-pass-mark)}
.ds-detail__row--missing{background:var(--status-needs-surface);
  border-color:var(--status-needs-border)}
.ds-detail__row--missing .ds-detail__mark{background:var(--status-problem-fill)}
.ds-detail--rubric .ds-detail__row{grid-template-columns:auto 1fr}
.ds-detail--bullets{list-style:none;margin:0;padding:0}
.ds-detail--bullets li{padding-left:1.1em;position:relative;font-size:14px;
  line-height:1.5;margin-bottom:.4rem}
.ds-detail--bullets li::before{content:"\2014";position:absolute;left:0;
  color:var(--t7-coral)}

/* --- BandGroup --- */
.ds-bandgroup{border:1px solid var(--t7-warm-gray);border-top:0;margin:0}
.ds-bandgroup:first-child{border-top:1px solid var(--t7-warm-gray)}
.ds-bandgroup__bar{display:flex;align-items:center;justify-content:space-between;
  gap:12px;padding:12px 22px;list-style:none;cursor:pointer}
.ds-bandgroup--problem .ds-bandgroup__bar,
.ds-bandgroup--needs-work .ds-bandgroup__bar{background:var(--status-needs-surface);
  cursor:default}
.ds-bandgroup--pass .ds-bandgroup__bar{background:var(--t7-lilac)}
.ds-bandgroup__bar::-webkit-details-marker{display:none}
.ds-bandgroup__label{display:flex;align-items:center;gap:10px;min-width:0}
.ds-bandgroup__marker{width:10px;height:10px;flex:0 0 auto;
  background:var(--status-pass-mark)}
.ds-bandgroup--problem .ds-bandgroup__marker{background:var(--status-problem-fill);
  border-radius:0}
.ds-bandgroup--needs-work .ds-bandgroup__marker{background:none;
  border:2px solid var(--status-ink)}
.ds-bandgroup__subtext{font-family:var(--t7-mono);font-size:12px;color:var(--status-ink)}
.ds-bandgroup__toggle{font-family:var(--t7-mono);font-size:12px;font-weight:700;
  color:var(--t7-electric)}
.ds-bandgroup__toggle::before{content:"show all"}
.ds-bandgroup[open] .ds-bandgroup__toggle::before{content:"hide"}

/* --- CheckList's dimension grouping (reference pages) --- */
.ds-dimsection{margin:0 0 var(--t7-space-5);scroll-margin-top:var(--t7-space-4)}
/* Number, name, count, points and share as five separate things. The old
   heading was one 20px serif string carrying all of them, which reads at a
   glance as a single run of text — the same collision the test rows had. */
.ds-dimsection__head{display:flex;align-items:baseline;gap:0.75rem;
  margin:0 0 0.35rem;font-family:var(--t7-sans)}
.ds-dimsection__num{font-family:var(--t7-mono);font-size:0.9375rem;
  color:var(--t7-muted);flex:0 0 auto}
.ds-dimsection__name{margin:0;font-size:var(--t7-step-2);line-height:1.2;
  color:var(--t7-dark-purple)}
.ds-dimsection__meta{margin:0 0 0.625rem;font-size:var(--t7-step--1);
  color:var(--t7-muted)}
/* The dimension's share of the hundred, drawn. Decorative — the figure is in
   the meta line above, so this is aria-hidden in the markup. */
.ds-dimsection__weight{height:8px;background:var(--t7-warm-gray);
  margin:0 0 var(--t7-space-3)}
.ds-dimsection__weight > span{display:block;height:100%;
  background:var(--t7-electric)}

/* --- DimensionBars --- */
.ds-dimbars{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 34px}
.ds-dimbars__row{display:grid;grid-template-columns:1fr 54px;gap:14px;
  align-items:center;padding:10px 0;border-bottom:1px solid var(--t7-warm-gray);
  text-decoration:none;color:inherit}
.ds-dimbars__row:hover{text-decoration:none}
.ds-dimbars__meta{display:flex;align-items:baseline;justify-content:space-between;
  gap:10px}
.ds-dimbars__name{font-weight:600;font-size:15px;color:var(--t7-dark-purple)}
.ds-dimbars .ds-sharebar{margin-top:6px}
.ds-dimbars__score{font-family:var(--t7-mono);font-size:15px;font-weight:700;
  text-align:right;color:var(--t7-dark-purple)}
@media (max-width:760px){.ds-dimbars{grid-template-columns:1fr}}

/* --- DimensionLedger --- */
.ds-ledger{border:1px solid var(--t7-warm-gray);background:var(--t7-paper)}
.ds-ledger__row{border-bottom:1px solid var(--t7-lilac)}
.ds-ledger__row:last-child{border-bottom:0}
.ds-ledger__row--head{display:grid;grid-template-columns:1fr 220px 92px 82px;
  gap:14px;padding:11px 18px;background:var(--t7-khaki);
  border-bottom:1px solid var(--t7-warm-gray);font-family:var(--t7-label);
  font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--t7-muted)}
.ds-ledger__row--head span:not(:first-child){text-align:right}
.ds-ledger__summary{display:grid;grid-template-columns:1fr 220px 92px 82px;
  gap:14px;align-items:center;padding:14px 18px;cursor:pointer;list-style:none}
.ds-ledger__summary::-webkit-details-marker{display:none}
.ds-ledger__name{display:flex;flex-direction:column;gap:3px}
.ds-ledger__title{font-weight:600;font-size:15px}
.ds-ledger__share{display:flex;flex-direction:column;gap:5px}
.ds-ledger__earned,.ds-ledger__score{text-align:right}
.ds-ledger__score{font-weight:700}
.ds-ledger__detail{padding:0 18px 18px}
@media (max-width:760px){
  .ds-ledger__row--head{display:none}
  .ds-ledger__summary{grid-template-columns:1fr;gap:6px}
  .ds-ledger__earned,.ds-ledger__score{text-align:left}
}

/* --- FixCards --- */
.ds-fixcard{display:grid;grid-template-columns:2.9rem 1fr 9.4rem;gap:20px;
  align-items:start;background:#fff;border:1px solid var(--t7-warm-gray);
  padding:18px 20px;margin-bottom:.9rem;text-decoration:none;color:inherit}
.ds-fixcard:hover{text-decoration:none;background:var(--t7-paper)}
.ds-fixcard--problem{border-left:var(--rail-width) solid var(--status-problem-fill)}
.ds-fixcard--needs-work{border-left:var(--rail-width) solid var(--status-needs-border)}
.ds-fixcard--pass{border-left:var(--rail-width) solid var(--status-pass-mark)}
.ds-fixcard__n{font-family:var(--t7-serif);font-size:30px;line-height:.9;
  color:var(--t7-electric)}
.ds-fixcard__body{display:flex;flex-direction:column;gap:6px;min-width:0}
.ds-fixcard__title{font-weight:600;font-size:17px;line-height:1.3}
.ds-fixcard__found{font-size:14px;line-height:1.5;color:var(--t7-muted)}
.ds-fixcard__do{font-size:15px;line-height:1.5}
.ds-fixcard__stat{display:flex;flex-direction:column;gap:4px;text-align:right}
.ds-fixcard__pts{font-family:var(--t7-serif);font-size:26px;line-height:1;
  color:var(--t7-dark-purple)}
@media (max-width:640px){.ds-fixcard{grid-template-columns:2rem 1fr}
  .ds-fixcard__stat{grid-column:1 / -1;flex-direction:row;text-align:left;
    gap:12px;align-items:baseline}}

/* --- FixHero — the sign-in gate flow's proof fix, always open, never
   collapsible. 2px purple border + a lilac block shadow so it reads as the
   one thing on the page nothing can take away. --- */
.ds-fixhero{border:2px solid var(--t7-electric);box-shadow:8px 8px 0 var(--t7-lilac);
  margin:0 0 28px;background:#fff}
.ds-fixhero__head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:10px;padding:12px 20px;background:var(--t7-electric);color:#fff;
  font-family:var(--t7-label);font-size:11px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase}
.ds-fixhero__pts{font-family:var(--t7-mono);letter-spacing:.04em}
.ds-fixhero .ds-checkpanel{border:0}

/* --- LockedList — held fixes. Rank/id/title/lock-strip/points on desktop;
   three lines on mobile. Consecutive rows share edges so the list reads as
   one held block, ending in a dark summary bar a locked list must never be
   without. --- */
.ds-lockedlist{border:1px solid var(--t7-warm-gray);border-top:0;margin:0 0 28px}
.ds-lockedrow{display:grid;grid-template-columns:40px 92px 1fr 260px 110px;
  gap:14px;align-items:center;background:var(--t7-paper);
  border:1px solid var(--t7-warm-gray);border-top:0;padding:12px 18px}
.ds-lockedrow__rank{font-family:var(--t7-serif);font-size:15px;color:var(--t7-muted)}
.ds-lockedrow__id{font-size:12px}
.ds-lockedrow__title{font-size:14.5px;line-height:1.4;color:var(--t7-dark-purple)}
.ds-lockedrow__evidence{display:inline-flex;align-items:center;gap:7px;
  background:var(--t7-khaki);border:1px dashed var(--t7-warm-gray);
  padding:6px 10px;font-family:var(--t7-mono);font-size:12px;letter-spacing:.06em;
  color:var(--t7-muted)}
.ds-lockedrow__lock{width:13px;height:10px;flex:0 0 auto;position:relative;
  border:1.5px solid var(--t7-lavender);border-radius:1px}
.ds-lockedrow__lock::before{content:"";position:absolute;left:2px;right:2px;
  bottom:100%;height:5px;border:1.5px solid var(--t7-lavender);border-bottom:0;
  border-radius:3px 3px 0 0}
.ds-lockedrow__pts{font-family:var(--t7-mono);font-weight:700;text-align:right;
  color:var(--t7-muted)}
.ds-lockedlist__foot{background:var(--t7-dark-purple);color:var(--t7-lilac);
  padding:12px 18px;text-align:center}
.ds-lockedlist__foot .ds-monostat{color:var(--t7-lilac)}
@media (max-width:640px){
  .ds-lockedrow{grid-template-columns:1fr auto;grid-template-areas:
    "rank pts" "title title" "evidence evidence";row-gap:6px}
  .ds-lockedrow__rank{grid-area:rank}
  .ds-lockedrow__id{display:none}
  .ds-lockedrow__title{grid-area:title}
  .ds-lockedrow__evidence{grid-area:evidence;width:100%;box-sizing:border-box}
  .ds-lockedrow__pts{grid-area:pts}
}

/* --- GateCard — sells the report, never the subscription: one CTA, one
   price line, provider marks for recognition only (not four separate
   actions — the button is the only door). --- */
.ds-gatecard{border:1px solid var(--t7-warm-gray);background:var(--t7-khaki);
  padding:26px 24px;display:flex;flex-direction:column;align-items:center;
  gap:14px;text-align:center;margin:0 0 28px}
.ds-gatecard__count{margin:0;font-family:var(--t7-serif);font-size:19px;
  color:var(--t7-dark-purple);max-width:32ch}
.ds-gatecard__providers{display:flex;gap:8px}
.ds-gatecard__mark{width:30px;height:30px;display:flex;align-items:center;
  justify-content:center;background:var(--t7-lilac);color:var(--t7-electric);
  font-family:var(--t7-label);font-weight:700;font-size:13px}
.ds-gatecard__cta{width:100%;max-width:360px}
.ds-gatecard__price{margin:0;font-family:var(--t7-mono);font-size:12.5px;
  line-height:1.75;color:var(--t7-muted)}

/* --- PlanCard + BillingToggle — the plan moment. Selected: 2px purple
   border, block shadow, purple header, coral button. Unselected: paper
   surface, warm-gray border, khaki header, outline button. A real radio
   group drives which price line each card shows (billing.js). --- */
.ds-billingtoggle{display:inline-flex;border:1px solid var(--t7-dark-purple);
  width:fit-content;margin:0 auto}
.ds-billingtoggle__seg{font-family:var(--t7-label);font-size:12px;
  letter-spacing:.04em;text-transform:uppercase;padding:8px 18px;border:0;
  background:transparent;color:var(--t7-dark-purple);cursor:pointer}
.ds-billingtoggle__seg.is-active{background:var(--t7-dark-purple);color:#fff}
.ds-billingtoggle__note{text-align:center;color:var(--t7-muted);margin:8px 0 18px}
.fs-monitoring__buy .ds-billingtoggle{border-color:var(--t7-lilac)}
.fs-monitoring__buy .ds-billingtoggle__seg{color:var(--t7-lilac)}
.fs-monitoring__buy .ds-billingtoggle__seg.is-active{background:var(--t7-lilac);
  color:var(--t7-dark-purple)}
.ds-plancards{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media (max-width:640px){.ds-plancards{grid-template-columns:1fr}}
.ds-plancard{border:1px solid var(--t7-warm-gray);background:var(--t7-paper);
  color:var(--t7-dark-purple);
  padding:20px;display:flex;flex-direction:column;gap:12px}
.ds-plancard--selected{border:2px solid var(--t7-electric);
  box-shadow:8px 8px 0 var(--t7-lilac)}
.ds-plancard__head{display:flex;align-items:center;justify-content:space-between;
  background:var(--t7-khaki);color:var(--t7-dark-purple);
  margin:-20px -20px 0;padding:14px 20px}
.ds-plancard--selected .ds-plancard__head{background:var(--t7-electric);color:#fff}
.ds-plancard__name{font-family:var(--t7-serif);font-size:18px}
.ds-plancard__flag{font-family:var(--t7-label);font-size:10px;letter-spacing:.08em;
  background:var(--t7-coral);color:var(--t7-dark-purple);padding:2px 8px}
.ds-plancard__price{margin:0;font-family:var(--t7-serif);font-size:28px;
  color:var(--t7-dark-purple)}
.ds-plancard__price .ds-monostat{font-size:12px;display:block;color:var(--t7-muted)}
.ds-plancard__rows{list-style:none;margin:0;padding:0;display:flex;
  flex-direction:column;gap:6px;font-size:13.5px}
.ds-plancard__rows li{display:flex;justify-content:space-between;
  border-bottom:1px solid var(--t7-warm-gray);padding-bottom:6px}
.ds-plancard__rows li span:first-child{color:var(--t7-muted)}
.ds-plancard__rows li span:last-child{font-family:var(--t7-mono);font-weight:700;
  color:var(--t7-dark-purple)}
.ds-plancard__form{margin:0}
.ds-plancard__cta{width:100%}
.ds-plancard__foot{margin:0;font-size:12.5px;color:var(--t7-muted);text-align:center}
/* While billing is off. The button stays in place and stays legible — the
   tier is still being offered, just not yet sold — so it reads as "not
   available at the moment" rather than as a control that failed. */
.ds-plancard__cta:disabled{opacity:.45;cursor:not-allowed}
.ds-plancard__cta:disabled:hover{background:inherit;color:inherit}
.ds-plancard__soon{margin:-4px 0 0;font-family:var(--t7-mono);font-size:11.5px;
  letter-spacing:.06em;text-transform:uppercase;color:var(--t7-muted);
  text-align:center}
.ds-myplan{border:1px solid var(--t7-warm-gray);background:var(--t7-khaki);
  padding:20px 22px;margin:0 0 26px;display:flex;flex-direction:column;gap:10px}
.ds-myplan .ds-planpicker{margin-top:8px}

/* --- CrawlLog --- */
.ds-crawllog__anomalies{display:flex;flex-direction:column;gap:6px;margin-bottom:.8rem}
.ds-crawllog__row{display:grid;grid-template-columns:5rem 1fr auto;gap:14px;
  align-items:baseline;padding:8px 12px;background:var(--t7-paper);
  border:1px solid var(--t7-warm-gray);font-size:13.5px}
.ds-crawllog__url{font-family:var(--t7-mono);word-break:break-all}
.ds-crawllog__note{color:var(--t7-muted);font-size:13px}
.ds-crawllog__clean summary{cursor:pointer;font-family:var(--t7-mono);font-size:13px;
  color:var(--t7-muted);list-style:none;padding:.4rem 0}
.ds-crawllog__clean summary::-webkit-details-marker{display:none}
.ds-crawllog__clean summary::before{content:"\25b8 "}
.ds-crawllog__clean[open] summary::before{content:"\25be "}
.ds-crawllog__templates{display:flex;flex-direction:column;gap:6px;padding-top:.4rem}

/* --- ProvenanceReceipt --- */
.ds-receipt{margin:0;display:grid;grid-template-columns:11rem minmax(0,1fr);
  gap:.35rem 1rem;font-size:14px;background:var(--t7-khaki);padding:1rem 1.2rem}
.ds-receipt dt{font-family:var(--t7-mono);text-transform:uppercase;
  letter-spacing:.07em;font-size:10px;color:var(--t7-muted);padding-top:.25rem}
.ds-receipt dd{margin:0;color:var(--t7-dark-purple)}
.ds-receipt__note{font-size:13px;color:var(--t7-muted);margin:.6rem 0 0}
@media (max-width:640px){.ds-receipt{grid-template-columns:1fr}
  .ds-receipt dd{margin:0 0 .6rem}}

/* ================================================================ full-scan
   The saved-scan destination (web/templates/full-scan.html), built to the
   design handoff's own rendered reference. Unlike every other page it is a
   single bordered 1120px card whose bands each carry their own background,
   rather than one .card of running content. */
.fs{max-width:1120px;margin:4vh auto;background:var(--t7-paper);
  border:1px solid rgba(29,4,70,.12)}
.fs-band{padding:32px 40px;border-bottom:1px solid var(--t7-warm-gray)}
.fs-band--paper{background:var(--t7-paper)}
.fs-band--khaki{background:var(--t7-khaki)}
.fs-band--lilac{background:var(--t7-lilac);border-bottom-color:#D6CCF5}
.fs-band--mimosa{background:var(--t7-mimosa)}
.fs-band--purple{background:var(--t7-medium);color:#fff;border-bottom:0}

.fs-eyebrow{margin:0;font-family:var(--t7-label);font-size:12px;font-weight:600;
  letter-spacing:.06em;text-transform:uppercase;color:var(--t7-muted)}
/* Coral is a fill and a rule in this palette, not an ink: as text on paper it
   reads 1.95:1, which fails at any size. The warm tone is kept — --air-warn is
   the same family two shades down — and clears 5.74. */
.fs-eyebrow--coral{color:var(--air-warn)}
.fs-eyebrow--electric{color:var(--t7-electric)}
/* `currentColor`, not a named ink: this link sits inside an eyebrow that is
   coral on paper and --t7-coral on purple, and any fixed colour would fail one
   of those two. Underlined because colour alone is then the only thing left
   separating it from the words beside it, and colour alone is not a signal. */
.fs-eyebrow__link{color:currentColor;text-decoration:underline;
  text-underline-offset:2px}

/* --- buttons, matching the reference's two treatments --- */
.fs-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;
  font-family:var(--t7-sans);font-weight:600;font-size:16px;line-height:1;
  padding:12px 24px;border:2px solid var(--t7-electric);border-radius:3px;
  background:transparent;color:var(--t7-electric);text-decoration:none;cursor:pointer}
.fs-btn--sm{padding:8px 16px;font-size:14px}
.fs-btn--lg{padding:16px 32px;font-size:17px}
/* Bright orange on deep purple: 6.95:1 against #1D0446, and the only element on
   that band carrying any saturation, so it is unambiguously the thing to click. */
.fs-btn--orange{background:#FF7A1A;border-color:#FF7A1A;color:#1D0446;font-weight:700;
  padding:16px 32px;font-size:17px}
.fs-btn--orange:hover{background:#FF9040;border-color:#FF9040;color:#1D0446;
  text-decoration:none}
.fs-btn--primary{background:var(--t7-medium);border-color:var(--t7-medium);color:#fff}
.fs-pricecard .fs-btn{width:100%}
.fs-btn--primary:hover{background:var(--t7-dark-purple);border-color:var(--t7-dark-purple);
  color:#fff;text-decoration:none}
.fs-btn--outline:hover{background:var(--t7-electric);color:#fff;text-decoration:none}

.fs-header{padding:18px 40px}
.fs-header .topbar{margin-bottom:0}
.fs-stale{padding:16px 40px;font-size:14.5px;line-height:1.5;color:var(--t7-dark-purple)}

/* --- welcome banner --- */
.fs-welcome{display:flex;align-items:flex-start;gap:16px;padding:18px 40px}
.fs-welcome__mark{flex:none;width:26px;height:26px;background:var(--t7-medium);
  border-radius:4px;color:#fff;display:flex;align-items:center;justify-content:center;
  font-weight:700;font-size:14px}
.fs-welcome__body{flex:1}
.fs-welcome__lede{font-weight:600;font-size:16px;color:var(--t7-dark-purple)}
.fs-welcome__note{font-size:14px;line-height:1.5;color:var(--t7-dark-purple);margin-top:3px}
.fs-welcome__dismiss{flex:none;appearance:none;background:none;border:0;cursor:pointer;
  font-size:18px;line-height:1;color:var(--t7-muted);padding:13px;margin:-13px}
.fs-welcome__dismiss:hover{color:var(--t7-electric)}

/* --- census meta banner: the gate/TLS warning and the identifying line
   (URL, rank, pages, tests, date) that used to sit in the old ds-hero
   layout's orange callout and the plain text just below it, now one lilac
   band read before the score rather than beside it --- */
.fs-meta{padding:16px 40px;font-size:14.5px;line-height:1.5;color:var(--t7-dark-purple)}
.fs-meta > p + p{margin-top:10px}
.fs-meta__line{font-family:var(--t7-mono);font-size:13px;color:var(--t7-muted)}

/* --- identity + score --- */
.fs-identity{padding:34px 40px 26px}
.fs-identity__row{display:flex;justify-content:space-between;align-items:flex-start;gap:40px}
/* Shared with the first contact scan's header — see result.html. One
   declaration rather than two, because two is how that page ended up printing
   the domain in purple sans while this one printed it in dark serif. */
/* 80% of the size it was. A domain is the one string on this page nobody
   chose the length of — give.animalhumanesociety.org wrapped onto a second
   line at 52px and took the scanned-at line with it. Every report header
   reads this rule, the first contact scan's included. */
.fs-identity__domain{margin:8px 0 6px;font-family:var(--t7-serif);font-weight:400;
  font-size:clamp(26px,4vw,42px);letter-spacing:-.01em;color:var(--t7-dark-purple);
  word-break:break-word}
.fs-identity__scanned{margin:0;font-weight:600;font-size:15px;color:var(--t7-dark-purple)}
.fs-identity__score{text-align:right;flex:none}
.fs-identity__num{margin:4px 0 0;font-family:var(--t7-serif);font-weight:400;font-size:66px;
  line-height:1;color:var(--t7-dark-purple)}
.fs-identity__num span{font-family:var(--t7-mono);font-size:24px;color:var(--t7-muted)}
.fs-identity__stats{margin:6px 0 0;font-weight:600;font-size:13px;color:var(--t7-dark-purple)}
/* Sits in the eyebrow beside "Your score", above the number, so the way to
   check the figure is offered before the figure itself. It inherits the
   eyebrow's family, size, tracking and uppercasing — only the colour and the
   underline mark it as the one part of that line you can click. */
.fs-identity__rescan{color:var(--t7-electric);text-decoration:underline;
  text-underline-offset:3px;white-space:nowrap}
.fs-identity__rescan:hover{color:var(--t7-dark-purple)}
.fs-identity__math{color:var(--t7-electric);text-decoration:underline;
  text-underline-offset:3px;white-space:nowrap}
.fs-identity__math:hover{color:var(--t7-dark-purple)}

/* "Scan again" and the site-type field share one flex row, both using the
   same button style so they read as one set of controls. The row holds two
   separate <form> elements; display:contents on each makes their controls
   direct flex children, so gap and alignment are inherited from the row
   rather than needing a separate wrapper. */
.fs-identity__again{display:flex;align-items:center;gap:12px;margin-top:12px;flex-wrap:wrap}
.fs-identity__again form{display:contents}
.fs-identity__againbtn{font-family:var(--t7-label);font-weight:600;font-size:13px;
  letter-spacing:.06em;text-transform:uppercase;color:var(--t7-dark-purple);
  background:transparent;border:1.5px solid var(--t7-dark-purple);border-radius:2px;
  padding:9px 16px 7px;cursor:pointer}
.fs-identity__againbtn:hover{background:var(--t7-dark-purple);color:#fff}
.fs-identity__againnote{font-weight:600;font-size:13px;color:var(--t7-muted)}
/* 1px × 24px warm-gray rule between Scan Again and the site-type controls. */
.fs-identity__divider{width:1px;height:24px;background:var(--t7-warm-gray);align-self:center}
/* The site-type select inherits fs-identity__againbtn for height/border/font.
   appearance:none removes the OS chrome; a dark-purple caret drawn as an SVG
   replaces it, with enough right padding to keep selected text clear of it. */
select.fs-identity__againsel{appearance:none;-webkit-appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%231D0446' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 10px center;
  background-size:10px 7px;padding-right:28px}

.fs-scorebar{margin-top:30px}
/* The two-segment label row above the bar on the Primary Indicators page.
   Above, not below: the labels say what the two regions of the bar *are*, and
   a reader meets them on the way down to it rather than after having already
   guessed. Below the bar is where the band names used to sit, which is the
   reading this page exists to avoid. */
.fs-scorebar__segments{display:flex;margin-bottom:6px;font-family:var(--t7-label);
  font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;
  color:var(--t7-dark-purple)}
.fs-scorebar__segment{display:block;padding-left:6px;
  border-left:1px solid var(--t7-warm-gray);white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.fs-scorebar__segment.is-untested{color:var(--t7-muted)}
/* At 375px "Primary Indicators" is wider than 28% of the bar. The label wins
   over the alignment: a truncated word says less than a label that has moved
   a few pixels off its own segment. */
@media (max-width:560px){
  .fs-scorebar__segments{font-size:10px;letter-spacing:.06em}
  .fs-scorebar__segment{overflow:visible;flex:0 0 auto;min-width:0}
  .fs-scorebar__segment.is-untested{margin-left:auto;padding-left:0;
    border-left:0;text-align:right}
}
.fs-scorebar__pillrow{position:relative;height:22px}
.fs-scorebar__pill{position:absolute;transform:translateX(-50%);background:var(--t7-medium);
  color:#fff;font-weight:600;font-size:12px;padding:3px 8px;border-radius:3px;white-space:nowrap}
.fs-scorebar__track{position:relative;height:14px;border:1px solid var(--t7-dark-purple);
  display:flex}
.fs-scorebar__earned{background:var(--t7-dark-purple)}
.fs-scorebar__band{background:var(--t7-lilac)}
.fs-scorebar__rest{flex:1;background:var(--t7-paper)}
.fs-scorebar__tick{position:absolute;top:0;width:1px;height:5px;background:var(--t7-warm-gray)}
.fs-scorebar__tick.is-tall{height:9px}
.fs-scorebar__marker{position:absolute;top:0;width:2px;height:12px;background:var(--t7-coral)}
.fs-scorebar__bands{position:relative;height:38px;margin-top:6px;
  border-top:2px solid var(--t7-coral)}
.fs-scorebar__bandlabel{position:absolute;top:8px;padding-left:6px;
  border-left:1px solid var(--t7-warm-gray)}
.fs-scorebar__bandname{display:block;font-family:var(--t7-mono);font-size:12px;font-weight:500;
  letter-spacing:.08em;color:var(--t7-muted);white-space:nowrap}
.fs-scorebar__bandlabel.is-active .fs-scorebar__bandname{color:var(--t7-dark-purple)}
.fs-scorebar__bandrange{display:block;font-family:var(--t7-mono);font-size:12px;
  color:var(--t7-muted)}
.fs-scorebar__scope{margin:10px 0 0;font-weight:600;font-size:13px;color:var(--t7-dark-purple);
  border-left:2px dashed var(--t7-dark-purple);padding-left:10px}

/* --- verdict --- */
.fs-verdict{padding:32px 40px 30px}
.fs-verdict h2{margin:10px 0 8px;font-family:var(--t7-serif);font-weight:400;
  font-size:clamp(26px,4vw,36px);color:var(--t7-dark-purple)}
.fs-verdict__body{margin:0;max-width:760px;font-weight:600;font-size:15px;line-height:1.6;
  color:var(--t7-dark-purple)}

/* --- the inline upgrade strip --- */
.fs-strip{display:flex;align-items:center;justify-content:space-between;gap:36px;
  padding:34px 40px}
.fs-band--deep{background:var(--t7-dark-purple);color:#fff;
  border-bottom-color:rgba(255,255,255,.18)}
.fs-strip__body{flex:1;min-width:min(380px,100%)}
.fs-strip__lede{margin:0;font-family:var(--t7-serif);font-weight:600;font-size:24px;
  line-height:1.25;color:#fff}
.fs-strip__sub{margin:8px 0 0;font-size:15px;line-height:1.55;color:var(--t7-lilac)}


/* --- top three quick wins --- */
.fs-wins{padding:32px 40px 34px}
.fs-wins__head{display:flex;align-items:baseline;justify-content:space-between;gap:20px}
.fs-wins__head h2{margin:8px 0 0;font-family:var(--t7-serif);font-weight:400;
  font-size:clamp(24px,3.6vw,32px);color:var(--t7-dark-purple)}
.fs-wins__note{margin:0;font-family:var(--t7-mono);font-size:12px;color:var(--t7-muted)}
.fs-wins__grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-top:22px}
.fs-wincard{background:var(--t7-khaki);border-left:5px solid var(--t7-coral);
  padding:20px 20px 22px;display:flex;flex-direction:column;gap:8px}
.fs-wincard__top{display:flex;align-items:baseline;justify-content:space-between}
.fs-wincard__rank{font-family:var(--t7-serif);font-size:34px;line-height:1;
  color:var(--air-warn)}
.fs-wincard__pts{border:1px solid var(--t7-coral);background:var(--t7-paper);padding:4px 10px;
  font-weight:600;font-size:15px;color:var(--t7-dark-purple)}
.fs-wincard__meta{margin:0;font-family:var(--t7-mono);font-size:12px;color:var(--t7-muted)}
.fs-wincard__title{margin:0;font-weight:600;font-size:17px;line-height:1.3;
  color:var(--t7-dark-purple)}
.fs-wincard__found{margin:0;font-size:13.5px;line-height:1.5;color:var(--t7-muted)}
.fs-wincard__do{margin:auto 0 0;font-weight:600;font-size:13.5px;line-height:1.5;
  color:var(--t7-dark-purple);border-top:1px solid var(--t7-warm-gray);padding-top:10px}

/* --- the work queue --- */
.fs-queue{padding:32px 40px 36px;border-bottom:0}
.fs-queue__head{display:flex;align-items:baseline;justify-content:space-between;
  border-bottom:1px solid var(--t7-warm-gray);padding-bottom:10px}
.fs-queue__head-right{display:flex;align-items:baseline;gap:12px}
.fs-queue__count{margin:0;font-family:var(--t7-mono);font-size:12px;color:var(--t7-muted)}
.fs-queue__filters{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:16px}
.fs-chip{font-family:var(--t7-mono);font-size:11.5px;font-weight:500;letter-spacing:.06em;
  padding:8px 13px;border:1px solid var(--t7-warm-gray);background:var(--t7-paper);
  color:var(--t7-dark-purple);text-decoration:none;white-space:nowrap}
.fs-chip:hover{border-color:var(--t7-electric);color:var(--t7-electric);text-decoration:none}
.fs-chip.is-active,
.fs-chip[aria-pressed="true"]{background:var(--t7-dark-purple);
  border-color:var(--t7-dark-purple);color:#fff;font-weight:700}
.fs-chip[aria-pressed="true"]:hover{background:var(--t7-dark-purple);
  border-color:var(--t7-dark-purple);color:#fff}
.fs-chip[aria-pressed="true"]::before{content:"\2713\00a0"}
/* Expand all/Collapse all is a label change, not a selection — the checkmark
   and the filled-in background belong to the filter chips beside it, which
   stay pressed until you pick something else; this button's own state is
   already carried by its text. */
.fs-chip[data-expand-all][aria-pressed]{background:var(--t7-paper);
  border-color:var(--t7-warm-gray);color:var(--t7-dark-purple);font-weight:500}
.fs-chip[data-expand-all][aria-pressed]:hover{background:var(--t7-paper);
  border-color:var(--t7-electric);color:var(--t7-electric)}
.fs-chip[data-expand-all]::before{content:none}

.fs-dim{margin-top:26px}
.fs-dim__head{display:flex;align-items:center;justify-content:space-between;gap:20px;
  width:100%;text-align:left;padding:13px 18px;border:0;
  border-left:5px solid var(--t7-lavender);background:var(--t7-khaki);cursor:pointer;
  font-family:inherit}
.fs-dim__head--lilac{background:var(--t7-lilac)}
.fs-dim__head--khaki{background:var(--t7-khaki)}
.fs-dim__head--mimosa{background:var(--t7-mimosa)}
.fs-dim__head--rail-electric{border-left-color:var(--t7-electric)}
.fs-dim__head--rail-medium{border-left-color:var(--t7-medium)}
.fs-dim__head--rail-lavender{border-left-color:var(--t7-lavender)}
.fs-dim__head--rail-coral{border-left-color:var(--t7-coral)}
.fs-dim__head:hover .fs-dim__title{color:var(--t7-electric)}
.fs-dim__title{font-family:var(--t7-sans);font-weight:600;font-size:17px;
  letter-spacing:0;color:var(--t7-dark-purple)}
.fs-dim__right{display:flex;align-items:center;gap:12px;white-space:nowrap}
.fs-dim__scored{font-family:var(--t7-mono);font-weight:600;font-size:14px;
  color:var(--t7-dark-purple)}
.fs-dim__caret{font-size:.85em;color:var(--t7-electric);transition:transform .12s ease}
.fs-dim__head[aria-expanded="false"] .fs-dim__caret{transform:rotate(-90deg)}
.fs-dim__head[aria-expanded="false"] + .fs-dim__rows{display:none}

/* A row is a disclosure, the same pattern the first-contact page uses: the
   summary is the line you scan, the panel under it is what we saw and what
   to do about it. */
.fs-row{border-bottom:1px solid #E4DDD6}
.fs-row[hidden]{display:none}
.fs-row--pass > .fs-row__summary{background:rgba(244,238,233,.6)}
.fs-row__summary{display:flex;align-items:flex-start;gap:18px;padding:14px 18px;
  cursor:pointer;list-style:none}
.fs-row__summary::-webkit-details-marker{display:none}
.fs-row__summary::before{content:"\25b8";position:absolute;margin-left:-13px;
  margin-top:1px;color:var(--t7-electric);font-size:1.1rem;line-height:1}
.fs-row[open] > .fs-row__summary::before{content:"\25be"}
.fs-row__summary:hover{background:#fff}
.fs-row--flat > .fs-row__summary{cursor:default}
.fs-row--flat > .fs-row__summary::before{content:none}
.fs-row--flat > .fs-row__summary:hover{background:none}
.fs-row--flat.fs-row--pass > .fs-row__summary:hover{background:rgba(244,238,233,.6)}
.fs-row[open] > .fs-row__summary{background:#fff}
.fs-row__id{flex:none;width:76px;font-family:var(--t7-mono);font-size:12px;
  color:var(--t7-muted);padding-top:2px}
.fs-row__main{flex:1;min-width:0}
.fs-row__question{display:block;font-weight:600;font-size:15px;color:var(--t7-dark-purple)}
.fs-row__finding{display:block;font-size:13.5px;line-height:1.5;color:var(--t7-muted);
  margin-top:2px}
.fs-row__chip{flex:none;font-family:var(--t7-mono);font-size:11px;font-weight:500;
  letter-spacing:.08em;padding:4px 8px;border:1px solid var(--t7-warm-gray);
  background:var(--t7-khaki);color:var(--t7-muted);white-space:nowrap}
.fs-row__chip--problem{background:var(--t7-mimosa);border-color:var(--t7-coral);
  color:var(--t7-dark-purple)}
.fs-row__chip--needs{background:var(--t7-lilac);border-color:var(--t7-electric);
  color:var(--t7-dark-purple)}
.fs-row__chip--unscored,.fs-row__chip--na{background:var(--t7-paper)}
.fs-row__pts{flex:none;width:44px;text-align:right;font-weight:600;font-size:14px;
  color:var(--t7-dark-purple)}
/* The shared CheckPanel, sitting inside a queue row rather than its own card. */
.fs-row .ds-checkpanel{border-top:1px solid var(--t7-warm-gray)}

/* --- monitoring --- */
.fs-monitoring{display:flex;gap:44px;align-items:flex-start;flex-wrap:wrap;
  padding:42px 40px 46px}
.fs-monitoring__pitch{flex:1;min-width:min(420px,100%)}
.fs-monitoring h2{margin:12px 0 10px;font-family:var(--t7-serif);font-weight:400;
  font-size:clamp(28px,4vw,38px);color:#fff;max-width:520px}
.fs-monitoring__lede{margin:0 0 20px;font-size:16px;line-height:1.6;color:var(--t7-lilac);
  max-width:560px}
.fs-money{display:flex;gap:14px;align-items:flex-start;max-width:560px;
  border-top:1px solid rgba(236,230,255,.35);padding-top:18px}
.fs-money__tag{flex:none;font-family:var(--t7-mono);font-size:11.5px;font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;color:var(--t7-coral);
  border:1px solid var(--t7-coral);padding:5px 8px}
.fs-money p{margin:0;font-size:14.5px;line-height:1.55;color:var(--t7-lilac)}

.fs-pricecard{flex:none;width:346px;background:var(--t7-paper);color:var(--t7-dark-purple);
  border:1px solid var(--t7-dark-purple);box-shadow:8px 8px 0 var(--t7-coral);padding:24px}
.fs-pricecard__price{margin:10px 0 0;font-family:var(--t7-serif);font-weight:400;font-size:40px;
  line-height:1}
.fs-pricecard__price span{font-family:var(--t7-mono);font-size:14px;color:var(--t7-muted)}
.fs-pricecard__list{display:flex;flex-direction:column;gap:8px;margin:14px 0 16px;
  font-weight:600;font-size:14.5px;line-height:1.4}
.fs-pricecard__more{border-top:1px solid var(--t7-warm-gray);padding-top:14px;
  margin-bottom:18px;font-weight:600;font-size:14.5px;line-height:1.45}
.fs-pricecard__more strong{color:var(--t7-electric)}
.fs-pricecard__foot{margin:12px 0 0;font-size:12.5px;line-height:1.5;color:var(--t7-muted)}
.fs-pricecard form{margin:0}

/* --- the report, while the crawl behind it is still running --- */
.fs-pending{padding:32px 40px 40px;border-bottom:0}
.fs-pending h2{margin:8px 0 18px;font-family:var(--t7-serif);font-weight:400;
  font-size:clamp(24px,3.4vw,30px);color:var(--t7-dark-purple)}

/* --- the Stripe plan picker, on the page rather than a click away --- */
.fs-plans{padding:32px 40px 38px}
.fs-plans__head h2{margin:8px 0 18px;font-family:var(--t7-serif);font-weight:400;
  font-size:clamp(24px,3.4vw,30px);color:var(--t7-dark-purple)}

/* --- agency --- */
.fs-agency{display:flex;align-items:center;justify-content:space-between;gap:30px;
  padding:26px 40px;border-bottom:0;border-top:1px solid #D6CCF5}
.fs-agency > div{max-width:720px}
.fs-agency__lede{margin:8px 0 0;font-weight:600;font-size:18px;color:var(--t7-dark-purple)}
.fs-agency__body{margin:4px 0 0;font-size:14.5px;line-height:1.6;color:var(--t7-dark-purple)}

@media (max-width:1040px){
  .fs-monitoring{gap:28px}
  .fs-pricecard{width:100%}
}
@media (max-width:860px){
  .fs-wins__grid{grid-template-columns:1fr}
}
@media (max-width:760px){
  .fs{margin:0 auto;border-left:0;border-right:0}
  .fs-band,.fs-header,.fs-identity,.fs-verdict,.fs-wins,.fs-queue,.fs-strip,
  .fs-welcome,.fs-agency,.fs-monitoring,.fs-stale,.fs-meta{padding-left:20px;padding-right:20px}
  .fs-identity__row{flex-direction:column;gap:14px}
  .fs-identity__score{text-align:left}
  .fs-strip,.fs-agency{flex-direction:column;align-items:flex-start}
  .fs-wins__head{flex-direction:column;gap:6px}
  /* Five band labels at their own range start collide on a narrow track —
     the active band is the fact that matters, so only it stays. */
  .fs-scorebar__bandlabel{display:none}
  .fs-scorebar__bandlabel.is-active{display:block;left:0 !important}
  /* The flex container is the summary, not the <details> around it. With the
     wrap on the wrong element `flex:1 0 100%` forced a full-width child onto a
     line that could not break, and the page scrolled sideways on every phone. */
  .fs-row__summary{flex-wrap:wrap;gap:8px 12px}
  .fs-row__main{flex:1 0 100%;order:3}
  .fs-row__chip{order:2}
  .fs-row__pts{order:1;width:auto;margin-left:auto}
}

/* The shared score scale on the First contact page. The component is the
   report's; only the zone past what one page can reach is new, and it is
   hatched rather than merely pale so "we did not look here" cannot be misread
   as "you scored nothing here". */
.fs-scorebar__unreachable{position:absolute;top:0;bottom:0;
  background:repeating-linear-gradient(135deg,
    rgba(99,85,121,.16) 0 4px, transparent 4px 8px);
  pointer-events:none}
.qr-head .fs-scorebar{margin-top:22px}

/* ------------------------------------------------------------- crawled URLs */
/* The scan's receipt. Collapsed by default because it is evidence, not a
   finding — but on the page, because "10 pages" is the one number on a report
   that a reader otherwise has to take on faith. The caret leads the label and
   turns to point down as it opens, so the control reads as a disclosure before
   it is clicked rather than only after. */
.fs-crawled{padding:0}
.fs-crawled__summary{display:flex;align-items:center;gap:10px;padding:16px 40px;
  cursor:pointer;list-style:none}
.fs-crawled__summary::-webkit-details-marker{display:none}
.fs-crawled__summary:hover{background:rgba(95,47,225,.05)}
.fs-crawled__summary:focus-visible{outline:2px solid var(--t7-electric);outline-offset:-2px}
.fs-crawled__caret{font-size:10px;color:var(--t7-muted);transition:transform .15s ease}
.fs-crawled__wrap[open] .fs-crawled__caret{transform:rotate(90deg)}
.fs-crawled__count{font-family:var(--t7-mono);font-size:12px;font-weight:600;
  letter-spacing:.06em;text-transform:uppercase;color:var(--t7-dark-purple)}
/* One flowing row of chips rather than a column: ten short paths read faster
   side by side, and the wrap keeps a deep crawl from pushing the queue off the
   first screen. */
.fs-crawled__list{list-style:none;display:flex;flex-wrap:wrap;gap:6px;
  margin:0;padding:0 40px 20px 62px;max-height:260px;overflow-y:auto}
.fs-crawled__url{display:inline-block;padding:4px 10px;
  border:1px solid var(--t7-warm-gray);border-radius:3px;background:var(--t7-paper);
  font-family:var(--t7-mono);font-size:12px;line-height:1.5;
  color:var(--t7-muted);text-decoration:none;word-break:break-all}
.fs-crawled__url:hover{border-color:var(--t7-electric);color:var(--t7-electric);
  background:#fff;text-decoration:none}

@media (max-width:640px){
  .fs-crawled__summary{padding:14px 16px}
  .fs-crawled__list{padding:0 16px 16px 16px}
}

/* --------------------------------------------- the picker on the purple band */
.fs-monitoring__buy{flex:none;width:min(560px,100%)}
.fs-eyebrow--onpurple{color:var(--t7-coral)}
.fs-monitoring__foot{margin:14px 0 0;font-size:13px;color:var(--t7-lilac)}
/* The picker's own cards are light objects; on this band they sit on purple, so
   only the frame changes — the cards keep the treatment they have everywhere. */
.fs-monitoring__buy .ds-planpicker{margin-top:12px}
.fs-monitoring__buy .ds-billingtoggle__note{color:var(--t7-lilac)}

/* ---------------------------------------------------------- rounding note */
/* The disclaimer at the bottom of every scan. Deliberately quiet — it is a
   footnote, not a warning — but never behind a disclosure, because the
   discrepancy it explains is visible on the page above it. */
.ds-roundingnote{max-width:none;margin:0;padding:0;color:var(--t7-muted);
  font-size:12px;line-height:1.45}
.ds-roundingnote strong{color:var(--t7-dark-purple)}

/* ------------------------------------------------------ the arithmetic page */
.fs-math{padding:40px}
.fs-math h2{margin:0 0 10px;font-family:var(--t7-serif);font-size:26px;
  color:var(--t7-dark-purple)}
.fs-math__lede{max-width:62ch;color:var(--t7-muted);font-size:15px;line-height:1.6}
.fs-math__sums{display:grid;gap:12px;margin:28px 0;padding:24px;
  border:1px solid var(--t7-warm-gray);background:var(--t7-paper)}
.fs-math__sums>div{display:flex;justify-content:space-between;align-items:baseline;
  gap:24px}
.fs-math__sums dt{color:var(--t7-muted);font-size:14px}
.fs-math__sums dd{margin:0}
.fs-math__num{font-family:var(--t7-mono);font-variant-numeric:tabular-nums;
  font-size:17px;color:var(--t7-dark-purple)}
.fs-math__num--big{font-size:34px;font-weight:600}
.fs-math__note{margin:28px 0;padding:24px;border-left:4px solid var(--t7-coral);
  background:var(--t7-mimosa)}
.fs-math__note h3{margin:0 0 8px;font-size:17px;color:var(--t7-dark-purple)}
.fs-math__note p{margin:0 0 10px;max-width:68ch;font-size:14px;line-height:1.6;
  color:var(--t7-dark-purple)}
.fs-math__note p:last-child{margin-bottom:0}
.fs-math__tablewrap{overflow-x:auto;margin:20px 0}
.fs-math__table{width:100%;border-collapse:collapse;font-size:14px}
.fs-math__table th,.fs-math__table td{padding:8px 12px;
  border-bottom:1px solid var(--t7-warm-gray);text-align:left;vertical-align:top}
.fs-math__table .num{text-align:right;font-variant-numeric:tabular-nums}
.fs-math__table thead th{border-bottom:2px solid var(--t7-dark-purple);
  font-family:var(--t7-mono);font-size:11px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--t7-muted)}
.fs-math__table tfoot th,.fs-math__table tfoot td{
  border-top:2px solid var(--t7-dark-purple);border-bottom:none;font-weight:600}
.fs-math__table tbody th{font-weight:600;color:var(--t7-dark-purple)}
.fs-math__id{font-family:var(--t7-mono);font-size:13px}
.fs-math__title{display:block;font-weight:400;color:var(--t7-muted);font-size:13px}
.fs-math__sum{white-space:nowrap;color:var(--t7-muted);font-family:var(--t7-mono);
  font-size:13px}
.fs-math__why{color:var(--t7-muted);font-size:12px;max-width:34ch}
.fs-math__rounded{background:var(--t7-mimosa);font-weight:600}
.fs-math__row--uncounted th,.fs-math__row--uncounted td{color:var(--t7-muted)}
.fs-math__footnote{max-width:68ch;color:var(--t7-muted);font-size:13px;line-height:1.6}

@media (max-width:640px){
  .fs-math{padding:24px 16px}
  .fs-math__sums{padding:16px}
  .fs-math__sums>div{flex-direction:column;gap:2px}
  .fs-math__why{display:none}
}

/* The rounding note's own band: the last thing in the card, so it sits tight to
   the bottom edge rather than floating in a band's worth of air. */
.fs-footnote{padding:14px 40px 16px;border-bottom:0}

/* ------------------------------------------------- the long-page shell (1B) */
/* Rail plus content, on the five pages long enough to need looking up rather
   than reading through. The rail is first in source order, which is also where
   it belongs on a narrow screen — so the single-column collapse below is a
   grid change and needs no DOM reordering. */
.pagegrid{display:grid;grid-template-columns:var(--t7-toc-width) minmax(0,1fr);
  gap:var(--t7-space-5);align-items:start}
.pagegrid__main{min-width:0}

.toc{position:sticky;top:var(--t7-space-4);align-self:start;
  max-height:calc(100vh - var(--t7-space-6));overflow-y:auto;
  border-right:1px solid var(--t7-warm-gray);padding-right:var(--t7-space-2)}
.toc__label{margin:0 0 var(--t7-space-1);padding-left:0.75rem;
  font-family:var(--t7-label);font-size:0.6875rem;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--t7-muted)}
.toc__list{list-style:none;margin:0;padding:0}
.toc__item{margin:0}
/* 44px floor: a contents item is a touch target like any other link. */
.toc__link{display:flex;align-items:center;justify-content:space-between;gap:0.5rem;
  min-height:44px;padding:0.625rem 0.75rem;border-left:3px solid transparent;
  font-size:var(--t7-step--1);line-height:1.4;color:var(--t7-dark-purple);
  text-decoration:none}
.toc__link:hover{background:var(--t7-khaki);text-decoration:underline;
  text-underline-offset:2px}
.toc__meta{font-family:var(--t7-mono);font-size:0.8125rem;color:var(--t7-muted);
  flex:0 0 auto}
/* Set by inpage-nav.js as you scroll. With JavaScript off nothing is marked
   and every link still navigates, which is the whole contract. */
.toc__link[aria-current="true"]{background:var(--t7-lilac);
  border-left-color:var(--t7-electric);font-weight:600}
.toc__link[aria-current="true"] .toc__meta{color:var(--t7-electric)}

/* Below 900px the rail stops being a rail and becomes a plain bordered list at
   the top of the document, where it already is in source order. */
@media (max-width:900px){
  .pagegrid{grid-template-columns:1fr;gap:var(--t7-space-4)}
  .toc{position:static;max-height:none;overflow:visible;border-right:0;
    border:1px solid var(--t7-warm-gray);padding:var(--t7-space-2);
    background:var(--t7-paper)}
  .toc__label{padding-left:0}
}

/* Reading progress. Fixed to the top of the viewport, 4px, and only ever
   visible once JavaScript has unhidden it — see inpage-nav.js. Decorative:
   aria-hidden, because the scrollbar already says this to everyone else. */
.progress{position:fixed;top:0;left:0;right:0;height:4px;z-index:60;
  background:var(--t7-warm-gray)}
.progress > span{display:block;height:100%;width:0;background:var(--t7-coral)}
.ds-expandall-wrap{margin:0 0 var(--t7-space-2)}
.btn-sm{padding:.4rem .8rem;font-size:.875rem;min-height:44px;
  display:inline-flex;align-items:center}


/* "The short version" — the panel a visitor reads instead of the policy when
   all they want to know is whether handing over a URL costs them anything. */
.summarypanel{background:var(--t7-lilac);padding:var(--t7-space-3) 1.5rem;
  margin:0 0 var(--t7-space-5)}
.summarypanel__label{margin:0 0 0.625rem;font-family:var(--t7-label);
  font-size:0.6875rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--t7-electric)}
.summarypanel ul{margin:0;padding-left:1.1rem;display:flex;flex-direction:column;
  gap:0.5rem}
.summarypanel li{font-size:1.0625rem;line-height:1.6;color:var(--t7-dark-purple)}

/* The date-and-contact line under a page title. Metadata, so it is allowed the
   muted ink — at 15px, and never for a sentence of the policy itself. */
.page-meta{margin:0 0 var(--t7-space-4);font-size:var(--t7-step--1);
  line-height:1.6;color:var(--t7-muted)}

/* A real data table in prose. Header cells carry the weight; the rule under
   the head is what separates them from the body at a glance. AIR-2.3. */
.doc-table{width:100%;border-collapse:collapse;margin:0 0 var(--t7-space-3);
  font-size:1.0625rem;line-height:1.6}
.doc-table th,.doc-table td{text-align:left;padding:0.875rem 1rem 0.875rem 0;
  border-bottom:1px solid var(--t7-warm-gray);vertical-align:top}
.doc-table thead th{font-family:var(--t7-label);font-size:0.75rem;font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;color:var(--t7-muted);
  border-bottom:2px solid var(--t7-dark-purple);padding-bottom:0.5rem}
/* A row header is a service's name, so it is set like one. Without these three
   it inherits `.doc th`, which is a column-header treatment — mono, 10.5px,
   uppercase — and "WorkOS" came out as "WORKOS". */
.doc-table tbody th{font-family:var(--t7-sans);font-size:1.0625rem;
  text-transform:none;letter-spacing:0;font-weight:600;
  color:var(--t7-dark-purple);padding-right:var(--t7-space-2);white-space:nowrap}
@media (max-width:560px){
  .doc-table tbody th{white-space:normal}
}

/* A rail with real hierarchy: the Open Standard has two top-level sections and
   everything else sits under them. Only pages that pass a level use this; the
   rest are flat and every item is level 2. */
.toc__item--l1 > .toc__link{font-weight:600;color:var(--t7-dark-purple)}
.toc__item--l1 + .toc__item--l2 > .toc__link,
.toc__item--l2 > .toc__link{padding-left:1.25rem}

/* --- the agency roster (/dashboard) -------------------------------------------
   All new selectors, all prefixed `ro-`, all built on the existing --t7-*
   and --air-* tokens. Checked for collisions before adding: none of these
   names appears anywhere above, which matters in a file that has already
   undone its own rules once with a duplicate `.doc` block. */

/* The two-second line. Bigger than body copy and smaller than a page title:
   it is a sentence somebody reads, not a heading. */
.ro-number{margin:0 0 1.6rem;font-size:1.125rem;line-height:1.5;
  color:var(--t7-dark-purple)}
.ro-number strong{font-family:var(--t7-mono);font-size:1.5rem;font-weight:600;
  letter-spacing:-.01em}
.ro-number__sep{color:var(--t7-muted);margin:0 .4rem}
.ro-number__of{color:var(--t7-muted);font-size:.9375rem}

/* Movement. The colour is the least of it — the arrow and the sign carry the
   meaning, so a reader who cannot distinguish the hues loses nothing. Down is
   the alarming direction on this site, so down is the warm colour. */
.ro-delta{font-family:var(--t7-mono);font-size:.875rem;font-weight:600;
  white-space:nowrap}
.ro-delta.is-up{color:var(--air-good)}
.ro-delta.is-down{color:var(--air-bad)}
.ro-delta.is-flat{color:var(--t7-muted)}

/* Sparkline. Sized in the SVG rather than here so the drawing and the box
   cannot disagree; this only sets colour and vertical rhythm. */
.ro-spark{display:block;overflow:visible}
.ro-spark__line{fill:none;stroke:var(--t7-electric);stroke-width:1.5;
  stroke-linejoin:round;stroke-linecap:round}
.ro-spark__dot{fill:var(--t7-coral)}
.c-spark{width:104px}

/* The host under the client name is the phone layout's only copy of it. */
.ro-host{display:none}
/* Tabular so a column of durations lines up on its digits rather than jittering
   between "8s" and "12m 4s". */
.c-took{font-variant-numeric:tabular-nums;white-space:nowrap;
  color:var(--t7-muted);font-size:.8125rem}

/* The sort control is the column heading now, so it has to look pressable
   without looking like body copy that happens to be blue. Inherits the
   heading's size and tracking; only the colour and the underline change. */
.ro-sortlink{color:var(--t7-electric);text-decoration:none}
.ro-sortlink:hover,.ro-sortlink:focus-visible{text-decoration:underline}
/* The column the table is actually in. Marked rather than linked — pressing
   the sort you are already in is a reload that changes nothing — and the
   caret repeats for a sighted reader what `aria-sort` says to a screen
   reader. */
.ro-sorted{color:var(--t7-dark-purple);font-weight:700}

/* The plan position. Stated, not warned about — it only becomes a warning
   when there is actually nothing left. */
.ro-quota{margin:1rem 0 0;font-size:.875rem;color:var(--t7-muted)}
.ro-quota.is-at-limit{color:var(--air-warn);font-weight:600}

/* Extra domains under a client are ordinary rows of the roster table, one
   tbody per client. That is what lines their columns up with the row above —
   they used to be a table of their own inside a colspan, which cannot inherit
   another table's column widths and brought a second header with it.

   The tbody is also what scopes the disclosure. The CRM's
   `tr.p-row:has(.row-toggle[open]) + tr.p-detail` reaches exactly one row, and
   `~` in its place reveals every client's domains at once — the bug that rule's
   own comment warns about. `tbody:has(...)` has neither problem: the open
   toggle and the rows it reveals are in the same tbody and no other. */
.ro-table > tbody:has(.row-toggle[open]) > tr.p-detail{display:table-row}
/* The CRM's panel row zeroes its padding because it holds a panel. These hold
   table cells, so they take the same padding as the row above — and !important
   only because the rule they are overriding uses it. */
.ro-table > tbody > tr.p-detail > td{padding:.4rem .6rem !important;
  vertical-align:baseline;white-space:nowrap;
  border-bottom:1px solid var(--t7-khaki)}
.ro-table > tbody > tr.p-detail:hover > td{background:var(--t7-paper)}

/* On a phone the table drops the three columns that are context rather than
   answer — history, last scanned, monitoring — so the four that answer the
   question in two seconds (client, domain, score, change) fit without
   sideways scrolling. Scrolling was the first attempt and it was wrong: it
   kept every column and put score and change off the right-hand edge, which
   is the whole point of the page hidden behind a gesture.

   The cells are hidden, not removed: the sparkline's sr-only scan count and
   the monitoring state stay in the markup for a screen reader, and the report
   link moves nowhere because it is beside the host. */
/* An intermediate step before the phone layout. Pages is the column worth
   losing first at tablet width: it is about how the crawl ran rather than
   what it found, and hiding it brings the admin table back to six columns
   which fit comfortably at this breakpoint. The viewer's seven already fit. */
@media (max-width:1150px){
  /* Columns: 1 client, 2 domain, 3 score, 4 change, 5 pages, 6 last scan,
     7 actions. Drop pages (5) from the admin table only; the viewer fits. */
  .ro-table:not(.ro-table--viewer) th:nth-child(5),
  .ro-table:not(.ro-table--viewer) tr>td:nth-child(5){display:none}
}

@media (max-width:900px){
  .ro-number{font-size:1rem}
  .ro-number strong{font-size:1.25rem}
  /* Drop domain, pages and last-scan — phone keeps client, score, change and
     actions. Positional, so every column added or removed needs this list
     updated. Columns: 1 client, 2 domain, 3 score, 4 change, 5 pages,
     6 last scan, 7 actions — narrow keeps 1, 3, 4 and 7. Column 7 survives
     because the weekly switch sits in it beside the two icons, and turning
     scanning off is worth reaching from a phone. */
  .ro-table:not(.ro-table--viewer) th:nth-child(2),
  .ro-table:not(.ro-table--viewer) th:nth-child(5),
  .ro-table:not(.ro-table--viewer) th:nth-child(6),
  .ro-table:not(.ro-table--viewer) tr>td:nth-child(2),
  .ro-table:not(.ro-table--viewer) tr>td:nth-child(5),
  .ro-table:not(.ro-table--viewer) tr>td:nth-child(6){display:none}
  /* A viewer's seven: 1 client, 2 domain, 3 score, 4 change, 5 pages,
     6 last scanned, 7 report. Narrow keeps client, score, change and the
     report — dropping the report would leave them a table they can read and
     nothing they can open. */
  .ro-table--viewer th:nth-child(2),
  .ro-table--viewer th:nth-child(5),
  .ro-table--viewer th:nth-child(6),
  .ro-table--viewer tr>td:nth-child(2),
  .ro-table--viewer tr>td:nth-child(5),
  .ro-table--viewer tr>td:nth-child(6){display:none}
  .ro-host{display:block;word-break:break-all}
  .detail-panel{padding-left:.6rem}
}

/* The monitoring switch. A real <button> in a real form — the roster works
   with scripts off — dressed as a switch so it reads as state rather than as
   an action. `role="switch"` and aria-checked carry that to a screen reader,
   which a coloured pill never did. */
.ro-toggle{display:inline-flex;align-items:center;border:0;padding:.35rem .2rem;
  background:none;cursor:pointer;font:inherit;color:var(--t7-muted)}
.ro-toggle__track{width:1.9rem;height:1rem;border-radius:1rem;flex:0 0 auto;
  background:var(--t7-warm-gray);position:relative;transition:background .12s}
.ro-toggle__dot{position:absolute;top:2px;left:2px;width:.75rem;height:.75rem;
  border-radius:50%;background:#fff;transition:transform .12s}
.ro-toggle.is-on .ro-toggle__track{background:var(--air-good, var(--t7-electric))}
.ro-toggle.is-on .ro-toggle__dot{transform:translateX(.9rem)}
.ro-toggle:focus-visible{outline:2px solid var(--t7-electric);outline-offset:2px}
.c-pages{font-variant-numeric:tabular-nums;color:var(--t7-muted);
  font-size:.8125rem}
/* Row controls: quiet until the row is hovered, like the CRM's `.kill`, and
   laid out side by side so the cell is as wide as three small squares rather
   than as wide as the word "Rescan".

   The flex box is a div inside the cell, never the cell itself. `display:flex`
   on a `<td>` stops it being a table cell: it leaves the row's box, so it no
   longer shares the row's height or sits on the column's grid, and the roster
   rendered visibly jagged — worst on a grantee's table, where this cell holds
   one short link and nothing else was tall enough to hide it. */
.c-act{white-space:nowrap}
.c-act__row{display:flex;gap:.15rem;align-items:center}
/* A grantee's only control. `.c-sub` is `display:block`, which on this link
   stretched it across the cell and put its underline under the whole column —
   two classes so it beats the lone `.c-sub` on class count rather than on
   source order. */
.c-sub.ro-report{display:inline-block}
/* Visible at rest, unlike the CRM's `.kill`. Rescan is a thing somebody came
   to the page to do, not a destructive tidy-up they should have to hunt for —
   and a hover-only control does not exist at all on a touch screen. Quiet
   rather than hidden: warm gray until the row or the control is hovered. */
.rowact{display:inline-grid;place-items:center;width:1.6rem;height:1.6rem;
  padding:0;border:0;border-radius:0;background:none;cursor:pointer;
  color:var(--t7-warm-gray);
  transition:color .12s,background .12s}
tr.p-row:hover .rowact,tr.p-detail:hover .rowact{color:var(--t7-muted)}
.rowact:focus-visible{outline:2px solid var(--t7-electric);outline-offset:1px}
.rowact:hover{color:var(--t7-electric);background:var(--t7-lilac)}

.ag-actions{display:flex;flex-wrap:wrap;gap:.6rem;margin:0 0 1.6rem}

/* The guided path a new organization sees in place of an empty roster. An
   ordered list because it is one, so a screen reader announces "3 items"
   before the first step rather than after the third. */
.ag-steps{list-style:none;margin:0 0 1.6rem;padding:0;display:flex;
  flex-wrap:wrap;gap:.8rem}
.ag-steps__step{flex:1 1 11rem;display:flex;gap:.7rem;align-items:baseline;
  background:var(--t7-khaki);border-radius:6px;padding:.8rem 1rem;
  font-size:15px;line-height:1.35}
.ag-steps__n{font-family:var(--t7-mono);font-size:13px;color:#fff;flex:0 0 auto;
  background:var(--t7-electric);border-radius:50%;width:1.5rem;height:1.5rem;
  display:inline-flex;align-items:center;justify-content:center}

/* --- one domain (/dashboard/domain/{id}) --------------------------------------
   A dark hero carrying identity, score and trend, then a two-column body: what
   changed on the left, the three things somebody sets about this domain on the
   right. Squared, like the rest of the site — the handoff's 3 and 4px radii are
   deliberately not honoured here (docs/readiness-design-system.md). */

/* Full-bleed inside the card, matching .card's own 22px side padding, so the
   band reads as this page's header rather than as the first of six panels. */
.dv-hero{margin:0 -22px;padding:30px 22px 0;
  background:var(--t7-dark-purple);color:var(--t7-paper);
  display:flex;flex-direction:column;gap:28px}

.dv-hero__top{display:flex;justify-content:space-between;align-items:flex-end;
  gap:24px;flex-wrap:wrap}
.dv-hero__id{display:flex;flex-direction:column;gap:10px;min-width:0}
.dv-crumb{margin:0;display:flex;flex-wrap:wrap;gap:8px;
  font-family:var(--t7-label);font-size:13px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--t7-lavender)}
.dv-crumb a{color:var(--t7-lilac)}
.dv-crumb__type{color:var(--t7-paper)}
/* Wraps, never truncates: an ellipsis in the middle of a hostname leaves
   somebody unsure which subdomain they are looking at. */
.dv-hero__domain{margin:0;font-family:var(--t7-sans);font-size:36px;
  font-weight:600;letter-spacing:-.01em;line-height:1.1;overflow-wrap:anywhere}
.dv-hero__run{margin:0;display:flex;align-items:center;gap:16px;flex-shrink:0}
.dv-hero__hint{font-size:14px;color:var(--t7-lilac)}
.dv-hero__run .btn[disabled]{opacity:.55;cursor:default}

/* Score left, trend right, divided by a drawn rule rather than by whitespace:
   they are two readings of one thing and the rule says so. */
.dv-hero__main{display:grid;grid-template-columns:420px minmax(0,1fr);gap:48px;
  align-items:stretch}
.dv-label{margin:0;font-family:var(--t7-label);font-size:12px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--t7-lilac)}

.dv-score{display:flex;flex-direction:column;gap:18px;padding-right:48px;
  border-right:1px solid var(--t7-medium)}
.dv-score__row{display:flex;align-items:flex-end;gap:20px}
.dv-score__num{font-size:128px;font-weight:600;line-height:.8;
  font-variant-numeric:tabular-nums}
.dv-score__side{display:flex;flex-direction:column;gap:8px;padding-bottom:6px}
.dv-score__band{align-self:flex-start;background:var(--t7-mimosa);
  color:var(--t7-dark-purple);font-family:var(--t7-label);font-size:12px;
  letter-spacing:.1em;font-weight:600;padding:5px 10px 3px;
  text-transform:uppercase}
/* On the dark ground the light-background status colours fall below AA, so
   these are the on-dark pair. The glyph carries the direction either way —
   colour is never the only signal. */
.dv-score__delta{font-size:18px;font-weight:600}
.dv-score__delta.is-up{color:var(--status-pass-on-dark)}
.dv-score__delta.is-down{color:var(--status-fail-on-dark)}
.dv-score__delta.is-flat{color:var(--t7-lilac)}
.dv-score__of{font-size:13px;color:var(--t7-lilac)}
.dv-score__never{margin:0;font-size:36px;font-weight:600;color:var(--t7-lilac)}
/* The one serif line on the page. It is the sentence a person reads when they
   have no intention of reading a table, so it is set as prose. */
.dv-score__says{margin:0;font-family:var(--t7-serif);font-size:19px;
  line-height:1.45;text-wrap:pretty}

.dv-trend{display:flex;flex-direction:column;gap:10px;min-width:0}
.dv-trend__head{display:flex;justify-content:space-between;align-items:baseline;
  gap:16px;flex-wrap:wrap}
.dv-trend__none{margin:34px 0;font-size:15px;color:var(--t7-lilac)}

/* The range filter. Real submit buttons in a GET form, so it works with no
   scripts and the choice lands in the URL either way. */
.dv-range{display:flex;gap:4px;margin:0}
.dv-range__seg{font:inherit;font-size:13px;line-height:1;padding:6px 10px;
  background:transparent;border:0;color:var(--t7-lilac);cursor:pointer}
.dv-range__seg:hover{color:var(--t7-paper)}
.dv-range__seg.is-on{background:var(--t7-medium);color:var(--t7-paper)}

.dv-chart{margin:0}
.dv-chart svg{display:block;width:100%}
.dv-chart__line{fill:none;stroke:var(--t7-lilac);stroke-width:3;
  stroke-linejoin:round;stroke-linecap:round}
.dv-chart__dot{fill:var(--t7-lilac)}
/* The newest reading is ringed rather than filled, so the eye lands on where
   we are now before it reads the line that got there. */
.dv-chart__dot--now{fill:var(--t7-dark-purple);stroke:var(--t7-coral);
  stroke-width:3}
/* A failure is a tick on the axis, not a point on the line: there is no score
   to place it at. */
.dv-chart__fail{stroke:var(--t7-coral);stroke-width:2;stroke-linecap:round}
.dv-chart__grid{stroke:var(--t7-medium);stroke-width:1}
.dv-chart__tick{font-family:var(--t7-mono);font-size:11px;fill:var(--t7-lilac)}
.dv-chart__val{font-family:var(--t7-sans);font-size:14px;fill:var(--t7-lilac)}
.dv-chart__val--now{font-size:16px;font-weight:600;fill:var(--t7-paper)}
.dv-chart__date{font-family:var(--t7-mono);font-size:11px;fill:var(--t7-lilac)}
.dv-chart__cap{margin:0;font-size:13px;color:var(--t7-lilac)}
.dv-chart__point{cursor:default}
.dv-chart__point:focus-visible{outline:2px solid var(--t7-coral);outline-offset:2px}

/* Split from the two columns above by a rule that runs the full width of the
   band, which is what makes these three read as a footer to the hero rather
   than as a fourth panel. */
.dv-hero__strip{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  border-top:1px solid var(--t7-medium);margin:0 -22px;padding:0 22px}
.dv-fact{padding:16px 0;display:flex;gap:10px;align-items:baseline;
  flex-wrap:wrap}
.dv-fact .dv-label{font-size:11px}
.dv-fact__val{font-weight:500}

/* --- the body ------------------------------------------------------------- */
.dv-body{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:40px;
  padding:34px 0 0}
.dv-main{display:flex;flex-direction:column;gap:40px;min-width:0}
.dv-sec__head{display:flex;justify-content:space-between;align-items:baseline;
  gap:16px;margin:0 0 16px}
.dv-sec__title{margin:0;font-size:26px;font-weight:600;color:var(--t7-electric)}
.dv-sec__counts{margin:0;display:flex;gap:16px;font-size:14px;font-weight:600}
.dv-sec__link{font-size:15px;font-weight:500}
.dv-up{color:var(--status-pass)}
.dv-down{color:var(--status-fail)}

/* Scrolls inside its own frame on a narrow screen rather than squashing the
   columns — a check id and a date have a width below which they stop being
   readable at all. */
.dv-table-wrap{border:1px solid var(--t7-warm-gray);overflow-x:auto}
/* Below this the check id, the chip pair and a readable finding stop fitting
   side by side, and the frame scrolls rather than the columns squashing. */
.dv-tbl{width:100%;border-collapse:collapse;min-width:520px;table-layout:fixed}
/* Fixed columns so the two free-text cells — the check name and the finding —
   share what is left rather than one of them winning by having a long word in
   it. */
.dv-tbl--moved col.dv-col-rail{width:4px}
.dv-tbl--moved col.dv-col-change{width:150px}
.dv-tbl--moved col.dv-col-pts{width:52px}
.dv-tbl--scans col.dv-col-num{width:84px}
.dv-tbl--scans col.dv-col-pages{width:110px}
.dv-tbl--scans col.dv-col-report{width:84px}
.dv-tbl thead th{background:var(--t7-khaki);text-align:left;font-weight:400;
  font-family:var(--t7-label);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--t7-muted);padding:10px 16px}
.dv-tbl td{padding:16px;border-top:1px solid var(--t7-warm-gray);
  vertical-align:top;font-size:15px}
.dv-tbl .num{text-align:right}
.dv-tbl--scans td{vertical-align:middle}

/* The rail follows the direction of the change, never the band it landed on:
   failing to partial is good news, and colouring it by where it ended would
   say the opposite. */
.dv-tbl__rail{width:4px;padding:0 !important;border-top:0 !important}
.dv-tbl--moved tbody tr.is-up .dv-tbl__rail{background:var(--status-pass-bar)}
.dv-tbl--moved tbody tr.is-down .dv-tbl__rail{background:var(--status-fail-bar)}
.dv-check__id{font-family:var(--t7-mono);font-size:14px;font-weight:500;
  display:block}
.dv-check__name{font-size:15px;display:block;margin-top:4px}
.dv-change{white-space:nowrap}
.dv-change__was{font-family:var(--t7-label);font-size:11px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--t7-muted);margin-right:6px}
/* Never colour alone: every chip carries its own word, and the points column
   beside it carries the glyph. */
.dv-chip{display:inline-block;font-family:var(--t7-label);font-size:11px;
  letter-spacing:.08em;font-weight:600;padding:4px 8px 2px;
  background:var(--t7-khaki);color:var(--t7-muted)}
.dv-chip--pass{background:var(--status-pass-bg);color:var(--status-pass-ink)}
.dv-chip--problem{background:var(--status-fail-bg);color:var(--status-fail-ink)}
.dv-chip--needs-work{background:var(--t7-khaki);color:var(--t7-muted)}
.dv-pts{font-weight:600;white-space:nowrap}
.dv-pts.is-up{color:var(--status-pass)}
.dv-pts.is-down{color:var(--status-fail)}
.dv-tbl__saw{font-size:14px;line-height:1.5;color:var(--t7-dark-purple)}

.dv-when__day{font-weight:500}
/* display:block forces the pages/duration line below the relative time rather
   than running it on after a space-separated margin-left. */
.dv-when__ago{display:block;font-size:14px;color:var(--t7-muted);margin-top:2px}
.dv-scans__score{font-weight:600;font-size:18px}

/* --- the aside ------------------------------------------------------------ */
.dv-aside{display:flex;flex-direction:column;gap:24px}
.dv-card{border:1px solid var(--t7-warm-gray);background:var(--t7-paper);
  padding:24px;display:flex;flex-direction:column;gap:14px}
.dv-card__head{display:flex;justify-content:space-between;align-items:center;
  gap:12px}
.dv-card__title{margin:0;font-size:20px;font-weight:600}
.dv-card__count{background:var(--t7-khaki);font-family:var(--t7-label);
  font-size:12px;padding:3px 8px 1px}
.dv-card__blurb{margin:0;font-size:14px;line-height:1.5}
.dv-card__form{display:flex;gap:8px;margin:0;flex-wrap:wrap}
.dv-card__form input[type=text],.dv-card__form select{flex:1;min-width:0;
  font:inherit;font-size:15px;padding:10px 12px;border:1px solid var(--t7-warm-gray);
  background:var(--t7-paper);color:var(--t7-dark-purple);border-radius:0}
.dv-card__form--type{flex-wrap:wrap}
.dv-card__other{flex:1 0 100%;display:flex}
/* `display` beats the `hidden` attribute's own `display:none`, so without this
   verticalfield.js hides the industry box and the box stays on screen. */
.dv-card__other[hidden]{display:none}
.dv-card__other input{width:100%}
.dv-card__hint{margin:0;font-size:13px;color:var(--t7-muted)}
.dv-card__err{margin:0;font-size:13px;color:var(--air-bad);font-weight:600}
.dv-card__saved{margin:0;font-size:13px;color:var(--status-pass);font-weight:600}

.dv-money{list-style:none;margin:0;padding:0;display:flex;
  flex-direction:column;gap:2px}
.dv-money__row{display:flex;align-items:center;gap:8px;
  border-top:1px solid var(--t7-khaki);padding-top:8px}
.dv-money__url{flex:1;min-width:0;font-size:14px;color:var(--t7-muted);
  word-break:break-all}
.dv-money__row form{margin:0;line-height:0}
/* The CRM's `.kill` is invisible until `tr.p-row:hover` reveals it, and these
   rows are list items. Without this the trash can is present, focusable and
   never once drawn for somebody using a mouse. */
.dv-money__row:hover .kill{opacity:1}

/* Not a button. Archiving is ordinary and reversible, but it stops the weekly
   scan, so it does not get the same weight as Add and Save above it. */
.dv-archive{display:flex;flex-direction:column;gap:8px;
  border-top:1px solid var(--t7-warm-gray);padding-top:20px}
.dv-archive__note{margin:0;font-size:14px;line-height:1.5;color:var(--t7-muted)}
.dv-archive__link{align-self:flex-start;font:inherit;font-size:15px;
  font-weight:600;color:var(--t7-dark-purple);background:none;border:0;padding:0;
  text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.dv-confirm{border:1px solid var(--t7-dark-purple);background:var(--t7-paper);
  color:var(--t7-dark-purple);max-width:26rem;padding:24px}
.dv-confirm::backdrop{background:rgba(29,4,70,.45)}
.dv-confirm__q{margin:0 0 8px;font-size:20px;font-weight:600}
.dv-confirm__note{margin:0 0 20px;font-size:15px;line-height:1.5}
.dv-confirm__row{display:flex;gap:12px;justify-content:flex-end}

/* The aside drops under the main column before the hero splits: two 340px-ish
   columns stop working well before a 420px score and a chart do. */
@media (max-width:1000px){
  .dv-body{grid-template-columns:minmax(0,1fr);gap:32px}
}
@media (max-width:900px){
  .dv-hero__main{grid-template-columns:minmax(0,1fr);gap:28px}
  .dv-score{padding-right:0;border-right:0;
    border-bottom:1px solid var(--t7-medium);padding-bottom:24px}
  .dv-hero__strip{grid-template-columns:minmax(0,1fr)}
  .dv-fact{padding:10px 0;border-top:1px solid var(--t7-medium)}
  .dv-fact:first-child{border-top:0}
  .dv-hero__top{align-items:flex-start}
  .dv-hero__run{width:100%}
  .dv-score__num{font-size:88px}
}

/* --- the control panel (/control) ------------------------------------------
   Internal and desktop-only on purpose: this is read at a desk beside the
   thing it describes, and the tree needs horizontal room to stay legible.
   There is no narrow-screen block below, which is the deliberate choice rather
   than an omission. */

.ctl-sub{margin:0 0 1.6rem}
.ctl-soon{margin:0 0 2rem}
/* Dashed and dimmed so a placeholder can never be mistaken for a zero. An
   empty tile that looked like the others would read as "revenue: nothing". */
/* Two classes to beat `.tile:first-child` (0,1,1), which paints the leading
   tile dark purple — correct for a real figure, wrong for a placeholder, which
   would then be the loudest thing on the page while saying nothing. */
.tiles .tile--soon{border-style:dashed;opacity:.55;position:relative;
  background:#fff;border-color:var(--t7-warm-gray);color:inherit}
.tiles .tile--soon .n,.tiles .tile--soon .l{color:var(--t7-muted)}
.ctl-soon__tag{font-family:var(--t7-label);text-transform:uppercase;
  letter-spacing:.08em;font-size:.625rem;color:var(--t7-muted);margin-top:.2rem}

.ctl-tree{margin:0 0 2rem}
.ctl-table{width:100%}
.ctl-table .c-when{white-space:nowrap}
/* The row the page exists to surface, marked on the row itself rather than
   only in the count above it. */
.ctl-stalled{color:var(--t7-rust)}
tr.p-row.is-stalled>td:nth-child(2){box-shadow:inset 3px 0 0 var(--t7-rust)}
.ctl-client{margin:.7rem 0 .3rem;font-weight:600;font-size:.875rem}
.ctl-client .c-sub{font-weight:400}
.ctl-slug{font-family:var(--t7-mono);font-size:10.5px;color:var(--t7-muted)}
.ctl-empty{margin:0 0 .6rem}
.ctl-clamp{color:var(--t7-rust);font-weight:700;margin-left:.15rem}

/* --- The vertical ask ---
   On a scan page, and only for somebody who may answer it. Not a form in a
   settings screen: it interrupts a page whose reader came to look at a number,
   so it earns its place by saying what answering buys them — a held check and
   the points with it — rather than by asking to be categorized.

   Two tones. Unset gets the mimosa rail every other "this is missing" surface
   on the site gets. Set goes quiet and reads as an ordinary field, because the
   job is done and the reader is back to looking at their score. */
.vask{border:1px solid var(--t7-warm-gray);background:#fff;padding:10px 18px;
  margin:0 0 20px}
.vask--unset{background:var(--t7-mimosa);border-color:var(--t7-warm-gray);
  border-left:4px solid var(--t7-coral)}
.vask__form{display:flex;justify-content:flex-end}
.vask__controls{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.vask__label{font-weight:600;font-size:14px;color:var(--t7-dark-purple);
  white-space:nowrap}
/* A plain <select>'s own chrome varies by OS and browser; this redraws it in
   the design system's own terms — sharp corners, the warm-gray line every
   other field uses, the electric focus ring `:focus-visible` gives every
   other control — rather than leaving the one field on the page that looks
   like it belongs to the operating system instead of the site. */
.vask__select{appearance:none;-webkit-appearance:none;font:inherit;
  font-size:14px;min-width:12rem;padding:7px 30px 7px 10px;
  border:1px solid var(--t7-warm-gray);border-radius:0;background:#fff;
  color:var(--t7-dark-purple)}
select.vask__select{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%235b636d' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 10px center;
  background-size:10px 7px}
.vask__select:focus-visible{outline:2px solid var(--t7-electric);outline-offset:1px}
.vask__controls .btn-sm{padding:7px 14px}
@media (max-width:640px){
  .vask__form{justify-content:stretch}
  .vask__controls{flex-direction:column;align-items:stretch;width:100%}
  .vask__controls .btn{width:100%}
}

/* ================================================================ READY-36
   Agency dashboard redesign. New components only — existing classes (ro-delta,
   ro-toggle, rowact, kill, dv-when, etc.) are reused throughout the template.
   ================================================================ */

/* -- Page header -------------------------------------------------------- */
/* Eyebrow above the org name: "ADMIN / ORGANIZATION" in label caps. The slash
   is muted so the eye reads the text rather than the divider. */
.ro-eyebrow{font-family:var(--t7-label);font-size:13px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--t7-dark-purple);margin:0 0 .5rem}
.ro-eyebrow__sep{color:var(--t7-lavender);margin:0 .3em}
/* Org name and gear icon sit in a flex row so the icon aligns to the cap
   height of the heading rather than to an arbitrary baseline. */
.ro-page-head{display:flex;align-items:center;gap:.6rem;margin:0 0 1.6rem;
  flex-wrap:wrap}
.ro-page-title{margin:0;font-size:56px;font-weight:600;line-height:1;
  color:var(--t7-electric)}
/* Gear icon link. Square, 36px hit target at rest; khaki background on hover
   so it reads as "pressed" rather than just coloured. */
.ro-gear-btn{display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:36px;border-radius:0;color:var(--t7-lavender);
  background:none;border:0;text-decoration:none;transition:color .12s,background .12s;
  flex-shrink:0}
.ro-gear-btn:hover,.ro-gear-btn:focus-visible{color:var(--t7-electric);
  background:var(--t7-khaki)}
.ro-gear-btn:focus-visible{outline:2px solid var(--t7-electric);outline-offset:2px}

/* -- Stat strip --------------------------------------------------------- */
/* Three-cell bordered strip below the page heading. Cells are divided by
   1.5px vertical rules that share the outer border's colour. */
.ro-stat-strip{display:flex;border:1.5px solid var(--t7-warm-gray);
  margin:0 0 2rem}
.ro-stat-cell{flex:1 1 0;padding:20px 24px;display:flex;flex-direction:column;
  gap:6px}
.ro-stat-cell + .ro-stat-cell{border-left:1.5px solid var(--t7-warm-gray)}
.ro-stat-cell__label{font-family:var(--t7-label);font-size:13px;
  letter-spacing:.08em;text-transform:uppercase;color:var(--t7-muted);margin:0}
.ro-stat-cell__main{display:flex;align-items:baseline;gap:.3em}
/* 44px score number. Tabular so the digits align when the strip is scanned. */
.ro-stat-cell__num{font-size:44px;font-weight:600;line-height:1;
  font-variant-numeric:tabular-nums;color:var(--t7-dark-purple)}
.ro-stat-cell__of{font-size:15px;color:var(--t7-muted)}
/* 6px plan-usage bar. Khaki track, Medium Purple fill. */
.ro-stat-cell__bar-wrap{height:6px;background:var(--t7-khaki);
  border:1px solid var(--t7-warm-gray);overflow:hidden}
.ro-stat-cell__bar-fill{height:100%;background:var(--t7-medium);
  transition:width .3s}
.ro-stat-cell__note{font-size:13px;color:var(--t7-muted);margin:0}
@media (max-width:640px){
  .ro-stat-strip{flex-direction:column}
  .ro-stat-cell + .ro-stat-cell{border-left:0;border-top:1.5px solid var(--t7-warm-gray)}
}

/* -- Roster section heading ---------------------------------------------- */
/* Flex row: title + count box + inline links on the left; search form on the
   right. Wraps on narrow windows. */
.ro-section-head{display:flex;justify-content:space-between;align-items:center;
  gap:1rem;flex-wrap:wrap;margin-bottom:.4rem}
.ro-section-head__left{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}
/* Electric purple h2, 30px, matching the domain history page's section titles. */
.ro-section-title{margin:0;font-size:30px;font-weight:600;
  color:var(--t7-electric)}
/* Khaki count box. 13px semibold, label font. */
.ro-count-box{background:var(--t7-khaki);font-family:var(--t7-label);
  font-size:13px;font-weight:600;padding:2px 8px;white-space:nowrap}
/* Inline "Add a client · Add a domain" links beside the heading. */
.ro-inline-links{font-size:14px;display:flex;gap:.4rem;align-items:center}
.ro-inline-links a{color:var(--t7-electric);text-decoration:underline;
  text-underline-offset:3px}
.ro-inline-links__sep{color:var(--t7-muted)}

/* -- Roster search form -------------------------------------------------- */
.ro-search-form{margin:0}
.ro-search-wrap{position:relative;display:flex;align-items:center}
.ro-search-icon{position:absolute;left:10px;color:var(--t7-muted);
  pointer-events:none}
.ro-search-wrap input[type=search]{padding:7px 12px 7px 34px;border:1.5px solid
  var(--t7-warm-gray);border-radius:0;font:inherit;font-size:14px;
  color:var(--t7-dark-purple);background:var(--t7-paper);width:220px}
.ro-search-wrap input[type=search]::placeholder{color:var(--t7-muted)}
.ro-search-wrap input[type=search]:focus-visible{outline:2px solid var(--t7-electric);
  outline-offset:0;border-color:var(--t7-electric)}

/* -- Roster table columns ----------------------------------------------- */
/* Client column: electric purple, semibold, underlined link. */
.ro-client-link{color:var(--t7-electric);font-weight:600;
  text-decoration:underline;text-underline-offset:3px}
.ro-client-link:hover{color:var(--t7-dark-purple)}
/* Domain links: dark purple, underlined. */
.ro-domain-link{color:var(--t7-dark-purple);text-decoration:underline;
  text-underline-offset:3px}
.ro-domain-link:hover{color:var(--t7-electric)}
/* Score: plain bold 18px number, right-aligned. No badge. */
.ro-score-cell{white-space:nowrap}
.ro-score{font-size:18px;font-weight:600;font-variant-numeric:tabular-nums;
  color:var(--t7-dark-purple)}
/* Empty search result. */
.ro-empty-search{text-align:center;padding:1.5rem !important;
  color:var(--t7-muted);font-style:italic}

/* -- Multi-domain chip -------------------------------------------------- */
/* Khaki chip next to the client name that toggles child rows. The <details>
   element's open state drives the chevron rotation via CSS.
   Selector is doubled up on `.row-toggle .ro-domain-chip` rather than plain
   `.ro-domain-chip`: the roster table reuses `table.prospects`, which brings
   along `.row-toggle>summary`'s much older icon-only disclosure rule (a
   1.1rem square grid cell for a bare glyph, not a text chip). That rule's
   specificity otherwise wins over a single class and squashes this chip's
   text into its tiny box — same trap as the two CSS-specificity bugs in the
   project notes. Also why width/height/place-items are reset explicitly:
   `.ro-domain-chip` not declaring them would otherwise leave the old rule's
   values in effect even after this one wins on the properties it does set. */
.row-toggle .ro-domain-chip{list-style:none;display:inline-flex;align-items:center;
  gap:4px;width:auto;height:auto;place-items:normal;
  font-family:var(--t7-label);font-size:11px;font-weight:600;
  background:var(--t7-khaki);padding:2px 7px;cursor:pointer;
  color:var(--t7-dark-purple);margin-left:.5rem;vertical-align:middle;
  user-select:none}
.row-toggle .ro-domain-chip::before{content:none}
.ro-domain-chip::-webkit-details-marker{display:none}
.ro-domain-chip__chevron{font-size:13px;line-height:1;transition:transform .15s;
  display:inline-block}
details.row-toggle[open] .ro-domain-chip__chevron{transform:rotate(180deg)}
/* Child row styling when expanded: khaki bg. The existing .p-detail and
   .ro-table selectors handle visibility (display:table-row). */
.ro-table > tbody > tr.p-detail > td{background:var(--t7-khaki)}
.ro-table > tbody > tr.p-detail:hover > td{background:#ede7e1}

/* -- Sort links --------------------------------------------------------- */
/* Active sort column: electric purple link with ↑/↓ arrow. */
.ro-sortlink--active{color:var(--t7-electric);font-weight:600;
  text-decoration:none}
.ro-sortlink--active:hover,.ro-sortlink--active:focus-visible{
  text-decoration:underline;text-underline-offset:2px}

/* -- People section ----------------------------------------------------- */
/* Row tints khaki on hover and reveals the trash icon. */
.ro-people-row{transition:background .1s}
.ro-people-row:hover>td{background:var(--t7-khaki)}
/* Muted email beside the bold name. */
.ro-member-email{font-size:13px;color:var(--t7-muted);margin-left:.4rem}
/* Delete cell: narrow, keeps the icon right-aligned. The kill button is
   opacity:0 at rest and revealed on row hover or focus-within. */
.ro-people-del{width:2rem;padding-left:0 !important;text-align:right}
.ro-people-del form{margin:0;line-height:0}
.ro-people-del .kill{opacity:0;transition:opacity .12s}
.ro-people-row:hover .kill,.ro-people-del:focus-within .kill{opacity:1}

/* -- Role segmented control --------------------------------------------- */
/* Two joined form buttons inside a single electric-purple outline. Active
   side: Medium Purple fill with white text. Inactive: transparent with
   electric purple text. No JavaScript required — each is a separate POST. */
.ro-role-seg{display:inline-flex;border:1.5px solid var(--t7-electric)}
.ro-role-seg__btn{font:inherit;font-size:13px;padding:4px 10px;border:0;
  background:transparent;color:var(--t7-electric);cursor:pointer;line-height:1.4;
  transition:background .12s,color .12s}
.ro-role-seg__btn.is-active{background:var(--t7-medium);color:#fff;cursor:default}
.ro-role-seg__btn--left{border-right:1.5px solid var(--t7-electric)}
.ro-role-seg__btn:not(.is-active):hover{background:var(--t7-lilac)}
.ro-role-seg__btn:focus-visible{outline:2px solid var(--t7-electric);
  outline-offset:1px}

/* -- Pagination footer -------------------------------------------------- */
/* Shared pager bar for roster, people and my scans. Positioned below the
   table, using the same warm-gray border as the table. */
.ro-pager{display:flex;justify-content:space-between;align-items:center;
  gap:.75rem;padding:.6rem 1rem;border:1.5px solid var(--t7-warm-gray);
  border-top:0;flex-wrap:wrap}
.ro-pager__showing{font-size:13px;color:var(--t7-muted)}
.ro-pager__nav{display:flex;gap:4px;align-items:center}
/* Each page button: 32px square, square corners. Current page: Medium Purple
   fill + white text. Disabled arrows: 40% opacity. */
.ro-pager__btn{display:inline-flex;align-items:center;justify-content:center;
  width:32px;height:32px;font-size:14px;font-weight:500;border:1px solid
  var(--t7-warm-gray);border-radius:0;background:transparent;
  color:var(--t7-dark-purple);text-decoration:none;cursor:pointer;
  transition:background .1s,color .1s}
.ro-pager__btn:hover{background:var(--t7-khaki)}
.ro-pager__btn--current{background:var(--t7-medium);color:#fff;border-color:var(--t7-medium);
  cursor:default}
.ro-pager__btn--off{opacity:.4;cursor:default}

/* -- My scans empty box ------------------------------------------------- */
.ro-empty-box{border:1.5px solid var(--t7-warm-gray);padding:1.5rem}
.ro-empty-box .empty{margin:0}

/* -- Invite link in People heading -------------------------------------- */
.ro-invite-link{font-size:14px;color:var(--t7-electric);text-decoration:underline;
  text-underline-offset:3px;white-space:nowrap}

/* -- Narrow-screen roster adjustments ----------------------------------- */
/* Column layout after the Pages column was added: 1 client, 2 domain,
   3 score, 4 change, 5 pages, 6 last scan, 7 actions. At 900px hide domain
   (2), pages (5) and last scan (6) so client, score, change and actions fit.
   At 1150px the admin table hides pages (5) only — handled in the earlier
   media block above. */
@media (max-width:900px){
  .ro-table:not(.ro-table--viewer) th:nth-child(2),
  .ro-table:not(.ro-table--viewer) th:nth-child(5),
  .ro-table:not(.ro-table--viewer) th:nth-child(6),
  .ro-table:not(.ro-table--viewer) tr>td:nth-child(2),
  .ro-table:not(.ro-table--viewer) tr>td:nth-child(5),
  .ro-table:not(.ro-table--viewer) tr>td:nth-child(6){display:none}
  /* A viewer's table has the same seven columns. Hide domain (2), pages (5)
     and last scan (6); keep client, score, change and the report link. */
  .ro-table--viewer th:nth-child(2),
  .ro-table--viewer th:nth-child(5),
  .ro-table--viewer th:nth-child(6),
  .ro-table--viewer tr>td:nth-child(2),
  .ro-table--viewer tr>td:nth-child(5),
  .ro-table--viewer tr>td:nth-child(6){display:none}
  .ro-host{display:block;word-break:break-all}
}

/* --- one client (/dashboard/clients/{id}) -------------------------------------
   Two-column layout: 260px sticky left rail + flexible main column.
   Uses dv-* classes from the domain page for tables, cards, archive pattern.
   New cv-* classes only where nothing from dv-* or .prospects applies.
   -------------------------------------------------------------------------*/

.cv-layout{display:grid;grid-template-columns:260px minmax(0,1fr);gap:48px;
  align-items:start;margin-top:28px}

/* Rail */
.cv-rail{position:sticky;top:24px;display:flex;flex-direction:column;gap:20px}
.cv-crumb{margin:0;font-family:var(--t7-label);font-size:13px;
  letter-spacing:.12em;text-transform:uppercase;display:flex;flex-wrap:wrap;
  gap:6px;color:var(--t7-muted)}
.cv-crumb a{color:var(--t7-electric);text-decoration:underline;
  text-underline-offset:3px}
.cv-crumb__cur{color:var(--t7-muted)}
.cv-name{margin:0;font-size:44px;font-weight:600;line-height:1.05;
  color:var(--t7-electric);word-break:break-word}

.cv-add{display:flex;flex-direction:column;gap:8px}
.cv-add__btn{align-self:flex-start}
.cv-add__note{margin:0;font-size:13px;color:var(--t7-muted)}

/* Summary box */
.cv-summary{border:1.5px solid var(--t7-warm-gray);background:var(--t7-paper)}
.cv-summary__row{display:flex;justify-content:space-between;align-items:baseline;
  gap:8px;padding:12px 14px;border-top:1px solid var(--t7-warm-gray)}
.cv-summary__row:first-child{border-top:0}
.cv-summary__label{font-size:12px;color:var(--t7-muted);white-space:nowrap}
.cv-summary__val{display:flex;align-items:baseline;gap:6px;font-weight:500;
  text-align:right}
.cv-summary__score{font-size:40px;font-weight:600;line-height:1;
  color:var(--t7-dark-purple)}
.cv-summary__of{font-size:12px;color:var(--t7-muted)}
.cv-summary__none{font-size:14px;color:var(--t7-muted)}

/* In-page section nav */
.cv-nav{margin:0;padding:0;list-style:none;
  border:1.5px solid var(--t7-warm-gray)}
.cv-nav li + li{border-top:1px solid var(--t7-warm-gray)}
.cv-nav__link{display:flex;justify-content:space-between;align-items:center;
  padding:10px 14px;text-decoration:none;font-size:14px;font-weight:500;
  color:var(--t7-dark-purple);gap:8px}
.cv-nav__link:hover{background:var(--t7-lilac);color:var(--t7-paper);
  text-decoration:none}
.cv-nav__link[aria-current=page]{background:var(--t7-khaki)}
.cv-nav__count{font-family:var(--t7-label);font-size:12px;
  color:var(--t7-muted);white-space:nowrap}

/* Main column */
.cv-main{display:flex;flex-direction:column;gap:40px;min-width:0}

/* Domains table column widths */
.dv-tbl--domains col.dv-col-added{width:150px}

/* Domains host link */
.cv-host{font-weight:600;color:var(--t7-electric);text-decoration:underline;
  text-underline-offset:3px;display:block}

/* Settings + access cards row */
.cv-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(340px,1fr));
  gap:24px;align-items:start}

/* Card h3 (not dv-card__title which is h2 on the domain page) */
.cv-card-title{margin:0;font-size:22px;font-weight:600;
  color:var(--t7-dark-purple)}

/* Invite form: email input fills, button follows */
.cv-invite-form{margin:12px 0 4px}

/* Viewer list */
.cv-viewer-list{margin:12px 0 0;padding:0;list-style:none;
  border-top:1px solid var(--t7-warm-gray)}
.cv-viewer{display:flex;justify-content:space-between;align-items:center;
  gap:12px;padding:10px 0;border-bottom:1px solid var(--t7-khaki)}
.cv-viewer:last-child{border-bottom:0}
.cv-viewer__info{display:flex;flex-direction:column;gap:2px;min-width:0}
.cv-viewer__email{font-weight:600;font-size:14px;word-break:break-all}
.cv-viewer__sub{font-size:12px;color:var(--t7-muted)}
.cv-viewer__status{font-size:12px;color:var(--t7-muted)}
.cv-viewer-empty{margin-top:12px}

/* Remove link in viewer list */
.cv-viewer__remove-form{margin:0;flex-shrink:0}
.cv-viewer__remove{font:inherit;font-size:13px;background:none;border:0;
  padding:0;color:var(--t7-muted);text-decoration:underline;
  text-underline-offset:3px;cursor:pointer}
.cv-viewer__remove:hover{color:var(--t7-dark-purple)}

/* Narrow stacking: rail above main at ≤900px */
@media (max-width:900px){
  .cv-layout{grid-template-columns:minmax(0,1fr);gap:28px}
  .cv-rail{position:static;flex-direction:column}
  .cv-name{font-size:32px}
}
@media (max-width:640px){
  .cv-cards{grid-template-columns:minmax(0,1fr)}
  .cv-summary__score{font-size:28px}
}
