/* FIDMAT — built to the Claude Design handoff.
   Tokens taken verbatim from "Developer Handoff Spec" §1.1–§1.6 and from the
   HTML/CSS exports, which are the authority where the two differ.

   Two things intentionally NOT taken from the prototypes, per spec §7.1:
   the #E4EEEB outer desk background and the 10px page inset — both are
   artefacts of previewing a page inside a page. */

:root {
  /* §1.1 Colour palette — complete list */
  --brand-green: #006443;
  --brand-green-dark: #00432b;
  --ink: #16261F;
  --ink-2: #33453D;
  --ink-3: #4B5A54;
  --muted: #5A6862;
  --muted-2: #7C8B85;
  --muted-3: #8A9892;
  --disabled-text: #A8B8B1;
  --surface: #FFFFFF;
  --page-bg: #EEF5F2;
  --page-bg-2: #E4EEEB;
  --track: #D8E4DF;
  --line-strong: #B9CCC4;
  --swirl-unfilled: #CFE3DD;
  --connector: #AFC3BA;
  --legend-dot-border: #9AACA4;
  --band-label-pale: #3F8478;
  --deficit: oklch(48% 0.13 45);

  /* §1.2 Band fills. NOTE: the fills are the design's; the THRESHOLDS are
     the scoring engine's (1.75 / 2.5 / 3.25), not the spec's 1/2/3.
     See app/README.md — "Band thresholds" for why. */
  --band-foundation: #DCEEEA;
  --band-developing: #88C8C8;
  --band-established: #80B038;
  --band-advanced: #006443;

  --on-foundation: #26443A;
  --on-developing: #FFFFFF;
  --on-established: #17330A;
  --on-advanced: #FFFFFF;

  /* Label on white — pale bands darken for contrast (§1.4.1) */
  --label-foundation: #3F8478;
  --label-developing: #3F8478;
  --label-established: #80B038;
  --label-advanced: #006443;

  /* AI Readiness bar fill uses its own map: the Foundation fill is too pale
     to read on the #EEF5F2 track (§1.2) */
  --bar-foundation: #A6C9C2;
  --bar-developing: #88C8C8;
  --bar-established: #80B038;
  --bar-advanced: #006443;

  /* Alpha values used verbatim (§1.1) */
  --border-hairline: rgba(22, 38, 31, .08);
  --border-column: rgba(22, 38, 31, .06);
  --border-card: rgba(22, 38, 31, .14);
  --rule: rgba(22, 38, 31, .1);
  --selected-fill: rgba(0, 96, 64, .05);
  --row-hover: rgba(0, 96, 64, .055);

  --card-shadow: 0 12px 32px rgba(22, 38, 31, .08);
  --tooltip-shadow: 0 8px 20px rgba(22, 38, 31, .18);
}

* { box-sizing: border-box; }

/* NOT `height: 100%` — that pins the body box to the viewport, so a view
   taller than one screen (the 50-row admin table) overflows past the footer
   instead of pushing it down. `min-height` fills the screen when content is
   short and grows when it is not. The survey sets an explicit height only
   while it is locked. */
body {
  margin: 0;
  background: var(--page-bg);
  color: var(--ink);
  font-family: Roboto, "Segoe UI", system-ui, -apple-system, sans-serif;
  font-size: 15px;
  line-height: 1.55;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

a { color: var(--brand-green); text-decoration: none; }
a:hover { color: var(--brand-green-dark); }

/* §7.2 — focus-visible on every interactive element. None of the prototypes
   had them; keyboard users could not see where they were. */
:focus-visible {
  outline: 3px solid var(--brand-green);
  outline-offset: 2px;
  border-radius: 4px;
}

/* §7.2 — prefers-reduced-motion jumps to the final state. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-delay: 0ms !important;
    transition-duration: .001ms !important;
  }
}

/* ── §1.5 Shared header ──────────────────────────────────────────── */

.site-header {
  background: var(--surface);
  border-bottom: 1px solid var(--border-hairline);
  padding: 0 56px;
  flex-shrink: 0;
  position: sticky;
  top: 0;
  z-index: 20;
}

/**
 * Survey screens lock the viewport so the header and the progress bar never
 * scroll away — branding and "where am I" stay on screen while presenting.
 * Applied only when the survey is showing, so the landing and the report
 * keep normal document scrolling.
 *
 * Guarded on height as well as width: below about 560px of viewport the
 * fixed chrome would leave too little room for a question, so it reverts to
 * ordinary scrolling with the sticky fallback.
 */
@media (min-width: 720px) and (min-height: 560px) {
  body.survey-locked { height: 100vh; overflow: hidden; }
  body.survey-locked main,
  body.survey-locked #view-survey { flex: 1 1 0; min-height: 0; }
}

.header-bar {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 88px;
}

.header-left { display: flex; align-items: center; gap: 16px; }
.header-logo { height: 50px; width: auto; }
.header-divider { width: 1px; height: 34px; background: var(--border-card); flex-shrink: 0; }

.wordmark {
  font-family: Montserrat, sans-serif;
  font-weight: 800;
  font-size: 19px;
  color: var(--ink);
  letter-spacing: .01em;
  line-height: 1.1;
}

.brand-sub {
  font-family: Roboto, sans-serif;
  font-size: 13px;
  color: var(--muted-2);
  margin-top: 3px;
}

.saved-note { font-size: 12.5px; color: var(--muted-3); }

.ref-pill {
  font-family: Montserrat, sans-serif;
  font-weight: 700;
  font-size: 12px;
  color: var(--muted);
  background: var(--page-bg);
  border-radius: 100px;
  padding: 6px 14px;
  white-space: nowrap;
}

/* ── §1.6 Shared footer ──────────────────────────────────────────── */

.site-footer {
  background: var(--surface);
  border-top: 1px solid var(--border-hairline);
  padding: 16px 56px;
  flex-shrink: 0;
}

.footer-bar {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
}

.footer-wordmark { font-family: Montserrat, sans-serif; font-weight: 700; font-size: 13px; color: var(--brand-green); }
.footer-centre { font-size: 12px; color: var(--muted-2); }
.footer-links { display: flex; gap: 18px; font-size: 12px; }

/* ── Shared main ─────────────────────────────────────────────────── */

/**
 * `flex: 1 0 auto`, NOT `flex: 1`.
 *
 * `flex: 1` means `flex-basis: 0`, which makes these contribute nothing to
 * the body's content height. Body then settles at exactly 100vh and any
 * taller view — the 50-row admin table, the county grid — overflows past
 * the footer instead of pushing it down. `1 0 auto` grows to fill a short
 * screen and refuses to shrink below its content on a long one.
 *
 * Two views deliberately opt back into a bounded box below, because their
 * internal proportions depend on a definite height.
 */
main { flex: 1 0 auto; display: flex; flex-direction: column; }
.view { flex: 1 0 auto; display: flex; flex-direction: column; }
[hidden] { display: none !important; }

/* The report no longer opts into a bounded box: its sections carry their own
   minimum heights instead, so nothing is squeezed below the size its content
   needs and nothing has to be clipped to hide the overflow. */

/* Buttons — all Montserrat 700, pill radius 100px (§1.3) */
.btn {
  font-family: Montserrat, sans-serif;
  font-weight: 700;
  border-radius: 100px;
  cursor: pointer;
  border: none;
  transition: background .15s, color .15s, border-color .15s;
}

.btn-primary {
  font-size: 15.5px;
  color: #fff;
  background: var(--brand-green);
  padding: 16px 32px;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  justify-content: center;
}
.btn-primary:hover { background: var(--brand-green-dark); }

.btn-nav {
  font-size: 14.5px;
  color: #fff;
  background: var(--brand-green);
  padding: 14px 30px;
}
.btn-nav[disabled] { background: var(--page-bg-2); color: var(--disabled-text); cursor: not-allowed; }

.btn-back {
  font-size: 14.5px;
  color: var(--brand-green);
  background: transparent;
  border: 1.5px solid rgba(0, 96, 64, .35);
  padding: 13px 26px;
}
.btn-back[disabled] { opacity: .45; cursor: not-allowed; }

.btn-tertiary {
  font-size: 12px;
  color: var(--brand-green);
  background: transparent;
  border: 1.5px solid rgba(0, 96, 64, .3);
  padding: 7px 14px;
  white-space: nowrap;
  flex-shrink: 0;
}

/* ── §2 Landing ──────────────────────────────────────────────────── */

.landing-main {
  flex: 1;
  display: flex;
  align-items: center;
  padding: 64px 56px 80px;
}

.landing-col { max-width: 560px; margin: 0 auto; width: 100%; }

.hero-headline {
  font-family: Montserrat, sans-serif;
  font-weight: 800;
  font-size: 44px;
  line-height: 1.1;
  letter-spacing: -.02em;
  color: var(--ink);
  margin: 0 0 20px;
  text-wrap: pretty;
}

.hero-subtext {
  font-size: 17.5px;
  line-height: 1.55;
  color: var(--muted);
  margin: 0 0 36px;
  max-width: 480px;
}

.meta-line { font-size: 13px; color: var(--muted-3); margin-top: 16px; }
.landing-rule { height: 1px; background: var(--rule); margin: 44px 0 30px; }

/* §2.5 — the prototype DISPLAYS a reference code, because it already knows
   the visitor. Production takes it as a credential, so this is a real input
   and has to look like one: the prototype's flat inset chip read as static
   text. White fill and a solid border make the affordance unambiguous while
   keeping the reference-code typography. */
.ref-row { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; margin-bottom: 4px; }

.ref-label {
  font-family: Montserrat, sans-serif;
  font-weight: 700;
  font-size: 13px;
  color: var(--ink);
}

.ref-input {
  font-family: Montserrat, sans-serif;
  font-weight: 700;
  font-size: 17px;
  letter-spacing: .04em;
  color: var(--ink);
  background: var(--surface);
  border: 1.5px solid var(--line-strong);
  border-radius: 10px;
  padding: 13px 16px;
  width: 260px;
  max-width: 100%;
  text-transform: uppercase;
  transition: border-color .15s, box-shadow .15s;
}
.ref-input::placeholder { color: var(--muted-3); font-weight: 500; letter-spacing: .02em; }
.ref-input:hover { border-color: var(--muted-2); }
.ref-input:focus {
  outline: none;
  border-color: var(--brand-green);
  box-shadow: inset 0 0 0 1px var(--brand-green);
}
.ref-input[aria-invalid="true"] { border-color: var(--deficit); }

.ref-helper { font-size: 12.5px; line-height: 1.55; color: var(--muted-3); margin: 0 0 20px; max-width: 460px; }
.login-error { color: var(--deficit); font-size: 13px; margin: -12px 0 18px; font-weight: 500; }

/* ── §4 Survey ───────────────────────────────────────────────────── */

.survey-container { max-width: 760px; margin: 0 auto; width: 100%; }

/* Pinned survey chrome. On a locked viewport it simply does not move; on
   short or mobile viewports it falls back to sticky, so the same context
   stays visible without fighting mobile browser chrome. */
.survey-fixed {
  flex-shrink: 0;
  background: var(--page-bg);
  border-bottom: 1px solid var(--rule);
  padding: 20px 56px 14px;
  position: sticky;
  top: 0;
  z-index: 15;
}

.progress-track { height: 8px; border-radius: 4px; background: var(--track); overflow: hidden; }
.progress-fill { height: 100%; border-radius: 4px; background: var(--brand-green); transition: width .35s cubic-bezier(.16, 1, .3, 1); }

.progress-meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-top: 10px;
}

.progress-caption { font-size: 12.5px; color: var(--muted-3); white-space: nowrap; flex-shrink: 0; }

/* The question area is the only thing that scrolls. */
.survey-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 28px 56px 48px;
}

.page-description {
  font-size: 14px;
  line-height: 1.55;
  color: var(--muted);
  margin: 0 0 18px;
  max-width: 62ch;
}

.survey-card { background: var(--surface); border-radius: 20px; padding: 38px 40px; }

.section-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--brand-green);
  text-transform: uppercase;
  letter-spacing: .07em;
  margin: 0;
  line-height: 1.35;
}

.question-block + .question-block { margin-top: 38px; padding-top: 34px; border-top: 1px solid var(--rule); }

.question-title {
  font-family: Montserrat, sans-serif;
  font-weight: 700;
  font-size: 25px;
  line-height: 1.32;
  letter-spacing: -.01em;
  color: var(--ink);
  margin: 0 0 30px;
  text-wrap: pretty;
  padding: 0;
  display: block;
}

.question-block fieldset { border: none; margin: 0; padding: 0; }
.question-help { font-size: 14px; line-height: 1.55; color: var(--muted); margin: -18px 0 24px; max-width: 62ch; }

.options { display: flex; flex-direction: column; gap: 12px; }

/* §3.2 selectable option card — and §1.4.4: selection is never colour-only.
   Border colour, inset ring and radio dot all change. */
.option {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  width: 100%;
  text-align: left;
  padding: 19px 22px;
  min-height: 56px;
  border-radius: 14px;
  cursor: pointer;
  font: inherit;
  background: var(--surface);
  border: 1.5px solid var(--border-card);
  transition: background .15s, border-color .15s, box-shadow .15s;
}
.option:hover { border-color: var(--line-strong); }
.option.selected {
  background: var(--selected-fill);
  border-color: var(--brand-green);
  box-shadow: inset 0 0 0 1px var(--brand-green);
}

.option-mark {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  margin-top: 1px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--line-strong);
  background: var(--surface);
  transition: border-color .15s;
}
.option.selected .option-mark { border-color: var(--brand-green); }

.option-mark.square { border-radius: 6px; }

.option-dot {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--brand-green);
  transform: scale(0);
  transition: transform .18s cubic-bezier(.16, 1, .3, 1);
}
.option-mark.square .option-dot { border-radius: 2px; }
.option.selected .option-dot { transform: scale(1); }

.option-text { font-size: 15.5px; line-height: 1.55; color: var(--ink-2); text-wrap: pretty; }
.option.selected .option-text { color: var(--ink); }

.text-input, .select-input {
  width: 100%;
  max-width: 32rem;
  padding: 14px 16px;
  font: inherit;
  font-size: 15.5px;
  border: 1.5px solid var(--border-card);
  border-radius: 14px;
  background: var(--surface);
  color: var(--ink);
}

.comment-area { margin-top: 12px; }

/* Validation. Deficits are not red anywhere in this product (§1.4.3), so
   the unanswered state uses the same muted brick as a negative gap value. */
.question-block.invalid {
  border-left: 3px solid var(--deficit);
  margin-left: -22px;
  padding-left: 19px;
}

.question-error {
  color: var(--deficit);
  font-size: 13px;
  font-weight: 500;
  margin: 0 0 14px;
}

.question-block.invalid .option { border-color: rgba(157, 74, 44, .35); }

.validation-summary {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  background: var(--surface);
  border-left: 3px solid var(--deficit);
  border-radius: 0 10px 10px 0;
  color: var(--ink-2);
  font-size: 13.5px;
  padding: 12px 16px;
  margin: 20px 0 0;
}

.validation-jump {
  font-family: Montserrat, sans-serif;
  font-weight: 700;
  font-size: 12px;
  color: var(--brand-green);
  background: transparent;
  border: 1.5px solid rgba(0, 96, 64, .3);
  border-radius: 100px;
  padding: 6px 13px;
  cursor: pointer;
}
.validation-jump:hover { border-color: var(--brand-green); }

.nav-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 32px; }

/* Ranking */
.rank-list { display: flex; flex-direction: column; gap: 10px; }
.rank-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 18px;
  border: 1.5px solid var(--border-card);
  border-radius: 14px;
  background: var(--surface);
}
.rank-num {
  font-family: Montserrat, sans-serif;
  font-weight: 700;
  font-size: 12px;
  color: var(--brand-green);
  background: var(--page-bg);
  width: 26px; height: 26px;
  border-radius: 50%;
  display: grid; place-items: center;
  flex-shrink: 0;
}
.rank-label { flex: 1; font-size: 14.5px; line-height: 1.45; }
.rank-move {
  background: transparent;
  border: 1.5px solid rgba(0, 96, 64, .3);
  border-radius: 100px;
  cursor: pointer;
  width: 30px; height: 30px;
  color: var(--brand-green);
  flex-shrink: 0;
}
.rank-move[disabled] { opacity: .3; cursor: not-allowed; }

/* Matrix */
.matrix { width: 100%; border-collapse: collapse; }
.matrix th {
  font-family: Montserrat, sans-serif;
  font-weight: 700;
  font-size: 11.5px;
  color: var(--muted-2);
  padding: 6px 8px;
  text-align: center;
  line-height: 1.3;
}
.matrix th:first-child { text-align: left; width: 38%; }
.matrix td { text-align: center; padding: 12px 8px; border-top: 1px solid var(--rule); }
.matrix td:first-child { text-align: left; font-size: 14.5px; color: var(--ink-2); }
.matrix input { accent-color: var(--brand-green); width: 20px; height: 20px; }

/* Persona confirmation box — §3.2 */
.persona-box {
  background: var(--page-bg);
  border-radius: 14px;
  padding: 16px 20px;
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 28px;
}
.persona-text { flex: 1; }
.persona-lead { font-size: 14.5px; color: var(--ink-2); margin: 0; }
.persona-lead strong { color: var(--ink); }
.persona-desc { font-size: 12.5px; color: var(--muted-2); margin: 3px 0 0; }

/* ── §5 Dashboard ────────────────────────────────────────────────── */

/**
 * `flex: 1 0 auto`, not `flex: 1`.
 *
 * With a zero basis the report was bounded to whatever the viewport left
 * over, which squeezed the row card below the height its own content needs.
 * The score column then clipped (it carried `overflow: hidden` from the
 * design export) and the gauge was cut off at the bottom on any screen
 * shorter than about 1000px.
 *
 * Minimum heights below keep the export's proportions readable while
 * letting the report grow — and the page scroll — rather than truncate.
 * Spec §1.7 asks for a one-screen report on desktop; it still is on a
 * desktop-sized screen, but a clipped report is worse than a short scroll.
 */
.report-main { flex: 1 0 auto; padding: 26px 56px 20px; display: flex; }
.report-container { max-width: 1808px; width: 100%; margin: 0 auto; display: flex; flex-direction: column; flex: 1 0 auto; }

.title-block { margin-bottom: 16px; }
.eyebrow {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--muted-2);
  text-transform: uppercase;
  letter-spacing: .06em;
}
.report-h1 { font-family: Montserrat, sans-serif; font-weight: 800; font-size: 27px; color: var(--ink); margin: 3px 0 6px; }
.report-sub { font-size: 14px; color: var(--muted); margin: 0; }

.row-card {
  display: flex;
  background: var(--surface);
  border-radius: 20px;
  box-shadow: var(--card-shadow);
  margin-bottom: 18px;
  flex: 1 0 auto;
  /* Enough for the tallest column's content — the score device, its band
     pill, delta line, comparison bars and footnote. */
  min-height: 430px;
}

.chart-col { display: flex; flex-direction: column; }
/* NOT overflow: hidden. The export sets it, but the export's gauge column
   never has to fit real data on a laptop screen — here it silently cut the
   comparison bars off the bottom of the score card. */
.chart-col-1 { flex: 1.05; padding: 18px 20px 20px; text-align: center; border-right: 1px solid var(--border-column); align-items: center; }
.chart-col-2 { flex: 1.25; padding: 22px 24px; border-right: 1px solid var(--border-column); }
.chart-col-3 { flex: 1.55; padding: 22px 28px; }

.chart-label {
  font-family: Montserrat, sans-serif;
  font-weight: 700;
  font-size: 16.5px;
  color: var(--ink);
  text-align: center;
  margin-bottom: 14px;
  flex-shrink: 0;
}

.chart-body { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; }

/* Overall score device */
.gauge-wrap { position: relative; width: fit-content; margin: 0 auto; }
.gauge-centre {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  opacity: 0; animation: scoreReveal .5s ease-out 1s forwards;
}
.gauge-score { font-family: Montserrat, sans-serif; font-weight: 800; font-size: 34px; line-height: 1.1; }
.gauge-caption { font-size: 13px; color: var(--muted-2); }

.band-pill {
  display: inline-block;
  padding: 5px 16px;
  border-radius: 100px;
  font-family: Montserrat, sans-serif;
  font-weight: 700;
  font-size: 13px;
  margin-top: 4px;
}

.delta-line { font-family: Montserrat, sans-serif; font-weight: 700; font-size: 13.5px; margin-top: 9px; }
.delta-up { color: var(--brand-green); }
.delta-down { color: var(--deficit); }

.compare-wrap { width: 190px; margin-top: 11px; display: flex; flex-direction: column; gap: 4px; }
.compare-row { display: flex; align-items: center; gap: 7px; }
.compare-label { width: 48px; text-align: left; font-size: 11px; flex-shrink: 0; }
.compare-label.you { font-weight: 700; color: var(--ink); }
.compare-label.avg { color: var(--muted-3); }
.compare-track { position: relative; flex: 1; height: 7px; border-radius: 3px; background: var(--page-bg); overflow: hidden; }
.compare-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 3px; }
.compare-val { width: 32px; text-align: right; font-family: Montserrat, sans-serif; font-weight: 700; font-size: 11.5px; flex-shrink: 0; }
.compare-val.you { color: var(--ink); }
.compare-val.avg { color: var(--muted-3); }
.compare-foot { font-size: 11px; color: var(--muted-3); margin-top: 3px; text-align: center; }

/* Coxcomb */
.cox-wrap { position: relative; margin: -26px auto 0; }
.cox-label {
  position: absolute;
  transform: translate(-50%, -50%);
  text-align: center;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.25;
  color: var(--muted);
  transition: color .18s, left .18s cubic-bezier(.16,1,.3,1), top .18s cubic-bezier(.16,1,.3,1);
}
.cox-label.hot { font-weight: 700; color: var(--ink); }

.chart-tooltip {
  position: absolute;
  transform: translate(-50%, -50%);
  background: var(--surface);
  border-radius: 10px;
  padding: 8px 12px;
  box-shadow: var(--tooltip-shadow);
  pointer-events: none;
  z-index: 5;
  white-space: nowrap;
}
.tooltip-name { font-family: Montserrat, sans-serif; font-weight: 700; font-size: 12.5px; color: var(--ink); }
.tooltip-value { font-size: 12px; color: var(--muted); }

/* Dumbbell gap chart */
.gap-list { position: relative; padding-top: 2px; width: fit-content; margin: 0 auto; }
.gap-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  height: 46px;
  padding: 0 10px;
  margin-left: -10px;
  border-radius: 8px;
  background: transparent;
  transition: background .18s;
}
.gap-row.hot { background: var(--row-hover); }
.gap-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; transition: transform .18s; }
.gap-row.hot .gap-dot { transform: scale(1.35); }
.gap-name { width: 152px; flex-shrink: 0; font-weight: 700; font-size: 13px; color: var(--ink); line-height: 1.2; }
.gap-track-wrap { position: relative; width: 230px; flex: 0 0 auto; height: 2px; }
.gap-track { position: absolute; inset: 0; background: var(--page-bg); }
.gap-connector { position: absolute; top: 50%; height: 4px; border-radius: 2px; background: var(--connector); transform: translateY(-50%); }
.gap-bench-dot {
  position: absolute; top: 50%;
  width: 15px; height: 15px; border-radius: 50%;
  background: var(--surface); border: 3px solid var(--muted-2);
  transform: translate(-50%, -50%);
  box-shadow: 0 1px 3px rgba(22, 38, 31, .15);
  transition: transform .15s;
}
.gap-score-dot {
  position: absolute; top: 50%;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--brand-green);
  transform: translate(-50%, -50%);
  box-shadow: 0 2px 5px rgba(0, 96, 64, .35);
  transition: transform .15s;
}
.gap-row.hot .gap-bench-dot, .gap-row.hot .gap-score-dot { transform: translate(-50%, -50%) scale(1.25); }
.gap-value {
  width: 44px; flex-shrink: 0; text-align: right;
  font-family: Montserrat, sans-serif; font-weight: 800; font-size: 14.5px;
}
.gap-value.up { color: var(--brand-green); }
.gap-value.down { color: var(--deficit); }

.gap-legend { display: flex; align-items: center; gap: 8px; margin-top: 10px; flex-wrap: wrap; font-size: 12px; color: var(--muted); }
.legend-dot-business { width: 10px; height: 10px; border-radius: 50%; background: var(--brand-green); display: inline-block; margin-right: 4px; }
.legend-dot-bench { width: 10px; height: 10px; border-radius: 50%; background: var(--surface); border: 2px solid var(--legend-dot-border); display: inline-block; margin: 0 4px 0 14px; }

/* Bottom panels */
/* Enough for six AI capability bars plus the readiness indicators. */
.panels-row { display: flex; gap: 18px; flex: 0 0 auto; min-height: 290px; }
.panel {
  flex: 1;
  background: var(--surface);
  border-radius: 20px;
  padding: 20px 24px;
  box-shadow: var(--card-shadow);
  display: flex;
  flex-direction: column;
}
.panel-title { font-family: Montserrat, sans-serif; font-weight: 700; font-size: 15.5px; color: var(--ink); margin-bottom: 3px; }
.panel-sub { font-size: 12px; color: var(--muted-2); margin-bottom: 12px; }

.readiness-list { flex: 1; display: flex; flex-direction: column; justify-content: space-evenly; }
.readiness-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 8px; }
.readiness-label { font-weight: 700; font-size: 12.5px; color: var(--ink); }
.readiness-band { font-family: Montserrat, sans-serif; font-weight: 700; font-size: 11px; white-space: nowrap; }
.readiness-track {
  position: relative; height: 6px; border-radius: 4px; margin-top: 5px; overflow: visible;
  background: linear-gradient(to right,
    var(--band-foundation) 0%, var(--band-foundation) 25%,
    var(--band-developing) 25%, var(--band-developing) 50%,
    var(--band-established) 50%, var(--band-established) 75%,
    var(--band-advanced) 75%, var(--band-advanced) 100%);
}
.readiness-marker {
  position: absolute; top: 50%;
  width: 13px; height: 13px; border-radius: 50%;
  border: 2.5px solid var(--surface);
  box-shadow: 0 1px 4px rgba(22, 38, 31, .3);
  transform: translate(-50%, -50%);
}
.readiness-body { font-size: 11.5px; color: var(--muted); line-height: 1.35; margin-top: 3px; }

.ai-list { flex: 1; display: flex; flex-direction: column; justify-content: space-evenly; padding: 2px 0 4px; }
.ai-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.ai-label { font-weight: 500; font-size: 12.5px; color: var(--ink); line-height: 1.25; }
.ai-band { font-family: Montserrat, sans-serif; font-weight: 700; font-size: 10.5px; white-space: nowrap; flex-shrink: 0; }
.ai-track { position: relative; height: 7px; border-radius: 3px; background: var(--page-bg); margin-top: 5px; }
.ai-fill { position: absolute; left: 0; top: 1px; bottom: 1px; border-radius: 3px; transform-origin: left center; }
.ai-tick { position: absolute; top: -3px; bottom: -3px; width: 2px; border-radius: 1px; background: var(--muted-2); transform: translateX(-50%); }
.ai-legend { display: flex; align-items: center; gap: 7px; flex-shrink: 0; margin-top: 14px; font-size: 11.5px; color: var(--muted-2); }
.ai-legend-tick { width: 2px; height: 11px; border-radius: 1px; background: var(--muted-2); display: inline-block; flex-shrink: 0; }

/* Why a comparison is absent. Never leave the space silently blank — an
   unexplained gap reads as a broken panel rather than a respected choice. */
.absence-note {
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--muted-2);
  background: var(--page-bg);
  border-radius: 8px;
  padding: 8px 11px;
  margin-top: 12px;
  max-width: 260px;
  text-align: left;
}

/* ── DII / DETE ──────────────────────────────────────────────────
   Built from existing tokens and the report's card styling. The spec's
   §6.3 needle gauge is deliberately not built — see app/README.md. */

/* Tabs on the report, reusing the admin tab styling rather than a second
   set. Both panes are built once and toggled, never re-rendered. */
.report-tabs { margin-bottom: 16px; }
.report-pane { display: flex; flex-direction: column; flex: 1 0 auto; }
.report-pane[hidden] { display: none; }

.dii-card {
  background: var(--surface);
  border-radius: 20px;
  padding: 20px 24px 18px;
  box-shadow: var(--card-shadow);
}

.dii-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.dii-title { font-family: Montserrat, sans-serif; font-weight: 800; font-size: 20px; color: var(--ink); margin: 2px 0 4px; }
.dii-intro { font-size: 13px; color: var(--muted); margin: 0; max-width: 62ch; }

.dii-score-box { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.dii-score { display: flex; align-items: baseline; gap: 6px; }
.dii-score-value { font-family: Montserrat, sans-serif; font-weight: 800; font-size: 34px; line-height: 1; }
.dii-score-of { font-weight: 500; font-size: 16px; color: var(--muted-2); }
.dii-pill { font-size: 13px; padding: 6px 14px; margin-top: 0; }

/* The full scale, always — the business sees where it sits, not just its
   own band in isolation. */
.dii-scale { display: flex; gap: 4px; margin: 16px 0 14px; }
.dii-seg {
  flex: 1;
  border-radius: 6px;
  padding: 7px 10px;
  display: flex;
  flex-direction: column;
  opacity: .45;
  transition: opacity .2s;
}
.dii-seg.current { opacity: 1; box-shadow: inset 0 0 0 2px var(--ink); }
.dii-seg-label { font-family: Montserrat, sans-serif; font-weight: 700; font-size: 11px; color: var(--ink); }
.dii-seg-range { font-size: 10.5px; color: var(--ink-2); }

.dii-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px 14px; }
@media (max-width: 900px) { .dii-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .dii-grid { grid-template-columns: 1fr; } }

.dii-cell { display: flex; align-items: flex-start; gap: 8px; padding: 5px 0; font-size: 12.5px; }
.dii-dot {
  width: 11px; height: 11px; border-radius: 50%; flex-shrink: 0; margin-top: 3px;
  background: var(--surface); border: 2px solid var(--line-strong);
}
.dii-dot.on { background: var(--brand-green); border-color: var(--brand-green); }
.dii-cell-text { display: flex; flex-direction: column; min-width: 0; }
.dii-cell-label { color: var(--muted-2); line-height: 1.3; }
.dii-cell.on .dii-cell-label { color: var(--ink); }
.dii-cell-source { font-size: 10.5px; color: var(--muted-3); }

.dii-foot { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--rule); }
.dii-cohort { font-size: 12.5px; margin: 0 0 6px; }
.dii-cohort-label { color: var(--muted-2); }
.dii-cohort strong { color: var(--ink-2); }
.dii-cohort-note { color: var(--muted-3); }
.dii-disclosure { font-size: 11.5px; line-height: 1.55; color: var(--muted-2); margin: 0; max-width: 90ch; }

.flag-note {
  border-left: 3px solid var(--band-developing);
  background: var(--page-bg);
  padding: 10px 14px;
  border-radius: 0 10px 10px 0;
  font-size: 12px;
  color: var(--ink-2);
  line-height: 1.45;
  margin-top: 10px;
}

/* ── Admin / My Companies ────────────────────────────────────────
   Deliberately built from existing tokens and the report's band pill.
   Nothing new is designed here. */

.admin-main { flex: 1 0 auto; display: flex; padding: 26px 56px 0; min-height: 0; }
.admin-container { max-width: 1200px; width: 100%; margin: 0 auto; display: flex; flex-direction: column; min-height: 0; }

/* Title, summary strip, tabs and owner selector — one pinned block. */
.admin-chrome { flex-shrink: 0; }

/* The only thing that scrolls. */
.admin-scroll { flex: 1 0 auto; min-height: 0; padding-bottom: 40px; }

/**
 * Viewport lock, same principle as the survey screen. Without it the chrome
 * scrolls away and the tabs, counts and owner selector are unreachable part
 * way down a 50-company list.
 *
 * Guarded on height as well as width: on a short screen the pinned block
 * would leave too little room for rows, so it reverts to ordinary scrolling.
 */
@media (min-width: 720px) and (min-height: 620px) {
  body[data-view="view-admin"] { height: 100vh; overflow: hidden; }
  body[data-view="view-admin"] main,
  body[data-view="view-admin"] #view-admin { flex: 1 1 0; min-height: 0; }
  body[data-view="view-admin"] .admin-main { flex: 1 1 0; }
  body[data-view="view-admin"] .admin-scroll { flex: 1 1 0; overflow-y: auto; overscroll-behavior: contain; }

  /* Sticky now resolves against .admin-scroll, not the document. */
  body[data-view="view-admin"] .admin-table th { top: 0; }
  body[data-view="view-admin"] .admin-groups.sticky-heads .admin-group-head { top: 0; }
  body[data-view="view-admin"] .map-detail { top: 0; max-height: calc(100vh - 260px); }
}

.admin-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 18px;
}

.admin-stat {
  background: var(--surface);
  border-radius: 12px;
  padding: 12px 18px;
  box-shadow: var(--card-shadow);
  display: flex;
  flex-direction: column;
  min-width: 120px;
}
.admin-stat-value { font-family: Montserrat, sans-serif; font-weight: 800; font-size: 22px; color: var(--ink); line-height: 1.15; }
.admin-stat-label { font-size: 11.5px; color: var(--muted-2); margin-top: 2px; }

.admin-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.admin-tabs { display: flex; gap: 8px; flex-wrap: wrap; }

.admin-tab {
  font-family: Montserrat, sans-serif;
  font-weight: 700;
  font-size: 12.5px;
  padding: 8px 16px;
  border-radius: 100px;
  border: 1.5px solid rgba(0, 96, 64, .3);
  background: transparent;
  color: var(--brand-green);
  cursor: pointer;
  transition: background .15s, color .15s;
}
.admin-tab:hover { border-color: var(--brand-green); }
.admin-tab.active { background: var(--brand-green); border-color: var(--brand-green); color: #fff; }

.admin-filter { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--muted-2); }
.admin-scope-note { font-size: 12px; color: var(--muted-2); }
.admin-select {
  font: inherit;
  font-size: 12.5px;
  padding: 7px 10px;
  border: 1.5px solid var(--border-card);
  border-radius: 8px;
  background: var(--surface);
  color: var(--ink);
}

.admin-groups { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 14px; }

.admin-group {
  background: var(--surface);
  border-radius: 14px;
  box-shadow: var(--card-shadow);
  padding: 14px 16px 8px;
}

.admin-group-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-family: Montserrat, sans-serif;
  font-weight: 700;
  font-size: 14px;
  color: var(--ink);
  margin: 0 0 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--rule);
}

/**
 * Band view only: each group's heading pins to the top of its own column
 * while that column's cards scroll beneath it.
 *
 * Sticky resolves against .admin-scroll and stays inside its own
 * .admin-group, so the four bands pin and release independently. The
 * heading is pulled out to the card's full width and given an opaque
 * background, or rows would show through it once pinned.
 */
.admin-groups.sticky-heads .admin-group { padding-top: 0; }

.admin-groups.sticky-heads .admin-group-head {
  position: sticky;
  /* Clears the site header when the page scrolls normally; the lock below
     re-anchors it to 0, since sticky then resolves against .admin-scroll. */
  top: 88px;
  z-index: 2;
  background: var(--surface);
  margin: 0 -16px 8px;
  padding: 14px 16px 8px;
  border-radius: 14px 14px 0 0;
}

.admin-count {
  font-size: 12px;
  color: var(--brand-green);
  background: var(--page-bg);
  border-radius: 100px;
  padding: 2px 10px;
  flex-shrink: 0;
}

.admin-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--rule);
}
.admin-row:last-child { border-bottom: none; }

.admin-row-main { display: flex; flex-direction: column; min-width: 0; }
.admin-name { font-size: 13px; font-weight: 500; color: var(--ink); }
.admin-sub { font-size: 11px; color: var(--muted-2); }

.admin-row-meta { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.admin-score { font-family: Montserrat, sans-serif; font-weight: 700; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }

.band-pill-sm { font-size: 10px; padding: 3px 10px; margin-top: 0; }

.admin-flag {
  font-size: 10px;
  font-weight: 700;
  font-family: Montserrat, sans-serif;
  color: var(--deficit);
  background: var(--page-bg);
  border-radius: 100px;
  padding: 3px 8px;
  white-space: nowrap;
}

/* Drill-through affordance. Navigation only — the server re-checks the
   staff session and scope on every request. */
.openable { cursor: pointer; transition: background .12s; }
.admin-row.openable:hover,
.admin-row.openable:focus-visible { background: var(--row-hover); border-radius: 6px; }
.admin-table tr.openable:hover td,
.admin-table tr.openable:focus-visible td { background: var(--row-hover); }
.admin-table tr.openable:focus-visible { outline: 2px solid var(--brand-green); outline-offset: -2px; }
.openable .admin-name,
.openable .map-company-name { color: var(--brand-green); }
.not-openable { opacity: .65; }

.staff-return {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.staff-return-note { font-size: 12px; color: var(--muted-2); }

.admin-status { font-size: 11px; color: var(--muted-2); white-space: nowrap; }
.admin-status-complete { color: var(--brand-green); }
.admin-status-in_progress { color: var(--muted); }
.admin-status-not_started { color: var(--muted-3); }
.admin-muted { color: var(--muted-3); font-size: 11px; }

/* Table view */
/* NOT overflow-x: auto. Setting one axis to a non-visible value forces the
   other to compute as `auto`, which makes this element a scroll container —
   and a sticky <th> then resolves against a box with no height, so it never
   sticks. The scrolling belongs to .admin-scroll alone. */
.admin-table-wrap {
  background: var(--surface);
  border-radius: 14px;
  box-shadow: var(--card-shadow);
  padding: 6px 16px 12px;
  overflow: visible;
}
.admin-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 12.5px; }

/* Sticky under the 88px site header, so column names stay readable while
   scrolling 50 rows. `separate` borders because collapsed ones detach from
   a sticky cell. */
.admin-table th {
  text-align: left;
  padding: 0;
  border-bottom: 1px solid var(--rule);
  position: sticky;
  top: 88px;
  background: var(--surface);
  z-index: 2;
}
.admin-table td { padding: 9px 10px 9px 0; border-bottom: 1px solid var(--rule); vertical-align: middle; }
.admin-table tr:last-child td { border-bottom: none; }
.admin-cell-name { font-weight: 500; color: var(--ink); }
.admin-num { font-variant-numeric: tabular-nums; color: var(--muted); }
.admin-code { font-family: Montserrat, sans-serif; font-weight: 700; font-size: 11px; color: var(--muted-2); letter-spacing: .03em; }

.admin-sort {
  font-family: Montserrat, sans-serif;
  font-weight: 700;
  font-size: 11px;
  color: var(--muted-2);
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 12px 10px 12px 0;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  text-transform: uppercase;
  letter-spacing: .05em;
}
.admin-sort:hover { color: var(--ink); }
.admin-sort.active { color: var(--brand-green); }
.admin-arrow { font-size: 11px; }

/* Choropleth */

/* Detail sits BESIDE the map, not under it. The map is portrait
   (1000x1310), so side-by-side is the natural arrangement and keeps the
   selected county's breakdown in view without scrolling. Collapses only on
   genuinely narrow screens, where the panel is pushed ABOVE the map so it
   is still the first thing seen after a tap. */
.map-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 270px;
  gap: 16px;
  align-items: start;
}

.map-figure {
  background: var(--surface);
  border-radius: 14px;
  box-shadow: var(--card-shadow);
  padding: 14px 16px 12px;
  position: relative;
  min-width: 0;
}

/* Bounded so the map and its legend fit one screen alongside the panel. */
.map-svg { width: 100%; height: auto; max-height: 66vh; display: block; }

@media (max-width: 780px) {
  .map-layout { grid-template-columns: 1fr; }
  .map-detail { order: -1; }
}

.map-county {
  fill: var(--page-bg);
  stroke: var(--line-strong);
  stroke-width: 1.4;
  stroke-linejoin: round;
  cursor: pointer;
  transition: fill-opacity .15s, stroke-width .15s;
}
.map-county:hover, .map-county.active { fill-opacity: .82; stroke-width: 3; }
.map-county:focus-visible { outline: none; stroke: var(--ink); stroke-width: 3; }

/* Dimmed while a county is pinned, so the selection stays obvious. */
.map-svg.pinned .map-county:not(.active) { fill-opacity: .45; }

.map-outside { fill: #E9EEEC; stroke: #D4DEDA; stroke-width: 1.2; pointer-events: none; }

/* White halo via paint-order so labels stay legible over any band fill. */
.map-label-name,
.map-label-count {
  font-family: Montserrat, sans-serif;
  paint-order: stroke;
  stroke: rgba(255, 255, 255, .9);
  stroke-linejoin: round;
}

.map-label-name { font-weight: 700; font-size: 15px; fill: var(--ink); stroke-width: 3.5px; }
.map-label-count { font-weight: 800; font-size: 17px; fill: var(--brand-green); stroke-width: 3.5px; }

.map-tooltip {
  position: absolute;
  z-index: 6;
  pointer-events: none;
  background: var(--surface);
  border-radius: 9px;
  box-shadow: var(--tooltip-shadow);
  padding: 7px 11px;
  display: flex;
  flex-direction: column;
  white-space: nowrap;
}
.map-tooltip-name { font-family: Montserrat, sans-serif; font-weight: 700; font-size: 12.5px; color: var(--ink); }
.map-tooltip-meta { font-size: 11.5px; color: var(--muted); }

.map-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--rule);
  font-size: 11.5px;
  color: var(--muted);
}
.map-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.map-swatch { width: 12px; height: 12px; border-radius: 3px; border: 1px solid transparent; flex-shrink: 0; display: inline-block; }

/* Sticky under the site header, so it stays put while the page scrolls. */
.map-detail {
  background: var(--surface);
  border-radius: 14px;
  box-shadow: var(--card-shadow);
  padding: 16px 18px;
  position: sticky;
  top: 100px;
  max-height: calc(100vh - 120px);
  overflow-y: auto;
}
.map-detail-eyebrow {
  font-size: 11px; font-weight: 500; color: var(--muted-2);
  text-transform: uppercase; letter-spacing: .06em; margin: 0 0 2px;
}
.map-detail-title { font-family: Montserrat, sans-serif; font-weight: 700; font-size: 17px; color: var(--ink); margin: 0 0 4px; }
.map-detail-meta { font-size: 12.5px; color: var(--muted); margin: 0 0 10px; }
.map-detail-score { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.map-avg-value { font-family: Montserrat, sans-serif; font-weight: 800; font-size: 26px; color: var(--ink); line-height: 1; }
.map-detail-note { font-size: 11px; color: var(--muted-2); margin: 0 0 12px; }
.map-detail-flags { font-size: 11.5px; color: var(--deficit); font-weight: 500; margin: 10px 0 0; }
.map-hint { font-size: 11px; color: var(--muted-3); margin: 12px 0 0; }

.map-breakdown { display: flex; flex-direction: column; gap: 5px; margin-top: 8px; }
.map-band-row { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--ink-2); }
.map-band-row.empty { opacity: .4; }
.map-band-name { flex: 1; }
.map-band-count { font-family: Montserrat, sans-serif; font-weight: 700; font-variant-numeric: tabular-nums; }

.map-companies { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--rule); }
.map-companies-head {
  font-family: Montserrat, sans-serif; font-weight: 700; font-size: 11px;
  text-transform: uppercase; letter-spacing: .05em; color: var(--muted-2); margin: 0 0 6px;
}
.map-company {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 5px 6px; margin: 0 -6px; border-radius: 6px; font-size: 12px;
}
.map-company.openable:hover, .map-company.openable:focus-visible { background: var(--row-hover); }
.map-company-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.map-source { font-size: 11px; color: var(--muted-3); line-height: 1.5; margin: 12px 0 0; max-width: 70ch; }
.map-loading { font-size: 13px; color: var(--muted-2); padding: 40px; text-align: center; }

@media (max-width: 719px) {
  .admin-main { padding: 20px 20px 0; }
  .admin-groups { grid-template-columns: 1fr; }
  .map-detail { position: static; max-height: none; }
  .map-svg { max-height: none; }
  .map-tooltip { display: none; }
}

.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;
}

/* ── Animations (§5, timings compressed — see app/README.md) ─────── */

@keyframes scoreReveal { from { opacity: 0; } to { opacity: 1; } }
@keyframes barGrow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes rowIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@keyframes panelIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }
@keyframes petalGrow { from { opacity: 0; transform: scale(.02); } to { opacity: 1; transform: scale(1); } }
@keyframes ringGrow { from { opacity: 0; transform: scale(.8); } to { opacity: 1; transform: scale(1); } }
@keyframes gapDotIn { from { opacity: 0; transform: translate(-50%, -50%) scale(.2); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
@keyframes gapConnector { from { opacity: 0; transform: translateY(-50%) scaleX(0); } to { opacity: 1; transform: translateY(-50%) scaleX(1); } }
@keyframes swooshFly {
  0% { opacity: 0; transform: scale(.6) rotate(0deg); }
  15% { opacity: 1; transform: scale(.6) rotate(0deg); }
  100% { opacity: 1; transform: scale(1) rotate(720deg); }
}
@keyframes swooshTint {
  0% { fill: var(--logoFill); fill-opacity: 1; }
  30% { fill: var(--logoFill); fill-opacity: 1; }
  100% { fill: var(--bandFill); fill-opacity: .5; }
}

/* ── §1.7 Responsive ─────────────────────────────────────────────── */

@media (max-width: 1099px) {
  .row-card, .panels-row { flex-direction: column; }
  .row-card { flex: 0 0 auto; }
  .panels-row { flex: 0 0 auto; }
  .chart-col-1, .chart-col-2 { border-right: none; border-bottom: 1px solid var(--border-column); }
  .report-main { padding: 20px; }
}

@media (max-width: 719px) {
  .site-header, .site-footer { padding-left: 20px; padding-right: 20px; }
  .header-bar { height: 68px; }
  .header-logo { height: 36px; }
  .header-divider { height: 28px; }
  .wordmark { font-size: 17px; }
  .brand-sub { font-size: 11.5px; }
  .saved-note { display: none; }
  .survey-fixed { padding: 14px 20px 12px; top: 68px; }
  .survey-scroll { padding: 20px 20px 36px; overflow-y: visible; }
  .progress-meta { flex-direction: column; align-items: flex-start; gap: 3px; }
  .landing-main { padding: 40px 24px 48px; }
  .landing-col { max-width: 100%; }
  .hero-headline { font-size: 30px; margin-bottom: 16px; }
  .hero-subtext { font-size: 15.5px; margin-bottom: 28px; }
  .btn-primary { width: 100%; }
  .landing-rule { margin: 32px 0 26px; }
  .survey-card { padding: 24px 20px; }
  .question-title { font-size: 20px; margin-bottom: 22px; }
  .option { padding: 16px; min-height: 62px; }
  .option-text { font-size: 14.5px; }
  .options { gap: 10px; }
  .nav-row { margin-top: 24px; }
  .footer-bar { justify-content: center; text-align: center; }
  .gap-name { width: 84px; font-size: 10.5px; }
  .gap-track-wrap { flex: 1; width: auto; min-width: 0; }
  .gap-row { height: 34px; gap: 6px; }
  .gap-value { width: 34px; font-size: 11.5px; }
  .persona-box { flex-direction: column; align-items: flex-start; gap: 10px; }
}

/* ── DII / DETE report configurator ──────────────────────────────────
   An admin view, so it reuses the admin chrome (.admin-select, .admin-stat,
   .admin-summary) and the report's card shell. Nothing new is designed here:
   the band fills are the same four the report uses, applied inline from the
   API's band names rather than restated as CSS. */

.dii-report-host { display: flex; flex-direction: column; gap: 14px; }

.dr-head { margin-bottom: 2px; }
.dr-title { font-family: Montserrat, sans-serif; font-weight: 800; font-size: 22px; color: var(--ink); margin: 2px 0 4px; }
.dr-scope { font-size: 12.5px; color: var(--muted-2); margin: 0; }

.dr-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px 16px;
  background: var(--surface);
  border-radius: 14px;
  padding: 14px 18px;
  box-shadow: var(--card-shadow);
}
.dr-filter { display: flex; flex-direction: column; gap: 4px; min-width: 150px; }
.dr-filter-label { font-size: 11px; color: var(--muted-2); font-weight: 500; }
.dr-reset { margin-left: auto; font-size: 12.5px; padding: 8px 14px; }
.dr-reset:disabled { opacity: .4; cursor: default; }

.dr-n { margin: 0; }

.dr-card {
  background: var(--surface);
  border-radius: 20px;
  padding: 18px 24px 16px;
  box-shadow: var(--card-shadow);
}
.dr-card-head { font-family: Montserrat, sans-serif; font-weight: 700; font-size: 14.5px; color: var(--ink); margin: 2px 0 12px; }
.dr-note { font-size: 12px; color: var(--muted-2); margin: 12px 0 0; }

/* Headline: basic level against the 2030 target. */
.dr-basic-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.dr-basic-figure { display: flex; flex-direction: column; align-items: flex-end; flex-shrink: 0; }
.dr-basic-value { font-family: Montserrat, sans-serif; font-weight: 800; font-size: 40px; line-height: 1; color: var(--brand-green); }
.dr-basic-sub { font-size: 12px; color: var(--muted-2); margin-top: 4px; }

/* The target is a marked line on the bar, not a second number, so the gap
   reads as a distance rather than as arithmetic the reader has to do. */
.dr-target-track {
  position: relative;
  height: 20px;
  background: var(--track);
  border-radius: 10px;
  margin: 26px 0 8px;
}
.dr-target-fill {
  height: 100%;
  border-radius: 10px;
  background: var(--brand-green);
  transition: width .4s cubic-bezier(.16, 1, .3, 1);
}
.dr-target-marker { position: absolute; top: -6px; bottom: -6px; width: 2px; background: var(--ink); }
.dr-target-flag {
  position: absolute;
  bottom: calc(100% + 3px);
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-size: 10.5px;
  font-weight: 500;
  color: var(--ink-2);
}
.dr-gap { font-size: 12.5px; color: var(--deficit); margin: 0; font-weight: 500; }
.dr-gap.met { color: var(--brand-green); }

/* Four-band distribution and per-variable adoption share a row shape. */
.dr-bands, .dr-vars { display: flex; flex-direction: column; gap: 6px; }
.dr-band-row, .dr-var { display: flex; align-items: center; gap: 12px; }

.dr-band-label { width: 128px; flex-shrink: 0; display: flex; align-items: baseline; gap: 6px; }
.dr-band-name { font-size: 12.5px; color: var(--ink); font-weight: 500; }
.dr-band-range { font-size: 10.5px; color: var(--muted-3); }
.dr-band-track { flex: 1; height: 22px; background: var(--track); border-radius: 6px; overflow: hidden; min-width: 0; }
.dr-band-fill { height: 100%; border-radius: 6px; transition: width .4s cubic-bezier(.16, 1, .3, 1); }
.dr-band-value, .dr-var-value {
  width: 92px;
  flex-shrink: 0;
  text-align: right;
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.dr-var-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.dr-derived-key { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--muted-2); margin-bottom: 12px; }

.dr-var-label { width: 268px; flex-shrink: 0; display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.dr-var-name { font-size: 12.5px; color: var(--ink); min-width: 0; }
.dr-var-source { font-size: 10.5px; color: var(--muted-3); white-space: nowrap; }
.dr-var-track { flex: 1; height: 16px; background: var(--track); border-radius: 5px; overflow: hidden; min-width: 0; }
.dr-var-fill { height: 100%; border-radius: 5px; background: var(--bar-established); transition: width .4s cubic-bezier(.16, 1, .3, 1); }

/* The three derived variables are marked, not hidden: a reader comparing to
   Eurostat needs to see which figures are approximations. */
.dr-derived-mark {
  flex-shrink: 0;
  width: 15px;
  height: 15px;
  border-radius: 4px;
  background: var(--band-developing);
  color: var(--ink);
  font-size: 9.5px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.dr-var.derived .dr-var-fill { background: var(--bar-developing); }

/* Small-cell guard. Deliberately not styled as an error — nothing has gone
   wrong, the selection is simply too small to publish. */
.dr-suppressed {
  background: var(--surface);
  border-radius: 20px;
  padding: 22px 24px;
  box-shadow: var(--card-shadow);
  border-left: 4px solid var(--band-developing);
}
.dr-suppressed-head { font-family: Montserrat, sans-serif; font-weight: 700; font-size: 15px; color: var(--ink); margin: 0 0 8px; }
.dr-suppressed-body { font-size: 13px; color: var(--ink-2); margin: 0 0 8px; max-width: 76ch; line-height: 1.55; }
.dr-suppressed-hint { font-size: 12.5px; color: var(--muted); margin: 0 0 10px; max-width: 76ch; }
.dr-suppressed-note { font-size: 11.5px; color: var(--muted-2); margin: 0; max-width: 82ch; line-height: 1.5; }

.dr-method { background: var(--page-bg-2); box-shadow: none; }
.dr-method-list { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 7px; }
.dr-method-list li { font-size: 12px; color: var(--ink-2); line-height: 1.55; max-width: 100ch; }
.dr-method-version { font-size: 11.5px; color: var(--muted); margin: 12px 0 0; max-width: 100ch; line-height: 1.5; }

@media (max-width: 900px) {
  .dr-var-label { width: 180px; }
  .dr-band-label { width: 104px; }
  .dr-reset { margin-left: 0; }
}

/* ── Engagement (admin) ───────────────────────────────────────────────
   Deliberately thin: the bars, cards and notes reuse the DII report's
   `dr-*` classes so the two admin views share one visual language. Only
   what is genuinely new to this view is defined here. */

.eng-summary { margin-bottom: 18px; }
.eng-card { margin-bottom: 18px; }
.eng-card-head { margin-bottom: 14px; }
.eng-card-title {
  font-family: Montserrat, sans-serif;
  font-weight: 800;
  font-size: 18px;
  color: var(--ink);
  margin: 2px 0 4px;
}
.eng-card-intro { margin-top: 0; max-width: 78ch; }

/* Wide enough that "D2 Operations Booking · Attraction" stays on one line;
   an uneven row height in a funnel reads as a rendering fault. */
.eng-label { width: 228px; flex-direction: column; align-items: flex-start; gap: 1px; }
.eng-label .dr-band-name { line-height: 1.25; }
.eng-row { padding: 1px 0; }
.eng-row-flagged .dr-band-name { color: var(--ink); font-weight: 700; }
.eng-histogram { margin-top: 14px; }

/* Headline figures above each distribution. */
.eng-figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
  gap: 10px;
  margin-bottom: 4px;
}
.eng-figure {
  background: var(--track);
  border-radius: 12px;
  padding: 10px 14px;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.eng-figure-flagged { background: #F7E4E0; }
.eng-figure-label { font-size: 11px; color: var(--muted-2); text-transform: uppercase; letter-spacing: .04em; }
.eng-figure-value { font-family: Montserrat, sans-serif; font-weight: 800; font-size: 22px; color: var(--ink); line-height: 1.15; }
.eng-figure-note { font-size: 11px; color: var(--muted-3); }

/* "Nothing yet" -- a real state, and it has to look intentional rather
   than like a view that failed to load. */
.eng-empty {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 20px;
  background: var(--track);
  border-radius: 14px;
}
.eng-empty-mark {
  font-family: Montserrat, sans-serif;
  font-weight: 800;
  font-size: 22px;
  color: var(--muted-3);
  line-height: 1;
}
.eng-empty-text { font-size: 12.5px; color: var(--muted-2); margin: 0; max-width: 70ch; }
.eng-foot { margin-top: 4px; }

@media (max-width: 860px) {
  .eng-label { width: 124px; }
}
