/* CoreBridge Sector Data Tool — BETA
   v4 | 12 June 2026 | Restyled to the live corebridgeadvisory.com.au design
   system, tokens read from the production site on 12 June 2026: ink #14110D,
   paper #F7F5F0, accent #5B4FE5, chip yellow #E6E04E, Neue Haas Display /
   Neue Haas Text / Tiempos Headline stacks, square geometry, warm-black
   header. Brand fonts load from the production site when online; system
   fallbacks otherwise. */

@font-face { font-family: "Neue Haas Display"; src: url("https://www.corebridgeadvisory.com.au/fonts/brand/NeueHaasDisplay-Bold.otf") format("opentype"); font-weight: 700; font-display: swap; }
@font-face { font-family: "Neue Haas Display"; src: url("https://www.corebridgeadvisory.com.au/fonts/brand/NeueHaasDisplay-Medium.otf") format("opentype"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Neue Haas"; src: url("https://www.corebridgeadvisory.com.au/fonts/brand/NeueHaasText-Roman.otf") format("opentype"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Neue Haas"; src: url("https://www.corebridgeadvisory.com.au/fonts/brand/NeueHaasText-Medium.otf") format("opentype"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Neue Haas"; src: url("https://www.corebridgeadvisory.com.au/fonts/brand/NeueHaasText-Bold.otf") format("opentype"); font-weight: 700; font-display: swap; }
/* Tiempos Headline — the editorial serif of the CoreBridge magazine system. Loaded
   on screen (not just print) so the hero and section titles read as CoreBridge. */
@font-face { font-family: "Tiempos Headline"; src: url("https://www.corebridgeadvisory.com.au/fonts/brand/TiemposHeadline-Regular.otf") format("opentype"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Tiempos Headline"; src: url("https://www.corebridgeadvisory.com.au/fonts/brand/TiemposHeadline-Medium.otf") format("opentype"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Tiempos Headline"; src: url("https://www.corebridgeadvisory.com.au/fonts/brand/TiemposHeadline-Semibold.otf") format("opentype"); font-weight: 600; font-display: swap; }

:root {
  --ink: #14110D;
  --ink-2: #2E2A22;
  --ink-3: #6B6557;
  --ink-surface: #1A1714;
  --header: rgba(14, 17, 22, 0.97);
  --paper: #F7F5F0;
  --paper-bright: #FEFCF7;
  --paper-on-ink: #EFEAE0;
  --paper-on-ink-2: #B8B1A1;
  --rule: #C9C3B5;
  --rule-soft: #DDD9CF;
  --accent: #5B4FE5;
  --accent-deep: #3A2FB8;
  --accent-wash: #E7E4FA;
  --accent-ink: #2A2483;
  --chip-yellow: #E6E04E;
  --accent-soft: #A39DEB;
  /* canonical semantic colours (replace the retired terracotta #B8553F and the
     off-palette green #2E7D5B that used to carry good/bad meaning) */
  --success: #3D5A3D;
  --danger: #8E2E2E;
  --chart-gold: #D4A017;
  --chart-amber: #C77D11;   /* amber FILL for charts/markers (AI-exposure, JSA caveat) */
  --warn-text:   #8E6E2E;   /* darker amber for TEXT — meets AA on light surfaces */
  --chart-h: 260px;         /* standard chart-card canvas height; taller/shorter charts override explicitly */
  --display: "Neue Haas Display", "Helvetica Neue", Inter, system-ui, -apple-system, sans-serif;
  --text: "Neue Haas", "Helvetica Neue", Inter, system-ui, -apple-system, sans-serif;
  --serif: "Tiempos Headline", "Source Serif 4", Georgia, serif;
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
  /* shared content-column geometry, so the header, main and footer never drift */
  --col-max: 1180px;
  --col-pad: 24px;
  /* radius scale + layered material depth (Apple/Google surfaces): a tonal step
     below the card, a top rim-light, a multi-stop ambient shadow */
  --r-chip: 8px; --r-ctl: 10px; --r-card: 16px; --r-hero: 20px;
  /* bento spacing scale: one rhythm for grid gaps, card padding and section gutters,
     so the dashboard breathes consistently and reflows cleanly across desktop / iPad /
     phone. Tuned down a step on tablet and phone via the breakpoints below. */
  --gap: 16px;            /* default grid gap (cards / charts) */
  --gap-sm: 13px;         /* tighter gap for dense KPI tiles */
  --pad-card: 17px 19px;  /* card interior */
  --pad-section: 26px 30px 30px;  /* section panel interior */
  --surface: #FFFEFB;          /* card fill, one notch above paper */
  --surface-sunk: #F2EFE8;     /* page, one tonal step below paper, so cards float */
  --rim: rgba(255, 255, 255, .72);
  --lead-ring: rgba(61, 90, 61, .60);      /* green top-10 pulse (success) */
  --watch-ring: rgba(142, 46, 46, .62);    /* red bottom-10 pulse (danger) */
  /* layered material depth (3D): three shadow tiers so a tab reads as boxes lifting
     off the page, tiles lifting off the boxes, and cells set into the tiles.
       --shadow-box  : section panels + headline box (deepest, far-reaching lift)
       --shadow-tile : the KPI / chart cards floating inside a box (medium)
       --shadow-card : standalone cards not inside a box
       --shadow-lift : hover (strongest)
       --inset-cell  : innermost cells, pressed slightly INTO their tile */
  --shadow-card: 0 1px 2px rgba(20,17,13,.06), 0 5px 12px -4px rgba(20,17,13,.11), 0 16px 30px -12px rgba(20,17,13,.14), 0 32px 56px -26px rgba(20,17,13,.15);
  --shadow-box:  0 1px 2px rgba(20,17,13,.06), 0 8px 18px -4px rgba(20,17,13,.13), 0 24px 46px -14px rgba(20,17,13,.20), 0 50px 84px -30px rgba(20,17,13,.22);
  --shadow-tile: 0 1px 2px rgba(20,17,13,.05), 0 3px 7px -2px rgba(20,17,13,.10), 0 11px 22px -8px rgba(20,17,13,.15);
  --shadow-lift: 0 2px 6px rgba(20,17,13,.09), 0 16px 30px -8px rgba(20,17,13,.22), 0 40px 64px -20px rgba(20,17,13,.28);
  --rim-inset: inset 0 1px 0 var(--rim), inset 0 0 0 1px rgba(255,255,255,.04);
  --inset-cell: inset 0 1px 2px rgba(20,17,13,.06), inset 0 0 0 1px rgba(20,17,13,.015);
  --shadow-chip: 0 1px 2px rgba(20,17,13,.07), 0 3px 8px -3px rgba(20,17,13,.16);  /* small number boxes (rank pill, rank/median cells) — a crisp little lift */
  /* legacy aliases used in inline styles */
  --ink-soft: #6B6557;
  --line: #DDD9CF;
  --card: #FEFCF7;
}
* { box-sizing: border-box; margin: 0; }
body { font-family: var(--text); background: var(--surface-sunk); color: var(--ink); font-size: 15.5px; line-height: 1.55; }
h1, h2, h3 { font-family: var(--display); font-weight: 700; letter-spacing: -0.015em; }

/* the dark band runs full-bleed, but its content (brand row, H1, lede) is held to
   the SAME column as main, so the H1/lede left and right edges align with the cards
   at every desktop width (fixes the lede sitting inset from the content below). */
header.site { background: var(--header); color: var(--paper-on-ink); padding: 30px 0 24px; }
header.site > * { max-width: var(--col-max); margin-left: auto; margin-right: auto; padding-left: var(--col-pad); padding-right: var(--col-pad); }
.brandmark { height: 38px; width: 38px; object-fit: contain; display: block; }
header.site .brand a { display: flex; align-items: center; }
@media print { .brandmark { content: url("brand/mark.png"); } }
header.site .brand {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .18em; text-transform: uppercase;
  color: var(--paper-on-ink-2); display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.beta-chip {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase;
  background: var(--chip-yellow); color: var(--ink); padding: 3px 10px; font-weight: 700;
}
header.site h1 { font-family: var(--serif); font-weight: 600; font-size: clamp(30px, 4.4vw, 50px); margin-top: 10px; letter-spacing: -0.02em; line-height: 1.04; color: #fff; }
header.site p.lede { margin-top: 12px; color: var(--paper-on-ink); font-size: 16.5px; line-height: 1.55; }

/* ===== site header — replicates the live corebridgeadvisory.com.au top bar:
   a slim, frosted cream bar with the CoreBridge mark + wordmark and the site nav,
   then a cream page-hero carrying the product title. ===== */
.site-head { background: rgba(247,245,240,0.96); -webkit-backdrop-filter: saturate(140%) blur(14px); backdrop-filter: saturate(140%) blur(14px); border-bottom: 1px solid var(--rule-soft); }
.site-head__inner { max-width: var(--col-max); margin: 0 auto; padding: 0 var(--col-pad); height: 60px; display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.site-head .brand { display: flex; align-items: center; gap: 12px; font-family: var(--display); font-weight: 700; font-size: 16px; letter-spacing: -0.012em; color: var(--ink); text-decoration: none; }
.site-head .brand__mark { width: 30px; height: 30px; flex: 0 0 30px; object-fit: contain; display: block; }
.site-head .nav { display: none; }
@media (min-width: 880px) { .site-head .nav { display: flex; align-items: center; gap: clamp(16px, 2.1vw, 30px); } }
.site-head .nav a { font: 400 14px var(--text); letter-spacing: .005em; color: var(--ink-2); position: relative; padding: 6px 0; text-decoration: none; transition: color .12s ease; white-space: nowrap; }
.site-head .nav a:hover { color: var(--ink); }
.site-head .nav a.is-active { color: var(--ink); font-weight: 500; }
.site-head .nav a.is-active::after { content: ""; position: absolute; inset: auto 0 -1px 0; height: 2px; background: var(--accent); }
.menu-btn { display: inline-flex; align-items: center; gap: 9px; background: transparent; border: 0; cursor: pointer; font: 500 13px var(--text); color: var(--ink); padding: 8px 0; }
@media (min-width: 880px) { .menu-btn { display: none; } }
.menu-btn__icon { position: relative; width: 18px; height: 14px; display: inline-block; }
.menu-btn__icon::before, .menu-btn__icon::after { content: ""; position: absolute; left: 0; right: 0; height: 2px; background: var(--ink); transition: transform .2s ease; }
.menu-btn__icon::before { top: 2px; }
.menu-btn__icon::after { bottom: 2px; }
.menu-btn[aria-expanded="true"] .menu-btn__icon::before { transform: translateY(4px) rotate(45deg); }
.menu-btn[aria-expanded="true"] .menu-btn__icon::after { transform: translateY(-4px) rotate(-45deg); }
.drawer { display: none; background: var(--ink-surface); border-bottom: 1px solid rgba(255,255,255,.10); }
.drawer.is-open { display: block; }
@media (min-width: 880px) { .drawer { display: none !important; } }
.drawer__nav { max-width: var(--col-max); margin: 0 auto; padding: 6px var(--col-pad) 16px; display: flex; flex-direction: column; }
.drawer__nav a { display: flex; justify-content: space-between; align-items: baseline; padding: 12px 2px; color: var(--paper-on-ink); text-decoration: none; border-bottom: 1px solid rgba(255,255,255,.08); font: 500 16px var(--text); }
.drawer__nav a:last-child { border-bottom: 0; }
.drawer__nav a .num { color: rgba(255,255,255,.4); font: 400 12px var(--mono); }

/* page hero — the product title on cream, in the website's editorial serif */
.page-hero { background: var(--paper); border-bottom: 1px solid var(--rule-soft); }
.page-hero .bandwrap { padding: 38px var(--col-pad) 34px; }
.page-hero .hero-eyebrow { display: inline-block; font: 700 10.5px var(--mono); letter-spacing: .14em; text-transform: uppercase; background: var(--chip-yellow); color: var(--ink); padding: 3px 10px; margin-bottom: 15px; }
.page-hero h1 { font-family: var(--serif); font-weight: 600; font-size: clamp(31px, 4.4vw, 52px); line-height: 1.05; letter-spacing: -0.02em; color: var(--ink); }
/* body text fills to the card/page right edge (no width cap) — Benjie's standing rule;
   the 1180px main container still bounds line length. The gremlin keeps re-adding these
   880/900px caps on revert, so if a paragraph suddenly stops short on the right, check here. */
.page-hero .lede { margin-top: 14px; font-size: 16.5px; line-height: 1.55; color: var(--ink-2); }
@media (max-width: 640px) { .page-hero .bandwrap { padding: 26px var(--col-pad) 24px; } }

/* full-bleed band whose text aligns to the shared content column */
.bandwrap { max-width: var(--col-max); margin: 0 auto; padding: 0 var(--col-pad); }
.beta-bar {
  background: var(--chip-yellow); color: var(--ink); padding: 9px 0;
  font-size: 13px; font-weight: 500; line-height: 1.45;
}
.beta-bar b { font-weight: 700; }

/* tab bar (restyled 14 Jun): short labels in rounded cluster panels; the active
   tab is a filled indigo pill so where-you-are reads instantly. */
/* full-bleed dark band, but the tab content aligns to the SAME centred content
   column as the header and main, so the menu and the headings below line up. */
nav.tabs { display: flex; gap: 10px; background: var(--ink-surface); flex-wrap: wrap; align-items: center;
  position: sticky; top: 0; z-index: 60;
  padding: 11px max(var(--col-pad), calc((100% - var(--col-max)) / 2 + var(--col-pad))); }
nav.tabs a {
  color: var(--paper-on-ink-2); text-decoration: none; padding: 9px 13px; font-size: 13.5px; font-weight: 500;
  border-radius: var(--r-chip); letter-spacing: -0.005em; line-height: 1; white-space: nowrap;
  transition: background .15s ease, color .15s ease;
}
nav.tabs a:hover { color: #fff; background: rgba(255,255,255,.08); }
nav.tabs a.active { background: var(--accent); color: #fff; font-weight: 700; box-shadow: 0 2px 9px rgba(91,79,229,.5); }

/* tab grouping: each of the five areas is its own rounded panel on a shared dark
   base, colour-coded from the brand palette (indigo / green / gold / clay, plus a
   neutral utility). The colour is carried on the kicker, a top accent rule, and the
   active pill, so each area reads as a distinct topic at a glance. */
nav.tabs .tab-cluster { display: flex; align-items: center; gap: 3px; background: #211d2e;
  border: 1px solid rgba(255,255,255,.09); border-top: 2px solid var(--clust, var(--accent));
  border-radius: var(--r-ctl); padding: 3px 5px 4px; }
nav.tabs .tab-cluster .tab-kicker { color: var(--clust-text, var(--accent-soft)); }
nav.tabs .tab-cluster a.active { background: var(--clust, var(--accent)); color: #fff;
  box-shadow: 0 2px 9px rgba(0,0,0,.45); }
/* the five areas */
nav.tabs .tab-cluster--bench  { --clust: #5B4FE5; --clust-text: #9d93f2; }   /* Benchmark a university: indigo */
nav.tabs .tab-cluster--local  { --clust: #3D5A3D; --clust-text: #7fb587; }   /* Your local area: green */
nav.tabs .tab-cluster--sector { --clust: #D4A017; --clust-text: #e6c766; }   /* Health of the sector: gold */
nav.tabs .tab-cluster--score  { --clust: #8E2E2E; --clust-text: #d9917c; }   /* Scorecard: clay */
nav.tabs .tab-cluster--sector a.active { color: var(--ink); }                /* gold pill needs ink text for contrast */
nav.tabs .tab-kicker {
  display: flex; align-items: center; font-family: var(--mono); font-size: 10px; font-weight: 600;
  letter-spacing: .15em; text-transform: uppercase;
  padding: 0 9px 0 11px; white-space: nowrap; pointer-events: none; user-select: none;
}
nav.tabs a.tab-util { margin-left: auto; border: 1px solid rgba(255,255,255,.16); }
nav.tabs a.tab-util.active { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.4); color: #fff; box-shadow: none; }
/* mobile nav: a grouped dropdown replaces the tab strip below 640px, so the 14
   views never get lost behind a sideways scroll. Shown only on mobile. */
.mobile-nav-wrap { display: none; }

main { max-width: 1180px; margin: 0 auto; padding: 28px 24px 60px; }
.controls { display: flex; gap: 14px; flex-wrap: wrap; align-items: end; margin-bottom: 22px; }
.controls label { display: block; font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 5px; font-weight: 500; }
/* the selectors share the row equally so they sit on one line (a compact locked header) and only
   wrap on narrow screens; each select fills its share, truncating the longest option rather than
   forcing the row taller. */
.controls > div { flex: 1 1 240px; min-width: 0; }
.controls > div > select { width: 100%; }
select, input[type=range], input[type=text] {
  font: inherit; padding: 9px 12px; border: 1px solid var(--rule); border-radius: 8px;
  background: var(--paper-bright); min-width: 220px; color: var(--ink);
}
select:focus, input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

/* accessibility: visible brand focus ring for keyboard users, and a skip link */
a:focus-visible, button:focus-visible, .btn:focus-visible, [tabindex]:focus-visible {
  outline: 3px solid var(--accent); outline-offset: 2px; border-radius: 1px;
}
/* on the dark nav/header/footer, indigo-on-dark is low contrast — use white there */
nav.tabs a:focus-visible, header.site a:focus-visible, footer.site a:focus-visible { outline-color: #fff; }
main:focus { outline: none; }  /* programmatic focus target for the skip link; no ring needed */
.skip-link {
  position: absolute; left: 8px; top: -48px; z-index: 1000;
  background: var(--accent); color: #fff; padding: 9px 16px; font-weight: 700; font-size: 14px;
  text-decoration: none; transition: top .12s ease;
}
.skip-link:focus { top: 8px; outline: 3px solid #fff; outline-offset: 2px; }
/* visually hidden but available to screen readers (carries non-colour meaning) */
.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; }

.grid { display: grid; gap: var(--gap); }
.kpis { grid-template-columns: repeat(auto-fill, minmax(208px, 1fr)); gap: var(--gap-sm); margin-bottom: 24px; }
/* cards: softened (curved) corners and a layered, slightly-3D shadow stack, with
   a lift on hover. A deliberate departure from the canonical square geometry for
   this public tool, to read like a contemporary Apple/Google-style dashboard. */
.card { background: var(--surface); border: 1px solid var(--rule-soft); border-radius: var(--r-card); padding: var(--pad-card);
  box-shadow: var(--shadow-card), var(--rim-inset);
  transition: box-shadow .2s cubic-bezier(.2,.7,.3,1), transform .2s cubic-bezier(.2,.7,.3,1); }
@media (hover: hover) {
  .card:hover { box-shadow: var(--shadow-lift), var(--rim-inset); transform: translateY(-2px); }
  .no-data:hover { box-shadow: none; transform: none; }   /* a placeholder, not an interactive card */
}
@media (prefers-reduced-motion: reduce) { .card, .role-tile { transition: none; } .card:hover, .role-tile:hover { transform: none; } }
/* cards in a row are equal height (grid stretch); their internals line up because
   every block ABOVE the divider has a fixed min-height: the title reserves two
   lines (a one-line and a two-line title push the value to the SAME baseline), the
   value reserves one line, the reference one line. So the .kpi-ctx divider sits at
   the same offset on every card and the lines align across the whole row. */
.kpi { display: flex; flex-direction: column; }
.kpi .label { font-family: var(--mono); font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); font-weight: 500; line-height: 1.3; min-height: 27px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.kpi .value { font-family: var(--display); font-weight: 700; font-size: 30px; letter-spacing: -0.02em; color: var(--ink); margin-top: 4px; line-height: 1.1; min-height: 33px; white-space: nowrap; }
/* the change badge sits on its own line below the number (the inline badge was too
   wide for the card and pushed the divider out of line); reserves one line whether
   or not a prior year exists, so every card's divider lands at the same height. */
.kpi-yoy { min-height: 18px; margin-top: 3px; line-height: 1.2; }
.kpi-yoy .yoy { margin-left: 0; }
.kpi .ref { font-size: 11.5px; color: var(--ink-3); margin-top: 4px; min-height: 16px; }
.kpi .bench { font-size: 12px; margin-top: 6px; color: var(--ink-3); }
.kpi .bench div { margin-top: 2px; }
.kpi .bench b { color: var(--accent-deep); }
/* KPI context: every datum is shown by default (no hover/click reveal). The
   national rank of 36 is promoted to a colour-keyed tile; state, mission,
   benchmark median and the multi-year move sit in a quiet 2-up labelled grid. */
.kpi-ctx { margin-top: 13px; padding-top: 12px; border-top: 1px solid var(--rule-soft); }
.kpi-rank { display: flex; align-items: baseline; gap: 8px; padding: 8px 11px; border-radius: var(--r-ctl); background: var(--accent-wash); border: 1px solid rgba(91,79,229,.30); margin-bottom: 9px; box-shadow: var(--shadow-chip); }
.kpi-rank .kr-pos { font-family: var(--display); font-weight: 700; font-size: 20px; letter-spacing: -0.01em; color: var(--accent-ink); line-height: 1; font-variant-numeric: tabular-nums; }
.kpi-rank .kr-of { font-family: var(--mono); font-size: 9.5px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); }
.kpi-rank--good { background: rgba(61,90,61,.10); border-color: rgba(61,90,61,.42); }
.kpi-rank--good .kr-pos { color: var(--success); }
.kpi-rank--bad { background: rgba(142,46,46,.08); border-color: rgba(142,46,46,.38); }
.kpi-rank--bad .kr-pos { color: var(--danger); }
/* scale/exposure (no good direction): a neutral indigo magnitude tag — large is
   notable, never "good". A distinct colour from the green/red performance pulse. */
.kpi-rank--scale { background: rgba(91,79,229,.08); border-color: rgba(91,79,229,.34); }
.kpi-rank--scale .kr-pos { color: var(--accent); }
.kc-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--rule-soft); border: 1px solid var(--rule-soft); border-radius: var(--r-ctl); overflow: hidden; }
.kc { display: flex; flex-direction: column; gap: 2px; padding: 7px 10px; background: var(--surface); }
.kc-l { font-family: var(--mono); font-size: 9px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); line-height: 1.25; }
.kc-v { font-size: 14px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1.15; }
.kc-v small { font-weight: 500; font-size: 10px; color: var(--ink-3); }
.kc-mv { font-size: 11px; font-weight: 700; margin-left: 2px; font-variant-numeric: tabular-nums; }
.kc-grid > .kc:only-child { grid-column: 1 / -1; }
.kc-grid > .kc:last-child:nth-child(odd) { grid-column: 1 / -1; }
.kc-trend { margin-top: 7px; }

/* colour pulse on key information: a green halo + green number on a top-10
   national rank, a red halo + red number on a bottom-10 rank (good-direction
   measures only). Both settle after a few cycles; both reduced-motion guarded. */
.kpi.kpi-lead, .kpi.kpi-watch { position: relative; }
.kpi.kpi-lead { border-color: rgba(61,90,61,.48); }
.kpi.kpi-lead .value { color: var(--success); }
.kpi.kpi-lead { border-color: rgba(61,90,61,.65); }
.kpi.kpi-lead::after { content:""; position:absolute; inset:-1.5px; border-radius:inherit; pointer-events:none; box-shadow: 0 0 0 0 var(--lead-ring); animation: cb-lead-pulse 2.2s ease-in-out infinite; }
@keyframes cb-lead-pulse { 0% { box-shadow: 0 0 0 0 var(--lead-ring); } 70%, 100% { box-shadow: 0 0 0 9px rgba(61,90,61,0); } }
.kpi.kpi-watch { border-color: rgba(142,46,46,.65); }
.kpi.kpi-watch .value { color: var(--danger); }
.kpi.kpi-watch::after { content:""; position:absolute; inset:-1.5px; border-radius:inherit; pointer-events:none; box-shadow: 0 0 0 0 var(--watch-ring); animation: cb-watch-pulse 2.3s ease-in-out infinite; }
@keyframes cb-watch-pulse { 0% { box-shadow: 0 0 0 0 var(--watch-ring); } 70%, 100% { box-shadow: 0 0 0 9px rgba(142,46,46,0); } }
/* top-decile on a scale measure: a STATIC indigo ring (no animation) so "among
   the largest" draws the eye without implying a good/bad performance signal. */
.kpi.kpi-scale { position: relative; border-color: rgba(91,79,229,.42); }
.kpi.kpi-scale::after { content:""; position:absolute; inset:-1.5px; border-radius:inherit; pointer-events:none; box-shadow: 0 0 0 2px rgba(91,79,229,.26); }
@media (prefers-reduced-motion: reduce) {
  .kpi.kpi-lead::after { animation: none; box-shadow: 0 0 0 2px var(--lead-ring); }
  .kpi.kpi-watch::after { animation: none; box-shadow: 0 0 0 2px var(--watch-ring); }
}

/* guided-entry "start here" action strip on the landing: one clear way in, so a
   first-time reader is not left to parse the full tab bar to begin */
.starter { margin: 2px 0 30px; }
.starter-head { display: flex; align-items: baseline; gap: 12px; margin: 0 0 13px; flex-wrap: wrap; }
.starter-eyebrow { font: 700 10.5px var(--mono); letter-spacing: .14em; text-transform: uppercase; background: var(--ink); color: var(--chip-yellow); padding: 4px 10px; border-radius: 4px; }
.starter-sub { font-size: 14px; color: var(--ink-2); }
.role-router { display: grid; grid-template-columns: repeat(auto-fit, minmax(238px, 1fr)); gap: 14px; margin: 0; }
/* each tile reads as an action: indigo title, a persistent arrow affordance, and a
   hover lift that nudges the arrow. No constant pulse — the arrow and the "Start
   here" framing carry the affordance without the noise of five pulsing rings. */
.role-tile { position: relative; display: block; padding: 18px 20px 42px; background: var(--surface); border: 1.5px solid var(--accent-soft); border-radius: var(--r-card); text-decoration: none; color: inherit; box-shadow: var(--shadow-card), var(--rim-inset); transition: box-shadow .2s cubic-bezier(.2,.7,.3,1), transform .2s cubic-bezier(.2,.7,.3,1), border-color .2s; }
@media (hover: hover) { .role-tile:hover { box-shadow: var(--shadow-lift), var(--rim-inset); transform: translateY(-2px); border-color: var(--accent); } .role-tile:hover .rt-go { transform: translateX(4px); } }
.role-tile .rt-title { display: block; font-family: var(--display); font-weight: 700; font-size: 16.5px; color: var(--accent); letter-spacing: -0.01em; }
.role-tile .rt-desc { display: block; font-size: 12.5px; color: var(--ink-2); margin-top: 5px; line-height: 1.45; }
.role-tile .rt-go { position: absolute; right: 18px; bottom: 13px; font-size: 19px; line-height: 1; color: var(--accent); font-weight: 700; transition: transform .2s cubic-bezier(.2,.7,.3,1); }
@media (prefers-reduced-motion: reduce) { .role-tile, .role-tile .rt-go { transition: none; } }
/* secondary paths as quiet text links beneath the three primary tiles */
.starter-more { display: flex; flex-wrap: wrap; gap: 8px 24px; margin: 16px 2px 0; }
.starter-link { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 500; color: var(--ink-2); text-decoration: none; transition: color .15s; }
.starter-link .sl-go { color: var(--accent); transition: transform .2s; }
@media (hover: hover) { .starter-link:hover { color: var(--accent); } .starter-link:hover .sl-go { transform: translateX(3px); } }

/* Low-SES focus band (Universities Accord parity agenda): a lead hero tile carrying
   the institution's headline share, then gap-to-target tiles laid 2-4 per row. The
   government's central equity measure gets its own prominent treatment. */
.lowses-band { grid-template-columns: 1.5fr 1fr 1fr 1fr; align-items: stretch; }
@media (max-width: 920px) { .lowses-band { grid-template-columns: 1fr 1fr; } }
@media (max-width: 540px) { .lowses-band { grid-template-columns: 1fr; } }
.lowses-hero { display: flex; flex-direction: column; }
.lowses-hero .ls-eyebrow { font-family: var(--mono); font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); font-weight: 500; line-height: 1.3; }
.lowses-hero .ls-big { font-family: var(--display); font-weight: 700; font-size: clamp(46px, 6vw, 62px); line-height: 1; letter-spacing: -0.03em; color: var(--accent-deep); margin: 8px 0 5px; font-variant-numeric: tabular-nums; }
.lowses-hero .ls-sub { font-size: 12.5px; color: var(--ink-3); line-height: 1.45; }
.lowses-hero .ls-rank { margin-top: auto; padding-top: 13px; }
.lowses-hero .ls-rank .kpi-rank { margin-bottom: 0; }
/* at or above the 2035 target: the hero reads green, matching the kpi-lead pulse on the
   equity-intake cards. Below target it stays the calm indigo hero (never red, per R10). */
.lowses-hero.ls-meets { position: relative; border-color: rgba(61,90,61,.65); }
.lowses-hero.ls-meets .ls-big { color: var(--success); }
.lowses-hero.ls-meets::after { content:""; position:absolute; inset:-1.5px; border-radius:inherit; pointer-events:none; box-shadow: 0 0 0 0 var(--lead-ring); animation: cb-lead-pulse 2.2s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .lowses-hero.ls-meets::after { animation: none; box-shadow: 0 0 0 2px var(--lead-ring); } }
.lowses-tile { display: flex; flex-direction: column; gap: 4px; }
.lowses-tile .lt-l { font-family: var(--mono); font-size: 9.5px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); line-height: 1.3; }
.lowses-tile .lt-v { font-family: var(--display); font-weight: 700; font-size: 27px; letter-spacing: -0.01em; color: var(--ink); line-height: 1.05; font-variant-numeric: tabular-nums; margin-top: 2px; }
.lowses-tile .lt-sub { font-size: 11.5px; color: var(--ink-3); line-height: 1.4; margin-top: auto; padding-top: 6px; }
.lowses-tile.lt-gap-pos .lt-v { color: var(--success); }   /* at or above the target = success-green */
.lowses-tile.lt-gap-neg .lt-v { color: var(--ink-2); }     /* below target: neutral, not red (equity is never flagged as a failing, R10) */

/* Campuses tab lead statement: answers "is there enrolment by campus?" up front,
   so the catchment cards are never mistaken for a campus headcount. A clean panel,
   not a left-border callout (the canonical lists that as an AI tell). */
.campus-lead { background: var(--surface); border: 1px solid var(--rule-soft); border-radius: var(--r-card); box-shadow: var(--shadow-card), var(--rim-inset); padding: 16px 20px 17px; margin: 0 0 6px; max-width: 940px; }
.campus-lead .cl-head { font-family: var(--display); font-weight: 700; font-size: 16px; color: var(--ink); margin-bottom: 5px; letter-spacing: -0.01em; }
.campus-lead p { font-size: 13.5px; color: var(--ink-2); line-height: 1.55; }
.campus-lead a { color: var(--accent); text-decoration: underline; }

/* scorecard summary band: quartile counts, a rank-profile strip, lead/lag chips */
.scd-summary { margin: 0 0 20px; }
.scd-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-bottom: 18px; }
.scd-stat { background: var(--paper); border: 1px solid var(--rule-soft); border-radius: var(--r-ctl); padding: 12px 16px; box-shadow: var(--rim-inset); }
.scd-stat .scd-n { font-family: var(--display); font-weight: 700; font-size: 30px; letter-spacing: -0.02em; line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums; }
.scd-stat .scd-l { font-size: 12px; color: var(--ink-3); margin-top: 4px; line-height: 1.35; }
.scd-stat.good .scd-n { color: var(--success); }
.scd-stat.bad .scd-n { color: var(--danger); }
.scd-strip-wrap { margin-bottom: 18px; }
.scd-strip-lbl { display: flex; justify-content: space-between; font-family: var(--mono); font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 6px; }
.scd-strip-lbl span:nth-child(2) { color: var(--ink-2); text-transform: none; letter-spacing: 0; font-family: var(--text); font-size: 12px; }
.scd-strip { position: relative; height: 28px; background: linear-gradient(90deg, rgba(142,46,46,.14), rgba(20,17,13,.03) 50%, rgba(61,90,61,.16)); border: 1px solid var(--rule-soft); border-radius: 999px; }
.scd-dot { position: absolute; top: 50%; width: 10px; height: 10px; border-radius: 50%; transform: translate(-50%,-50%); background: var(--ink-3); border: 1.5px solid var(--surface); box-shadow: 0 1px 2px rgba(20,17,13,.18); }
.scd-dot.good { background: var(--success); }
.scd-dot.bad { background: var(--danger); }
.scd-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.scd-col h4 { font-family: var(--mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 8px; }
.scd-chip { display: inline-flex; align-items: baseline; gap: 6px; font-size: 12.5px; background: var(--surface); border: 1px solid var(--rule-soft); border-radius: 999px; padding: 4px 12px; margin: 0 6px 7px 0; color: var(--ink-2); text-decoration: none; transition: border-color .15s; }
.scd-chip:hover { border-color: var(--accent); }
.scd-chip b { font-family: var(--display); font-weight: 700; }
.scd-chip.good b { color: var(--success); }
.scd-chip.bad b { color: var(--danger); }
/* compact rank pill for the Compare table — the one view where ranks are read side by
   side, so the rank earns the same colour-keyed treatment as the kpiPulse rings. */
.rank-pill { display: inline-flex; align-items: baseline; gap: 3px; padding: 2px 8px; border-radius: 999px; font: 700 12px var(--display); background: var(--surface-sunk); color: var(--ink-2); box-shadow: var(--shadow-chip); }
.rank-pill small { font-weight: 500; font-size: 10px; color: var(--ink-3); }
.rank-pill.good { background: rgba(61,90,61,.10); color: var(--success); }
.rank-pill.bad  { background: rgba(142,46,46,.10); color: var(--danger); }
/* ── Head-to-head versus mode ──────────────────────────────────────── */
.vs-tally { display: flex; justify-content: center; margin: 4px 0 14px; }
.vs-tally__score { font: 800 22px var(--display); letter-spacing: -.01em; color: var(--ink); background: var(--surface-sunk); border-radius: 999px; padding: 8px 24px; box-shadow: var(--shadow-chip); }
.vs-table th, .vs-table td { vertical-align: middle; }
.vs-table td small { color: var(--ink-3); font-weight: 400; font-size: 10px; }
.vs-table .vs-win { background: rgba(61,90,61,.12); font-weight: 700; }
.vs-table .vs-arrow { font-size: 15px; color: var(--ink-3); text-align: center; width: 34px; }
.vs-table .vs-na { color: var(--ink-3); }
.vs-table .vs-ctx { font: 600 9px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); background: var(--surface-sunk); border-radius: var(--r-chip); padding: 1px 6px; margin-left: 6px; vertical-align: middle; }
.cmp-mode-btn { font: 600 12.5px var(--text); background: var(--ink); color: var(--paper-on-ink); border: none; border-radius: var(--r-chip); padding: 9px 16px; cursor: pointer; transition: background .15s; white-space: nowrap; }
.cmp-mode-btn[aria-pressed="true"] { background: var(--accent); color: #fff; }
.cmp-mode-btn:hover { background: var(--accent-deep); color: #fff; }
@media (max-width: 640px) { .scd-stats, .scd-cols { grid-template-columns: 1fr; } }

/* ── Guess-first "test your intuition" widgets ─────────────────────── */
.guess-pair { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--gap); }
.guess-widget { background: var(--surface); border: 1px solid var(--rule-soft); border-radius: var(--r-card); box-shadow: var(--shadow-tile); padding: 18px 20px; }
.guess-widget .gw-q { font: 600 14.5px var(--text); color: var(--ink); margin: 0 0 4px; line-height: 1.35; }
.guess-widget .gw-sub { font-size: 12px; color: var(--ink-3); margin: 0 0 12px; }
.guess-widget .gw-val { font: 700 16px var(--display); color: var(--accent-deep); }
.guess-widget input[type=range] { width: 100%; accent-color: var(--accent); margin: 8px 0 12px; height: 22px; cursor: grab; }
.guess-widget input[type=range]:active { cursor: grabbing; }
.guess-btn { font: 600 12.5px var(--text); background: var(--accent); color: #fff; border: none; border-radius: var(--r-chip); padding: 8px 18px; cursor: pointer; transition: background .15s; }
.guess-btn:hover { background: var(--accent-deep); }
.guess-btn:disabled { background: var(--surface-sunk); color: var(--ink-3); cursor: default; }
.guess-reveal { opacity: 0; max-height: 0; overflow: hidden; transition: opacity .3s ease, max-height .35s ease; font-size: 13px; line-height: 1.6; color: var(--ink-2); }
.guess-reveal.shown { opacity: 1; max-height: 520px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--rule-soft); }
/* reveal becomes a card of flashing big numbers */
.guess-reveal .gw-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; margin-bottom: 10px; }
.guess-reveal .gw-stat { background: var(--surface-sunk); border-radius: var(--r-chip); padding: 12px 14px; }
.guess-reveal .gw-big { font: 800 30px var(--display); color: var(--danger); line-height: 1.04; letter-spacing: -.01em; }
.guess-reveal .gw-big .gw-unit { font-size: 16px; font-weight: 700; }
.guess-reveal .gw-cap { font-size: 11.5px; color: var(--ink-2); margin-top: 5px; line-height: 1.45; }
.guess-reveal .gw-note { font-size: 12px; color: var(--ink-3); margin: 6px 0 0; }
.gw-flash { animation: cb-gw-flash 1.6s ease-in-out infinite; }
@keyframes cb-gw-flash { 0%, 100% { opacity: 1; text-shadow: 0 0 0 rgba(142,46,46,0); } 50% { opacity: .6; text-shadow: 0 0 16px rgba(142,46,46,.45); } }
@media (prefers-reduced-motion: reduce) { .gw-flash { animation: none; } }
.guess-reveal .gw-pointer { display: inline-block; margin-top: 6px; font: 600 12px var(--mono); letter-spacing: .03em; color: var(--accent-deep); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.guess-reveal .gw-pointer:hover { color: var(--accent); }
@media (prefers-reduced-motion: reduce) { .guess-reveal { transition: none; } }

/* ── Scrollytelling for the $13.1B gap section ─────────────────────── */
.sh-scrolly { display: grid; grid-template-columns: 1fr; gap: 0; }
.sh-scrolly__step { padding: 22px 2px; border-top: 1px solid var(--rule-soft); }
.sh-scrolly__step:first-child { border-top: none; }
.sh-scrolly__step h4 { font: 700 14.5px var(--display); color: var(--ink-3); margin: 0 0 6px; transition: color .25s; }
.sh-scrolly__step p { font-size: 13.5px; line-height: 1.6; color: var(--ink-2); margin: 0; }
.sh-scrolly__step.is-active h4 { color: var(--accent-deep); }
@media (min-width: 900px) {
  .sh-scrolly { grid-template-columns: 1.05fr .95fr; gap: 0 30px; align-items: start; }
  .sh-scrolly__sticky { position: sticky; top: calc(var(--navh, 70px) + 16px); }
  .sh-scrolly__step { min-height: 150px; display: flex; flex-direction: column; justify-content: center; }
}
@media (prefers-reduced-motion: reduce) { .sh-scrolly__sticky { position: static; } }

/* shareable stat-card button — sits top-right of each sector-health KPI tile */
.sh-share-btn { position: absolute; top: 9px; right: 9px; z-index: 2; font: 600 9.5px var(--mono); letter-spacing: .04em; background: var(--surface); color: var(--ink-3); border: 1px solid var(--rule-soft); border-radius: var(--r-chip); padding: 3px 8px; cursor: pointer; opacity: .5; transition: opacity .15s, color .15s, border-color .15s; }
.sh-kpi:hover .sh-share-btn, .sh-share-btn:focus-visible { opacity: 1; }
.sh-share-btn:hover { color: var(--accent-deep); border-color: var(--accent); }
@media (hover: none) { .sh-share-btn { opacity: .85; } }

/* sector overview hero statistic */
.sector-hero { margin: 4px 0 16px; }
.sector-hero .sh-num { font-family: var(--display); font-weight: 700; font-size: clamp(40px, 7vw, 66px); line-height: 1; letter-spacing: -0.03em; color: var(--accent-deep); }
.sector-hero .sh-cap { font-size: 15px; color: var(--ink-2); margin-top: 6px; max-width: 660px; }

/* "Explore CoreBridge" dropdown in the header (far right): coloured + pulsing
   so the route back to corebridgeadvisory.com.au is obvious */
.cb-nav {
  margin-left: auto; -webkit-appearance: none; appearance: none; cursor: pointer;
  background-color: var(--accent); color: #fff; border: none; border-radius: 0;
  font: 700 11px var(--mono); letter-spacing: .08em; text-transform: uppercase;
  padding: 8px 28px 8px 12px; min-width: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='3'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat; background-position: right 9px center;
  animation: cb-nav-pulse 2.6s ease-in-out 4;   /* draws the eye on load, then settles */
}
.cb-nav:hover { background-color: var(--accent-deep); }
.cb-nav:focus { outline: 2px solid #fff; outline-offset: 2px; }
.cb-nav option { color: var(--ink); background: #fff; font-family: var(--text); }
@keyframes cb-nav-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(123, 112, 235, 0); } 50% { box-shadow: 0 0 0 5px rgba(123, 112, 235, .45); } }
@media (prefers-reduced-motion: reduce) { .cb-nav { animation: none; } }

/* progressive disclosure: collapsible secondary sections. The ▸ caret carries the
   "there is more" affordance, so no attention pulse is needed here. */
details.disclose { margin: 16px 0; border-top: 1px solid var(--rule); }
details.disclose > summary { cursor: pointer; list-style: none; padding: 13px 2px 3px; font-family: var(--display); font-weight: 700; font-size: 17px; color: var(--ink); letter-spacing: -0.01em; display: flex; align-items: baseline; gap: 9px; }
details.disclose > summary::-webkit-details-marker { display: none; }
details.disclose > summary::before { content: "▸"; color: var(--accent); font-size: 11px; }
details.disclose[open] > summary::before { content: "▾"; }
details.disclose > summary .disc-sub { font-family: var(--mono); font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); font-weight: 500; }
details.disclose > summary:hover { color: var(--accent-deep); }

/* year-on-year change badge (KPI values, scorecard + compare tables) */
.yoy { font-family: var(--text); font-size: 12px; font-weight: 700; vertical-align: middle; margin-left: 5px; letter-spacing: 0; white-space: nowrap; }
.yoy-good { color: var(--success); }
.yoy-bad { color: var(--danger); }
.yoy-neutral { color: var(--ink-3); }
.yoy-period { font-weight: 400; font-size: 0.82em; color: var(--ink-3); }

/* real-terms change: a clear green/red pill so "outpaced inflation" vs "fell behind"
   is unmistakable, not a muted dark number */
.real-chg { display: inline-block; font-weight: 700; font-variant-numeric: tabular-nums; padding: 2px 9px; border-radius: 999px; font-size: 13px; line-height: 1.3; border: 1px solid transparent; }
.real-chg.up { color: var(--success); background: rgba(61,90,61,.14); border-color: rgba(61,90,61,.34); }
.real-chg.down { color: var(--danger); background: rgba(142,46,46,.13); border-color: rgba(142,46,46,.36); }

/* state & territory table */
.state-table td, .state-table th { vertical-align: middle; }
.state-table tbody td { padding: 11px 12px; }
.st-name { font-family: var(--display); font-weight: 700; font-size: 15px; color: var(--ink); letter-spacing: -0.01em; }
.st-unis { font-size: 11px; color: var(--ink-3); margin-top: 3px; max-width: 360px; line-height: 1.4; }
.st-unis b { color: var(--ink-2); }
.st-share { width: 156px; }
.share-bar { height: 8px; background: var(--rule-soft); overflow: hidden; border-radius: 999px; }
.share-bar span { display: block; height: 100%; background: var(--accent); }
.share-lbl { font-size: 11px; color: var(--ink-3); margin-top: 4px; font-variant-numeric: tabular-nums; }
.yoy-legend { background: var(--paper-bright); border: 1px solid var(--rule-soft); border-left: 3px solid var(--accent); border-radius: var(--r-ctl); padding: 8px 12px; font-size: 12.5px; line-height: 1.5; color: var(--ink-2); margin-bottom: 16px; max-width: 900px; }
.yoy-legend .yoy { margin-left: 0; }

/* feedback / errata box (open public beta) */
.feedback-box { }
.feedback-box h3 { font-size: 17px; color: var(--ink); margin-bottom: 6px; }
.feedback-box p { font-size: 13.5px; color: var(--ink-2); max-width: 760px; margin-bottom: 12px; }
.errata-badge { display: inline-block; font-family: var(--mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; background: var(--chip-yellow); color: var(--ink); padding: 3px 9px; font-weight: 700; margin-bottom: 8px; }

/* data-status / corrections card (Method tab) */
.data-status { }
.data-status h3 { font-size: 18px; color: var(--ink); margin-bottom: 2px; }
.data-status h4 { font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); font-weight: 600; margin: 14px 0 6px; }
.data-status ul { margin: 0; padding-left: 18px; }
.data-status li { font-size: 13px; color: var(--ink-2); margin-bottom: 4px; line-height: 1.5; }
.ds-head { display: flex; flex-wrap: wrap; gap: 14px 28px; align-items: flex-start; justify-content: space-between; }
.ds-meta { display: flex; gap: 22px; flex-wrap: wrap; }
.ds-meta > div { display: flex; flex-direction: column; }
.ds-k { font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.ds-v { font-family: var(--display); font-weight: 700; font-size: 15px; color: var(--ink); margin-top: 2px; white-space: nowrap; }
.ds-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 28px; }
.ds-corr li { color: var(--ink); }
.ds-corr b { color: var(--accent-deep); font-variant-numeric: tabular-nums; }
@media (max-width: 640px) { .ds-grid { grid-template-columns: 1fr; } .ds-meta { gap: 16px; } }
footer.site a { text-decoration: underline; }

/* blank-on-open prompt + pulsing institution selector */
.blank-prompt { max-width: 640px; padding: 26px 26px 30px; }
.blank-prompt h2 { font-size: 22px; color: var(--ink); margin-bottom: 8px; }
/* the "select a university" control gets a clearer, stronger pulse: a 2px accent
   border that breathes and a larger halo ring, so the one action that unlocks every
   single-university tab is unmistakable. The label also pulses to reinforce it. */
.instselect.pulse select { border: 2px solid var(--accent); background: var(--accent-wash); animation: cb-pulse 1.5s ease-in-out infinite; }
@keyframes cb-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(91,79,229,.62); border-color: var(--accent); } 50% { box-shadow: 0 0 0 12px rgba(91,79,229,0); border-color: var(--accent-deep); } }
.instselect.pulse label { color: var(--accent-deep); animation: cb-label-pulse 1.5s ease-in-out infinite; }
.instselect.pulse label::after { content: " — start here"; color: var(--accent); font-weight: 700; }
@keyframes cb-label-pulse { 0%, 100% { opacity: .65; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .instselect.pulse select { animation: none; outline: 2px solid var(--accent); } .instselect.pulse label { animation: none; opacity: 1; } }

/* "On this tab" contents strip: a map of the tab's sections so a long, data-dense
   view reads as a navigable set of labelled chunks, not a wall. Built from the
   section headings (buildSectionNav). */
/* sticky so the contents strip stays available while reading a long tab; scroll-spy
   (setupScrollSpy) lights the section you're in. Opaque page-tone bg so cards scroll
   cleanly beneath it. */
.section-nav { display: flex; align-items: baseline; gap: 10px 14px; flex-wrap: wrap; margin: 2px 0 30px; padding: 13px 24px; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
  position: sticky; top: 0; z-index: 50; background: var(--surface-sunk); }
/* desktop: lock the whole top control stack as you scroll — the tab bar (top), the institution
   and benchmark selectors below it, and the "on this tab" strip below those. The selector and
   strip carry extra left padding so their labels sit clear of the edge and read easily. */
@media (min-width: 641px) {
  #main > .controls { position: sticky; top: var(--navh, 56px); z-index: 56; margin: 0 0 22px; padding: 15px 24px; background: var(--paper); box-shadow: inset 0 -1px 0 var(--rule-soft); }
  .section-nav { top: calc(var(--navh, 56px) + var(--ctrlh, 70px)); }
}
@media (max-width: 640px) {
  /* offset the sticky section-nav (and the sticky table headers) below the mobile view-switcher
     (.mobile-nav-wrap, z-index 60); without this the "On this tab" strip slid under it on scroll.
     --mnavh is measured in setStickyVars; the switcher can wrap, so never hardcode its height. */
  .section-nav { padding: 13px 16px; position: static; }
  #main.has-secnav table.data th { top: calc(var(--mnavh, 0px) + 50px); }
}
/* programmatic focus target on view change: no visible box on the whole content column */
#main:focus { outline: none; }
/* the section you're currently reading: filled indigo pill, same language as the active tab */
.sn-link.active { background: var(--page-accent, var(--accent)); border-color: var(--page-accent, var(--accent)); color: var(--page-accent-on, #fff); box-shadow: 0 2px 9px rgba(20,17,13,.22); }
.sn-link.active .sn-num { background: #fff; color: var(--page-accent-deep, var(--accent-deep)); }
/* colour pulses: a flash as a pill becomes the active section (scroll-spy), and a flash
   on a section's number chip when you jump to it — both confirm where you've landed */
.sn-link.cb-pill-flash { animation: cb-pill-flash .9s ease-out 1; }
@keyframes cb-pill-flash { 0% { box-shadow: 0 0 0 0 rgba(91,79,229,.55); } 100% { box-shadow: 0 2px 9px rgba(91,79,229,.38), 0 0 0 8px rgba(91,79,229,0); } }
.sec-n.cb-flash { animation: cb-chip-flash 1.1s ease-out 1; }
@keyframes cb-chip-flash { 0% { background: var(--page-accent, var(--accent)); color: var(--page-accent-on, #fff); box-shadow: 0 0 0 0 rgba(20,17,13,.45); } 100% { box-shadow: 0 0 0 11px rgba(20,17,13,0); } }
@media (prefers-reduced-motion: reduce) { .sn-link.cb-pill-flash, .sec-n.cb-flash { animation: none; } }
/* data-table headers stick below the contents strip, but only on tabs that have one */
#main.has-secnav table.data th { top: 50px; z-index: 2; }
/* inside a scroll box the header sticks to the box's own top, not 50px (else the section-nav rides over it) */
#main.has-secnav div[style*="overflow:auto"] table.data th { top: 0; }
.sn-label { font-family: var(--mono); font-size: 9.5px; letter-spacing: .15em; text-transform: uppercase; color: var(--ink-3); white-space: nowrap; padding-top: 5px; }
.sn-links { display: flex; gap: 7px; flex-wrap: wrap; flex: 1; }
.sn-link { display: inline-flex; align-items: center; gap: 8px; font: 500 12.5px var(--text); color: var(--ink-2); background: var(--surface); border: 1px solid var(--rule-soft); border-radius: 999px; padding: 4px 14px 4px 4px; cursor: pointer; transition: background .15s, border-color .15s, color .15s; box-shadow: var(--shadow-card); }
.sn-link:hover { border-color: var(--page-accent, var(--accent)); color: var(--page-accent-deep, var(--accent-deep)); }
.sn-num { display: inline-grid; place-items: center; width: 19px; height: 19px; border-radius: 50%; background: var(--accent-wash); color: var(--accent-ink); font: 700 10px var(--mono); flex: none; }
.sn-link:hover .sn-num { background: var(--page-accent, var(--accent)); color: var(--page-accent-on, #fff); }

/* each section is its own rounded, shadowed box (a card), so a tab reads as a stack
   of discrete, layered panels rather than one continuous scroll. The white panel
   floats on the sunk page; its content (KPI/chart cards) sits inside as sub-panels. */
section.block { margin: 24px 0; scroll-margin-top: 80px; background: var(--surface); border: 1px solid var(--rule-soft);
  border-radius: var(--r-hero); box-shadow: var(--shadow-box), var(--rim-inset); padding: var(--pad-section); }
@media (max-width: 640px) { section.block { padding: 20px 16px 22px; } }
/* section titles lead in the editorial serif, fronted by a numbered anchor chip
   that ties each section to the "on this tab" strip and marks it as a discrete chunk */
section.block > h2 { font-family: var(--serif); font-weight: 600; font-size: clamp(23px, 2.3vw, 29px); line-height: 1.14; letter-spacing: -0.01em; color: var(--ink); margin-bottom: 8px; }
section.block h2 .sec-n { display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--page-accent, var(--accent)); color: var(--page-accent-on, #fff); border: 1px solid var(--page-accent, var(--accent)); font: 700 12px var(--mono); margin-right: 12px; vertical-align: 4px; }
section.block > p.note { color: var(--ink-3); font-size: 13.5px; margin-bottom: 14px; }
/* nested "boxes within a box" — the three catchment scales, readable tiles inside a panel */
.scale-explainer { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; padding: 16px; background: var(--surface-sunk); border: 1px solid var(--rule-soft); border-radius: var(--r-card); box-shadow: var(--shadow-box); margin: 0 0 12px; }
.scale-box { background: var(--surface); border: 1px solid var(--rule-soft); border-radius: var(--r-ctl); padding: 13px 15px; box-shadow: var(--shadow-tile); }
.scale-box .scale-tag { display: block; font-family: var(--display); font-weight: 700; font-size: 15px; color: var(--accent); letter-spacing: -0.01em; }
.scale-box .scale-unit { display: block; font-family: var(--mono); font-size: 10px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-2); margin-top: 4px; }
.scale-box .scale-km { display: block; font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }
.scale-box .scale-desc { font-size: 12.5px; color: var(--ink-2); line-height: 1.45; margin: 9px 0 0; }
/* an interpretive "read": one finding-carrying sentence, weighted darker than the
   descriptive note above it so the reader's eye lands on the so-what */
p.note.read-line { color: var(--ink); font-size: 14.5px; font-weight: 500; margin: -2px 0 14px; }
p.note.read-line b { color: var(--accent-deep); font-weight: 700; }
/* a headline KPI grid sitting bare at the top of a tab (the "at a glance" lead, not
   itself inside a section) gets the same boxed-panel treatment, so every chunk on a
   tab reads as a discrete, shadowed box rather than a loose row of floating cards. */
main > .grid.kpis { background: var(--surface); border: 1px solid var(--rule-soft);
  border-radius: var(--r-hero); box-shadow: var(--shadow-box), var(--rim-inset);
  padding: 24px 30px 28px; margin: 18px 0 24px; }
@media (max-width: 640px) { main > .grid.kpis { padding: 18px 16px 20px; } }

/* inside a section box (or the headline box above), the KPI / chart tiles FLOAT: a
   near-white fill, a top rim-light and a medium drop shadow, so each tile lifts off
   the box the way the box lifts off the page — boxes within boxes, real depth. Hover
   raises them further. */
section.block .card,
main > .grid.kpis > .card { background: var(--paper-bright); box-shadow: var(--shadow-tile), var(--rim-inset); }
@media (hover: hover) {
  section.block .card:hover,
  main > .grid.kpis > .card:hover { background: #fff; box-shadow: var(--shadow-lift), var(--rim-inset); transform: translateY(-3px); }
  section.block .no-data:hover { background: var(--paper); box-shadow: none; transform: none; }
}
/* placeholders stay flat (a missing measure should not float like real data) */
section.block .no-data, main > .grid.kpis .no-data { box-shadow: none; }
/* the in-tile mini-grid (rank tile + 2-up context) is set INTO the floating tile with
   a soft inner shadow, the deepest layer in the stack */
section.block .kc, main > .grid.kpis .kc { background: var(--surface); }
/* the rank/median panel lifts off the tile as its own raised number box */
section.block .kc-grid, main > .grid.kpis .kc-grid { box-shadow: var(--shadow-chip); }
/* a section whose only content is a single full-width card (a heading-less panel
   like the Method data-status or feedback box) would double-box; collapse the outer
   box and let that one card BE the panel, white and floating, not a card on a box. */
section.block:has(> .card:only-child) { background: transparent; border: none; box-shadow: none; padding: 0; }
section.block:has(> .card:only-child) > .card { background: var(--surface); box-shadow: var(--shadow-box), var(--rim-inset); }
.charts { grid-template-columns: repeat(auto-fit, minmax(430px, 1fr)); }
.chartcard h3 { font-size: 15px; margin-bottom: 8px; color: var(--ink-2); }
.chartcard .src { font-size: 11px; color: var(--ink-3); margin-top: 8px; }
/* base .src rule so source captions placed OUTSIDE a chartcard (tables, loose cards,
   sector sections) still render at the muted 11px caption size, not full body size.
   .chartcard .src above is more specific and keeps its margin inside charts. */
.src { font-size: 11px; line-height: 1.5; color: var(--ink-3); margin-top: 8px; }
/* every section's chart grid sits a consistent --gap below its lede (was 51 inline
   margin-top:14px magic numbers across the views). */
.block .grid.charts { margin-top: var(--gap); }
/* "no strong position" rank tile — used by kpiCard/pgRankTile in 5 views but the rule
   was never defined, so a neutral rank looked identical to a directional one. */
.kpi-rank--mid { background: var(--surface-sunk); border-color: var(--rule); }
.kpi-rank--mid .kr-pos { color: var(--ink-3); }
/* repeated OECD/section sub-heading (was a 7-property inline style duplicated 6×,
   with an off-token colour fallback and a raw 'JetBrains Mono' string). */
.sh-subsec-head {
  font: 600 10.5px/1.3 var(--mono);
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3);
  margin: 24px 0 10px; border-bottom: 1px solid rgba(20,17,13,.08); padding-bottom: 6px;
}
/* a brand-coloured marker that pulses over a key chart point (the latest value, or an
   important line crossover) — draws the eye to where the story is. CSS-animated (no JS
   redraw loop), placed by placePulseDot(); reduced-motion drops the pulse, keeps the dot. */
.chart-pulse { position: absolute; width: 9px; height: 9px; border-radius: 50%; transform: translate(-50%, -50%); pointer-events: none; z-index: 4; background: var(--accent); box-shadow: 0 0 0 2px var(--surface); }
.chart-pulse::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: inherit; opacity: .5; animation: cb-pt-pulse 1.9s cubic-bezier(.2,.6,.3,1) infinite; }
@keyframes cb-pt-pulse { 0% { transform: scale(1); opacity: .5; } 70%, 100% { transform: scale(3.6); opacity: 0; } }
.chart-pulse.good { background: var(--success); }
.chart-pulse.warn { background: var(--danger); }
.chart-pulse.gold { background: var(--chart-gold); }
.chart-pulse.teal { background: #1F6F5C; }
@media (prefers-reduced-motion: reduce) { .chart-pulse::after { animation: none; } }
/* matrix direction arrow (Jobs scatter): a thin indigo arrow rooted at the key uni's dot,
   rotated toward the sweet spot; a ghost stroke nudges toward the head to read as "move this way".
   Direction is the information, so reduced-motion keeps the static arrow and drops only the nudge. */
.matrix-arrow { position: absolute; width: 42px; height: 0; transform-origin: 0 50%; pointer-events: none; z-index: 5; border-top: 2px solid var(--accent); opacity: .75; }
.matrix-arrow::after { content: ""; position: absolute; right: -1px; top: -4px; border-left: 7px solid var(--accent); border-top: 4px solid transparent; border-bottom: 4px solid transparent; }
.matrix-arrow::before { content: ""; position: absolute; inset: 0; border-top: 2px solid var(--accent-deep, var(--accent)); opacity: .5; animation: cb-arrow-nudge 1.9s cubic-bezier(.2,.6,.3,1) infinite; }
@keyframes cb-arrow-nudge { 0% { transform: translateX(0); opacity: .55; } 60% { transform: translateX(10px); opacity: 0; } 100% { transform: translateX(0); opacity: 0; } }
.matrix-here { position: absolute; transform: translate(-50%, -50%); pointer-events: none; z-index: 5; font: 600 10px var(--mono); letter-spacing: .04em; text-transform: uppercase; color: var(--success); background: rgba(61,90,61,.10); border: 1px solid rgba(61,90,61,.4); padding: 2px 7px; border-radius: 11px; white-space: nowrap; }
@media (prefers-reduced-motion: reduce) { .matrix-arrow::before { animation: none; opacity: 0; } }
/* occBar "does this uni teach into this field" legend swatches */
.occ-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: 11.5px; color: var(--ink-2); margin: 0 0 8px; }
.occ-key { display: inline-block; width: 14px; height: 9px; border-radius: 2px; vertical-align: middle; margin-right: 2px; }
.occ-key.solid { background: var(--accent); }
.occ-key.faint { background: rgba(91,79,229,.14); border: 1.2px solid rgba(91,79,229,.55); }
.occ-key.ai { background: #C77D11; }
/* intentional no-data state, so a missing measure reads as data discipline, not a gap */
.no-data { display: flex; align-items: center; gap: 10px; padding: 18px 20px; background: var(--paper); border: 1px dashed var(--rule); border-radius: var(--r-card); box-shadow: none; font-size: 13px; color: var(--ink-3); }

table.data { width: 100%; border-collapse: collapse; background: var(--paper-bright); border: 1px solid var(--rule-soft); font-size: 14px; }
table.data th { background: var(--ink-surface); color: var(--paper-on-ink); text-align: left; padding: 9px 12px; font-weight: 500; font-family: var(--mono); font-size: 11px; letter-spacing: .04em; text-transform: uppercase; position: sticky; top: 0; z-index: 2; }
table.data td { padding: 8px 12px; border-top: 1px solid var(--rule-soft); }
table.data tr.me td { background: var(--accent-wash); font-weight: 600; }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data tr.section-row td { background: var(--accent-wash); color: var(--accent-ink); font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; font-weight: 700; padding: 9px 12px; border-top: 2px solid var(--accent); position: sticky; top: 33px; }
select optgroup { font-weight: 700; color: var(--ink); font-style: normal; }
select option { font-weight: 400; }

.campuscards { grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); }
.campus h3 { font-size: 15.5px; color: var(--ink); }
.campus .meta { font-size: 12.5px; color: var(--ink-3); margin-bottom: 8px; }
/* each catchment metric in its own padded box inside the campus card */
.cc-rows { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.cc-row { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; padding: 9px 14px; background: var(--surface-sunk); border: 1px solid var(--rule-soft); border-radius: var(--r-ctl); }
.cc-row .cc-l { font-size: 12.5px; color: var(--ink-2); line-height: 1.3; }
.cc-row .cc-v { font-size: 14px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.cc-row--wide { flex-direction: column; align-items: stretch; gap: 4px; }
.cc-row--wide .cc-v { text-align: left; font-weight: 600; font-size: 13px; white-space: normal; }
.pill { display: inline-block; font-size: 10.5px; font-family: var(--mono); letter-spacing: .03em; padding: 2px 9px; background: var(--accent-wash); color: var(--accent-ink); margin-left: 6px; border-radius: var(--r-chip); }

.attrib { margin-top: 34px; padding-top: 14px; border-top: 1px solid var(--rule); font-size: 11px; color: var(--ink-3); line-height: 1.7; }
.attrib h4 { font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2); margin-bottom: 4px; }
.scenario-h { font-family: var(--serif); font-weight: 600; font-size: 19px; letter-spacing: -0.01em; color: var(--ink); margin-bottom: 6px; }
.scenario .out { font-family: var(--display); font-weight: 700; font-size: 26px; color: var(--accent-deep); }
/* ── "What if" scenario slider card (gap-closure on the $13.1B section) ── */
.scn-card { background: var(--surface); border: 1.5px solid var(--rule-soft); border-radius: var(--r-card); box-shadow: var(--shadow-tile); padding: 18px 20px; margin: 0 0 14px; }
.scn-card .scn-head { font: 700 10px var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); margin-bottom: 8px; }
.scn-card .scn-q { font: 600 15px var(--text); color: var(--ink); margin: 0 0 10px; }
.scn-card label { font-size: 13px; color: var(--ink-2); }
.scn-card label b { font: 700 15px var(--display); color: var(--accent-deep); }
.scn-card input[type=range] { width: 100%; accent-color: var(--accent); margin: 8px 0 14px; height: 22px; cursor: grab; }
.scn-card input[type=range]:active { cursor: grabbing; }
.scn-out { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.scn-out > div { background: var(--surface-sunk); border-radius: var(--r-chip); padding: 10px 13px; }
.scn-out .scn-l { display: block; font-size: 11px; color: var(--ink-3); margin-bottom: 3px; }
.scn-out .scn-v { font: 800 21px var(--display); color: var(--ink); line-height: 1.05; }
.scn-out .scn-v--good { color: var(--success); }
.scn-card .scn-note { font-size: 10.5px; color: var(--ink-3); margin: 10px 0 0; line-height: 1.5; }
.flag { background: var(--accent-wash); border: 1px solid var(--accent); border-radius: var(--r-ctl); padding: 10px 14px; font-size: 13px; color: var(--accent-ink); margin: 12px 0; }

footer.site { background: var(--header); color: var(--paper-on-ink-2); padding: 26px 0; font-size: 12.5px; }
footer.site b { color: var(--paper-on-ink); }

.btn {
  display: inline-block; background: var(--accent); color: #fff; border: none; cursor: pointer;
  padding: 11px 20px; border-radius: 8px; font: 600 13.5px var(--text); letter-spacing: .01em;
}
.btn:hover { background: var(--accent-deep); }

.methodology h3 { margin: 18px 0 6px; color: var(--ink); font-size: 16px; }
.methodology p, .methodology li { font-size: 14px; }
.methodology ul { padding-left: 20px; }

.chips { display: flex; gap: 8px; flex-wrap: wrap; }
.chip { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; background: var(--paper-bright); border: 1.5px solid var(--rule); padding: 4px 10px; border-radius: var(--r-chip); }
.chip i { width: 10px; height: 10px; display: inline-block; }
.chip button { border: none; background: none; cursor: pointer; font-size: 15px; color: var(--ink-3); padding: 0 2px; }
.chip button:hover { color: var(--accent); }
.picklist { max-height: 200px; overflow: auto; padding: 4px; }

/* "Add to compare" toggle injected into each institution view's controls row */
.add-cmp-wrap { display: flex; align-items: end; }
.add-cmp {
  font-family: var(--mono); font-size: 12px; font-weight: 600; letter-spacing: .02em;
  background: var(--accent-wash); color: var(--accent-ink); border: 1.5px solid var(--accent);
  border-radius: 10px; padding: 9px 15px; cursor: pointer; white-space: nowrap;
  transition: background .15s, color .15s, box-shadow .15s;
}
.add-cmp:hover:not(:disabled) { background: var(--accent); color: #fff; }
.add-cmp.on { background: var(--accent); color: #fff; border-color: var(--accent-deep); }
.add-cmp:disabled { opacity: .5; cursor: not-allowed; }

/* sticky compare tray — the user's peer group, visible and editable on every view */
.cmp-tray {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
  background: rgba(26, 23, 20, .94); color: var(--paper-on-ink);
  border-top: 2px solid var(--accent);
  box-shadow: 0 -8px 26px rgba(20, 17, 13, .28);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  transform: translateY(110%); transition: transform .28s cubic-bezier(.22,.61,.36,1);
}
.cmp-tray.open { transform: translateY(0); }
.cmp-tray-inner {
  max-width: 1240px; margin: 0 auto; padding: 11px 24px;
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
}
.cmp-tray-label { font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--paper-on-ink-2); }
.cmp-tray-label b { color: var(--chip-yellow); font-size: 12px; margin-left: 4px; }
.cmp-tray-chips { display: flex; gap: 8px; flex-wrap: wrap; flex: 1; min-width: 200px; }
.cmp-tchip {
  display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 600;
  background: rgba(255, 255, 255, .07); color: var(--paper-on-ink);
  border: 1px solid rgba(255, 255, 255, .14); border-radius: 999px; padding: 4px 6px 4px 11px;
}
.cmp-tchip i { width: 9px; height: 9px; border-radius: 50%; background: var(--c, var(--accent)); display: inline-block; }
.cmp-tchip button { border: none; background: none; cursor: pointer; font-size: 15px; line-height: 1; color: var(--paper-on-ink-2); padding: 0 2px; }
.cmp-tchip button:hover { color: #fff; }
.cmp-tray-acts { display: flex; gap: 8px; }
.cmp-tray-go {
  font-family: var(--mono); font-size: 12px; font-weight: 700; letter-spacing: .02em;
  background: var(--chip-yellow); color: var(--ink); border: none; border-radius: 10px; padding: 9px 16px; cursor: pointer;
}
.cmp-tray-go:disabled { opacity: .45; cursor: not-allowed; }
.cmp-tray-clear {
  font-family: var(--mono); font-size: 12px; font-weight: 600;
  background: none; color: var(--paper-on-ink-2); border: 1px solid rgba(255, 255, 255, .22); border-radius: 10px; padding: 9px 14px; cursor: pointer;
}
.cmp-tray-clear:hover { color: #fff; border-color: rgba(255, 255, 255, .5); }
body.tray-open { padding-bottom: 76px; }
@media (max-width: 640px) {
  .cmp-tray-inner { padding: 9px 14px; gap: 9px; }
  .cmp-tray-label { width: 100%; }
  body.tray-open { padding-bottom: 116px; }
}
@media (prefers-reduced-motion: reduce) { .cmp-tray { transition: none; } }
.pickrow { display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: center; padding: 6px 10px; font-size: 13.5px; cursor: pointer; }
.pickrow:hover { background: var(--paper); }
.pickrow.on { background: var(--accent-wash); font-weight: 600; }
.pickrow .meta2 { color: var(--ink-3); font-size: 12px; }

/* KPI tiles stay a uniform size and pack densely (DO NOT re-add a double-width hero
   first tile — it pushed the last tile onto its own row and left dead space; removed
   16 Jun, and removed again after a file-revert re-introduced it). Uniform tiles keep
   the grid compact and the rows full. */

/* iPad / tablet tier (641–1024px), added in the bento refinement. The base layout
   jumped straight from desktop to phone, so iPad got the desktop tab bar wrapping
   into three rows. Here the tab bar becomes one clean swipeable strip, the content
   column tightens, and the bento grids reflow to a comfortable two-up via the
   existing auto-fit floors. A range query so it never collides with the ≤640 rules. */
@media (min-width: 641px) and (max-width: 1024px) {
  main { padding: 24px 20px 52px; }
  nav.tabs { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
  nav.tabs::-webkit-scrollbar { display: none; }
  nav.tabs .tab-cluster { flex: 0 0 auto; }
  nav.tabs a.tab-util { margin-left: 8px; flex: 0 0 auto; }
  section.block { padding: 24px 24px 28px; }
  .controls { gap: 12px; }
}

/* Mobile — added 11 Jun 2026. The base layout had no phone breakpoints; at ~390px
   the charts (420px grid floor) and the select controls (grow to content width)
   overflowed the screen. This stacks the controls full-width, drops charts to one
   fluid column that shrinks to fit, makes the 9-tab bar swipe sideways instead of
   stacking, and lets wide data tables scroll inside their own box. */
@media (max-width: 640px) {
  header.site { padding: 22px 0 18px; }
  header.site > *, .bandwrap { padding-left: 16px; padding-right: 16px; }
  header.site h1 { font-size: clamp(25px, 7.5vw, 36px); }
  .cb-nav { animation: none; }   /* on mobile only the sticky mobile-nav pulses, not both */
  .beta-bar { padding: 9px 0; }
  nav.tabs { display: none; }
  /* the mobile nav reads unambiguously as a view switcher: a sticky accent bar
     with a persistent "jump to a view" cue above a clearly-bordered control that
     shows the current view and a prominent caret. No pulse needed; the cue +
     border + caret carry the affordance. */
  .mobile-nav-wrap {
    display: block; position: sticky; top: 0; z-index: 60;     /* lock to the top on scroll */
    background: var(--accent); padding: 9px 16px 11px;
  }
  .mobile-nav-cue {
    display: block; font: 700 9.5px var(--mono); letter-spacing: .15em; text-transform: uppercase;
    color: rgba(255, 255, 255, .82); margin-bottom: 6px;
  }
  .mobile-nav {
    display: block; width: 100%; min-width: 0; max-width: 100%; margin: 0;
    border: 1.5px solid rgba(255, 255, 255, .55); border-radius: var(--r-ctl);
    background: rgba(255, 255, 255, .12); color: #fff;
    padding: 12px 44px 12px 14px; font: 700 16px var(--text); letter-spacing: .01em;
    -webkit-appearance: none; appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='3'><polyline points='6 9 12 15 18 9'/></svg>");
    background-repeat: no-repeat; background-position: right 14px center;
  }
  .mobile-nav optgroup { font-weight: 700; background: #fff; }
  .mobile-nav option { font-weight: 500; background: #fff; }
  /* colour-code the groups so the sections read at a glance (Android Chrome
     applies these to the native dropdown; matches the desktop cluster colours) */
  .mobile-nav optgroup[label="One university"], .mobile-nav optgroup[label="One university"] option { color: #3A2FB8; }
  .mobile-nav optgroup[label="Whole sector"], .mobile-nav optgroup[label="Whole sector"] option { color: #1F6F5C; }
  .mobile-nav optgroup[label="Scorecard"], .mobile-nav optgroup[label="Scorecard"] option { color: #8A7400; }
  .mobile-nav optgroup[label="Reference"], .mobile-nav optgroup[label="Reference"] option { color: #6B6557; }
  .mobile-nav:focus { outline: 3px solid #fff; outline-offset: 2px; }
  main { padding: 22px 16px 48px; }
  .controls { flex-direction: column; align-items: stretch; gap: 12px; }
  .controls > * { width: 100%; }
  /* the desktop rule (.controls > div { flex: 1 1 240px }) makes 240px a horizontal
     basis when the row flexes; in this column it becomes a 240px MINIMUM HEIGHT, so each
     dropdown sat in a 240px box with ~190px of dead space below it. Reset to content height
     here — matched at .controls > div specificity so it actually overrides the base rule. */
  .controls > div { flex: 0 0 auto; }
  select, input[type=range], input[type=text] { width: 100%; min-width: 0; max-width: 100%; }
  select { font-size: 12.5px; padding: 7px 10px; }
  .charts { grid-template-columns: minmax(0, 1fr); }
  .charts > * { min-width: 0; }
  .charts canvas { max-width: 100%; }
  /* allow y-axis labels to overflow the card edge rather than being clipped */
  .card.chartcard { overflow: visible; }
  table.data { display: block; overflow-x: auto; }
  footer.site { padding: 22px 0; }
}

/* ── Section-3 gap cards: shadow + ROI pulse animations ────────────── */
.sh-gap-card {
  border-radius: 10px;
  overflow: hidden;
  border: 1.5px solid rgba(142,46,46,.22);
  box-shadow: 0 2px 14px rgba(142,46,46,.11), 0 1px 4px rgba(20,17,13,.07);
  transition: box-shadow .25s;
}
.sh-gap-card:hover {
  box-shadow: 0 4px 22px rgba(142,46,46,.18), 0 2px 8px rgba(20,17,13,.1);
}
@keyframes shRoiBg {
  0%, 100% { background: rgba(61,90,61,.06); }
  50%       { background: rgba(61,90,61,.16); }
}
@keyframes shGoldBg {
  0%, 100% { background: rgba(212,160,23,.07); }
  50%       { background: rgba(212,160,23,.18); }
}
.sh-roi-pulse  { animation: shRoiBg  2.4s ease-in-out infinite; }
.sh-gold-pulse { animation: shGoldBg 2.4s ease-in-out infinite; }

/* signal panel (profile) — "don't make me find the signal", 13 Jun 2026.
   Three columns (strengths / watch / fastest), then a stands-out band. Each
   item is a link to the measure's full series. On brand: square cards, warm
   shadow, the canonical success-green / danger-red (--success / --danger). */
.signal-block { margin-top: 26px; }
.signal-cols { grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); align-items: stretch; }
.signal-col, .signal-standout { padding: 0; overflow: hidden; border-radius: var(--r-card); box-shadow: var(--shadow-tile); }
.signal-standout { margin-top: 14px; border-top: 3px solid var(--ink); }
.sg-strength { border-top: 3px solid var(--success); }
.sg-watch { border-top: 3px solid var(--danger); }
.sg-move { border-top: 3px solid var(--accent); }
.sig-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  font-family: var(--display); font-weight: 700; font-size: 15px; color: var(--ink);
  letter-spacing: -0.01em; padding: 13px 16px; border-bottom: 1px solid var(--rule-soft);
}
.sig-head span {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-3); font-weight: 500; white-space: nowrap;
}
.sig-item { display: flex; gap: 12px; align-items: baseline; padding: 10px 16px; border-bottom: 1px solid var(--rule-soft); text-decoration: none; color: inherit; }
.sig-item:last-child { border-bottom: none; }
.sig-item:hover { background: var(--accent-wash); }
.sig-rank { font-family: var(--display); font-weight: 700; font-size: 18px; color: var(--ink); white-space: nowrap; min-width: 60px; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
.sg-strength .sig-rank { color: var(--success); }
.sg-watch .sig-rank { color: var(--danger); }
.sig-rank.yoy-good { color: var(--success); }
.sig-rank.yoy-bad { color: var(--danger); }
.sig-rank.yoy-neutral { color: var(--ink-2); }
.sig-rank .of { font-family: var(--text); font-weight: 400; font-size: 11.5px; color: var(--ink-3); }
.sig-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sig-name { font-size: 13.5px; font-weight: 600; color: var(--ink); line-height: 1.3; }
.sig-meta { font-size: 11.5px; color: var(--ink-3); font-variant-numeric: tabular-nums; line-height: 1.4; }
.sig-empty { padding: 14px 16px; font-size: 12.5px; color: var(--ink-3); line-height: 1.5; }
/* the honest zero case (ranked, but nothing in the quartile): state the finding plainly as a
   deliberate read, not a grey blank. A hairline indigo top rule and the editorial serif; no icon. */
.sig-empty--honest { margin: 2px 14px; padding: 13px 0 2px; border-top: 1px solid var(--accent); font-family: var(--serif); font-size: 14px; color: var(--ink-2); line-height: 1.45; }
/* fastest-moving items: name on top, then a year-on-year and a multi-year row,
   each coloured success-green (rise) / danger-red (fall) with the sector move beside it */
.sig-move-item { flex-direction: column; align-items: stretch; gap: 5px; }
.sig-move-body { gap: 4px; }
.sig-move-row { display: flex; align-items: baseline; gap: 9px; font-size: 12px; }
.sig-move-lbl { font-family: var(--mono); font-size: 9px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); min-width: 30px; }
.sig-move-row b { font-weight: 700; min-width: 58px; font-variant-numeric: tabular-nums; }
.sig-move-row b.yoy-good { color: var(--success); }
.sig-move-row b.yoy-bad { color: var(--danger); }
.sig-peer { font-size: 11px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.sig-standout-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); }
/* Source-country small multiples: a grid of mini trend charts, each built like the full
   trend charts (year ticks across the bottom, compact enrolment ticks up the side) with a
   green-peak / red-trough pulse. The canvas is taller than a sparkline so the axis labels fit. */
.sm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(212px, 1fr)); gap: 14px; margin: 4px 0 2px; }
.sm-card { background: var(--surface); border: 1px solid var(--rule-soft); border-radius: var(--r-card); box-shadow: var(--shadow-tile); padding: 12px 13px 10px; }
.sm-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.sm-name { font-weight: 600; font-size: 13.5px; color: var(--ink); }
.sm-val { font-variant-numeric: tabular-nums; font-weight: 700; font-size: 13.5px; color: var(--accent-deep); }
.sm-sub { font-size: 11px; color: var(--ink-3); font-variant-numeric: tabular-nums; margin-top: 1px; min-height: 14px; }
.sm-cv { position: relative; height: 112px; margin-top: 8px; }
/* "How to read the numbers": themed subheadings + bulleted figures */
/* themed reading flows into balanced columns so it fills the box width (no lopsided
   empty right margin) while keeping a readable line length; collapses to one column
   on narrow screens via the column-width floor. */
.reading { column-width: 360px; column-gap: 36px; }
.reading-sec { margin-bottom: 15px; break-inside: avoid; -webkit-column-break-inside: avoid; }
.reading-sec:last-child { margin-bottom: 0; }
.reading-sec h4 { font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--accent-deep); font-weight: 700; margin: 0 0 6px; }
.reading-sec ul { margin: 0; padding-left: 18px; }
.reading-sec li { font-size: 13.5px; color: var(--ink-2); margin-bottom: 5px; line-height: 1.55; }
.reading-sec li b { color: var(--ink); font-weight: 600; }

/* inline glossary term: dotted underline + native hover definition */
abbr.gloss { text-decoration: none; border-bottom: 1px dotted var(--accent-soft); cursor: help; }
abbr.gloss:hover { border-bottom-color: var(--accent); }

/* signature read: the cross-dataset tension callout */
.card.tension { border-left: 3px solid var(--accent); background: var(--accent-wash); }
.card.tension .tension-line { margin: 0 0 10px; font-size: 15px; line-height: 1.55; color: var(--ink); }
.card.tension .tension-line:last-child { margin-bottom: 0; }
/* worry-briefing "question to ask" card — accent lead-in, mirrors the tension card */
.worry-briefing .worry-q { margin-top: var(--gap); border-left: 3px solid var(--accent); background: var(--accent-wash); }
.worry-briefing .worry-q .tension-line { margin: 6px 0 0; font-size: 15px; line-height: 1.55; color: var(--ink); }

/* empirical peer group: a compact grid of nearest universities */
.peer-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }
.peer-item { display: flex; flex-direction: column; gap: 2px; padding: 11px 13px; background: var(--surface); border: 1px solid var(--rule-soft); border-radius: var(--r-chip); text-decoration: none; box-shadow: var(--shadow-chip); transition: border-color .12s, box-shadow .12s; }
.peer-item:hover { border-color: var(--accent-soft); box-shadow: var(--shadow-lift); }
.peer-item .peer-name { font-weight: 600; color: var(--ink); font-size: 14px; line-height: 1.3; }
.peer-item .peer-meta { font-size: 11.5px; color: var(--ink-3); font-family: var(--mono); letter-spacing: .02em; }

/* full scorecard: rank-of-36 (tier-coloured), direction-coloured trend sparkline,
   1yr move + 5-yr rank movement */
.sc-table th, .sc-table td { white-space: nowrap; }
.sc-table td:first-child { white-space: normal; min-width: 200px; }
.sc-spark { padding: 3px 10px; vertical-align: middle; }
.spark { display: block; }
/* per-step trend colours: green = moved the good way, red = the other way, indigo =
   flat or no clear good direction */
.spark line { stroke-width: 1.5px; stroke-linecap: round; }
.spark .sp-good { stroke: var(--success); }
.spark .sp-bad  { stroke: var(--danger); }
.spark .sp-neu  { stroke: var(--accent); }
.spark circle.spd-good { fill: var(--success); }
.spark circle.spd-bad  { fill: var(--danger); }
.spark circle.spd-neu  { fill: var(--accent); }
.sc-year { font-size: 10px; color: var(--ink-3); font-weight: 400; }
.sc-rankmove { font-weight: 700; font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.sc-rankmove .of, .sc-rank .of { color: var(--ink-3); font-size: 0.82em; font-weight: 400; }
.sc-rank { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ink-2); }
.sc-rank.sc-good { color: var(--success); }
.sc-rank.sc-bad { color: var(--danger); }
@media print {
  /* keep the direction colours in the printed pack; only the neutral indigo needs
     darkening for paper (good/bad already use print-safe brand tokens) */
  .spark .sp-neu { stroke: #2A2483 !important; }
  .spark circle.spd-neu { fill: #2A2483 !important; }
  .sc-rankmove.yoy-good { color: var(--success) !important; }
  .sc-rankmove.yoy-bad { color: var(--danger) !important; }
  /* neutral 1-yr / rank-move text darkens for paper so it reads as "no clear
     direction", not as a disabled grey */
  .sc-table .yoy-neutral, .sc-rankmove.yoy-neutral { color: #45403A !important; }
}
.sig-standout-grid .sig-item { border-right: 1px solid var(--rule-soft); }
@media (max-width: 640px) {
  .signal-cols { grid-template-columns: 1fr; }
  .sig-standout-grid { grid-template-columns: 1fr; }
  .sig-standout-grid .sig-item { border-right: none; }
}

/* A4 information pack: print-only front matter (masthead + at-a-glance), hidden on screen */
.print-pack { display: none; }
@page { size: A4 landscape; margin: 11mm 13mm; }   /* the scorecard pack prints A4 landscape so the 9-column table has room */
@media print {
  /* bespoke A4 print: show ONLY the content container. One rule hides the whole page shell
     (site header + nav, the hero, the beta bar, the view tabs, mobile + drawer nav, footer,
     and any decoration) so none of the web chrome can leak onto the PDF. */
  body > *:not(#main) { display: none !important; }
  /* and the interactive bits that live inside the content itself */
  #main .controls, #main .btn, #main .section-nav, .sc-screen-wordmark, .sc-screen-title,
  .cmp-tray, .starter { display: none !important; }
  body { background: #fff; color: #14110D; font-size: 11px; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  main { padding: 0; max-width: none; }
  .card { break-inside: avoid; box-shadow: none; border: 1px solid var(--rule); }
  .kpi.kpi-lead::after, .kpi.kpi-watch::after { display: none !important; }   /* no on-screen pulses in the PDF */
  .sc-screen-wordmark, .sc-screen-title { display: none !important; }   /* the print pack replaces the on-screen header */
  .print-pack { display: block; }
  .ppk-head { border-bottom: 2.5px solid var(--accent); padding-bottom: 9px; margin-bottom: 12px; position: relative; }
  .ppk-wordmark { height: 28px; position: absolute; right: 0; top: 2px; }
  .ppk-kicker { font-family: var(--mono); font-size: 8.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--accent-deep); }
  .ppk-name { font-family: var(--serif); font-size: 27px; line-height: 1.04; margin: 4px 0 3px; color: #14110D; letter-spacing: -0.01em; }
  .ppk-sub { font-size: 9px; color: #666; max-width: 78%; }
  /* key-findings band: pulls the dashboard's signal, real-terms and focus reads */
  .ppk-findings { background: #F7F5F0; border: 1px solid #E4DFD2; border-left: 3px solid var(--accent); border-radius: 7px; padding: 8px 11px 9px; margin-bottom: 12px; break-inside: avoid; }
  .ppk-fh { font-family: var(--mono); font-size: 8px; letter-spacing: .12em; text-transform: uppercase; color: var(--accent-deep); margin-bottom: 4px; }
  .ppk-findings ul { margin: 0; padding: 0; list-style: none; }
  .ppk-findings li { font-size: 9.7px; line-height: 1.5; color: #2E2A22; margin-bottom: 2px; }
  .ppk-flbl { display: inline-block; min-width: 52px; font-family: var(--mono); font-size: 7px; letter-spacing: .04em; text-transform: uppercase; color: #888; font-weight: 700; vertical-align: 1px; }
  .ppk-fstr { color: var(--success); } .ppk-fwat { color: var(--danger); }
  .ppk-gh { font-family: var(--mono); font-size: 8px; letter-spacing: .1em; text-transform: uppercase; color: #999; margin-bottom: 5px; }
  .ppk-glance { display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px; margin-bottom: 6px; }
  .ppk-stat { border: 1px solid #E0DCCF; border-radius: 6px; padding: 6px 8px 7px; break-inside: avoid; background: #FFFEFB; }
  .ppk-k { font-family: var(--mono); font-size: 7px; letter-spacing: .03em; text-transform: uppercase; color: #777; line-height: 1.2; min-height: 17px; }
  .ppk-v { font-family: var(--display); font-weight: 700; font-size: 18px; color: #14110D; line-height: 1.05; }
  .ppk-v.ppk-good { color: var(--success); } .ppk-v.ppk-bad { color: var(--danger); }
  .ppk-r { font-size: 7.3px; color: #777; margin-top: 1px; }
  .ppk-med { font-size: 6.8px; color: #999; margin-top: 2px; line-height: 1.4; }
  /* interpretation + questions: turns the pack from a data sheet into a briefing */
  .ppk-rh { font-family: var(--serif); font-size: 12px; color: #14110D; margin: 13px 0 6px; padding-bottom: 3px; border-bottom: 1px solid #E4DFD2; break-after: avoid; }
  .ppk-reading { columns: 3; column-gap: 20px; margin-bottom: 4px; }   /* 3-up reading suits the landscape width */
  .ppk-reading .reading-sec { break-inside: avoid; margin-bottom: 6px; }
  .ppk-reading .reading-sec h4 { font-family: var(--mono); font-size: 7.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--accent-deep); margin: 0 0 2px; }
  .ppk-reading .reading-sec ul { margin: 0; padding-left: 12px; }
  .ppk-reading .reading-sec li { font-size: 8.4px; line-height: 1.4; color: #2E2A22; margin-bottom: 1.5px; }
  .ppk-reading .reading-sec li b { color: #14110D; }
  .ppk-prompts { margin: 0 0 8px; padding-left: 15px; break-inside: avoid; }
  .ppk-prompts li { font-size: 9.3px; line-height: 1.45; color: #2E2A22; margin-bottom: 3px; }
  /* the scorecard table must fit A4 width without clipping: kill the scroll wrapper, fix the
     layout to the page, scale the sparkline into its cell, repeat the header on each page */
  #main div[style*="overflow"] { overflow: visible !important; }
  /* table starts on its own page after the front matter */
  .sc-table-wrap { break-before: page; overflow: visible !important; }
  .sc-table { font-size: 8.4px; table-layout: fixed; width: 100%; break-before: auto; }
  .sc-table thead { display: table-header-group; }
  .sc-table th, .sc-table td { padding: 2.5px 4px; overflow: hidden; }
  .sc-table th:first-child, .sc-table td:first-child { width: 20%; white-space: normal; word-break: break-word; }
  .sc-table .sc-spark { width: 11%; }
  .sc-table .sc-spark svg { width: 100% !important; max-width: 60px; height: 15px; }
  .sc-table th { background: #211D31 !important; color: #fff !important; position: static; }
  .sc-table tr.section-row td { background: #E7E4FA !important; color: #2A2483 !important; }
  .sc-table tr, .sc-spark { break-inside: avoid; }
  .sc-rank.sc-good { color: var(--success) !important; } .sc-rank.sc-bad { color: var(--danger) !important; }
}
/* ---- Sector Financial Health panels (sh-*) ----
   Aligned to the standard .card system: same background, shadows, padding, font tokens and
   hover lift as section.block .card. Pulse rings use the same ::after / cb-*-pulse mechanism
   as .kpi.kpi-lead / .kpi.kpi-watch so the animation rhythm is identical site-wide. */
.sh-h2 { font-family: var(--serif); font-size: clamp(23px,2.3vw,29px); font-weight: 600; letter-spacing: -0.01em; line-height: 1.14; margin-bottom: 6px; color: var(--ink); }
.sh-lede { font-size: 13.5px; color: var(--ink-3); max-width: 720px; line-height: 1.6; margin-bottom: 24px; }
.sh-section-split { display:grid; grid-template-columns:2fr 1fr; gap:0 36px; align-items:start; margin-bottom:28px; }
.sh-section-split .sh-h2 { margin-bottom:0; }
.sh-section-split .sh-lede { font-size:11.5px; line-height:1.65; color:var(--ink-3); font-style:italic; border-left:2px solid rgba(20,17,13,.12); padding-left:12px; margin:4px 0 0; max-width:none; }
@media (max-width:700px) { .sh-section-split { grid-template-columns:1fr; gap:12px; } .sh-section-split .sh-lede { border-left:none; padding-left:0; } }

/* KPI tiles — standard card inside a section */
.sh-kpi-row { display:grid; grid-template-columns:repeat(auto-fill, minmax(208px,1fr)); gap:var(--gap-sm); margin-bottom:24px; }
/* Formula row (Section 02): hide + and = operators on mobile, stack cards */
@media (max-width:640px) { .sh-formula-row { grid-template-columns:1fr !important; } .sh-formula-op { display:none !important; } }
.sh-kpi { background:var(--paper-bright); border:1px solid var(--rule-soft); border-radius:var(--r-card); padding:var(--pad-card); display:flex; flex-direction:column; box-shadow:var(--shadow-tile), var(--rim-inset); position:relative; transition:box-shadow .2s cubic-bezier(.2,.7,.3,1), transform .2s cubic-bezier(.2,.7,.3,1), background .2s; }
@media (hover:hover) { .sh-kpi:hover { background:#fff; box-shadow:var(--shadow-lift), var(--rim-inset); transform:translateY(-3px); } }
.sh-kpi__label { font:500 10.5px var(--mono); letter-spacing:.06em; color:var(--ink-3); margin-bottom:6px; text-transform:uppercase; min-height:27px; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.sh-kpi__value { font:700 30px var(--display); letter-spacing:-0.02em; line-height:1.1; margin-bottom:6px; min-height:33px; white-space:nowrap; }
.sh-kpi__note { font-size:12px; color:var(--ink-3); line-height:1.45; flex:1; }
.sh-kpi__source { font:400 10px var(--mono); letter-spacing:.03em; color:var(--ink-3); opacity:.75; margin-top:10px; padding-top:8px; border-top:1px solid var(--rule-soft); line-height:1.5; }
/* colour-keyed tiles: border + value colour + pulsing ::after ring — identical mechanism to .kpi.kpi-lead / .kpi.kpi-watch */
.sh-kpi--red { border-color:rgba(142,46,46,.65); }
.sh-kpi--red .sh-kpi__value { color:var(--danger); }
.sh-kpi--red::after { content:""; position:absolute; inset:-1.5px; border-radius:inherit; pointer-events:none; box-shadow:0 0 0 0 var(--watch-ring); animation:cb-watch-pulse 2.3s ease-in-out infinite; }
.sh-kpi--green { border-color:rgba(61,90,61,.65); }
.sh-kpi--green .sh-kpi__value { color:var(--success); }
.sh-kpi--green::after { content:""; position:absolute; inset:-1.5px; border-radius:inherit; pointer-events:none; box-shadow:0 0 0 0 var(--lead-ring); animation:cb-lead-pulse 2.2s ease-in-out infinite; }
.sh-kpi--amber { border-color:rgba(180,110,20,.55); }
.sh-kpi--amber .sh-kpi__value { color:#8E6E2E; }
.sh-kpi--amber::after { content:""; position:absolute; inset:-1.5px; border-radius:inherit; pointer-events:none; box-shadow:0 0 0 0 rgba(180,110,20,.55); animation:cb-amber-pulse 2.3s ease-in-out infinite; }
@keyframes cb-amber-pulse { 0% { box-shadow:0 0 0 0 rgba(180,110,20,.55); } 70%,100% { box-shadow:0 0 0 9px rgba(180,110,20,0); } }
.sh-kpi--blue { border-color:rgba(91,79,229,.5); }
.sh-kpi--blue .sh-kpi__value { color:var(--accent-deep); }
.sh-kpi--blue::after { content:""; position:absolute; inset:-1.5px; border-radius:inherit; pointer-events:none; box-shadow:0 0 0 0 rgba(91,79,229,.5); animation:cb-blue-pulse 2.25s ease-in-out infinite; }
@keyframes cb-blue-pulse { 0% { box-shadow:0 0 0 0 rgba(91,79,229,.5); } 70%,100% { box-shadow:0 0 0 9px rgba(91,79,229,0); } }
@media (prefers-reduced-motion:reduce) { .sh-kpi--red::after, .sh-kpi--green::after, .sh-kpi--amber::after, .sh-kpi--blue::after { animation:none; } }
/* drifting smoke behind a card (fossil-fuel context) — charcoal wisps rising from the
   base. Uses ::before (the pulse uses ::after); animated via background-position so it
   stays clipped inside the rounded card and never disturbs the pulse ring. */
.sh-smoke > * { position: relative; z-index: 1; }
.sh-smoke::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: 0; pointer-events: none;
  background:
    radial-gradient(60% 80% at 25% 118%, rgba(28,25,22,.42), transparent 62%),
    radial-gradient(55% 75% at 70% 122%, rgba(50,45,40,.36), transparent 62%),
    radial-gradient(48% 68% at 50% 132%, rgba(16,14,12,.46), transparent 58%);
  background-size: 180% 180%; background-position: 50% 100%;
  filter: blur(6px); clip-path: inset(0 round var(--r-card));
  animation: cb-smoke 11s ease-in-out infinite alternate;
}
@keyframes cb-smoke { 0% { background-position: 38% 100%; } 100% { background-position: 62% 78%; } }
@media (prefers-reduced-motion: reduce) { .sh-smoke::before { animation: none; } }

/* chart cards — same base as standard .card.chartcard, with hover lift */
.sh-chart-grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(380px,1fr)); gap:var(--gap); margin-bottom:24px; }
.sh-chart-card { background:var(--paper-bright); border:1px solid var(--rule-soft); border-radius:var(--r-card); padding:var(--pad-card); box-shadow:var(--shadow-tile), var(--rim-inset); position:relative; transition:box-shadow .2s cubic-bezier(.2,.7,.3,1), transform .2s cubic-bezier(.2,.7,.3,1), background .2s; }
@media (hover:hover) { .sh-chart-card:hover { background:#fff; box-shadow:var(--shadow-lift), var(--rim-inset); transform:translateY(-3px); } }
.sh-chart-card h3 { font:700 15px var(--display); letter-spacing:-0.01em; margin-bottom:4px; color:var(--ink-2); }
.sh-chart-card p { font-size:12.5px; color:var(--ink-3); margin-bottom:12px; line-height:1.45; }
.sh-chart-card .sh-ref { margin-top:10px; }
.sh-chart-wrap { position:relative; }
.sh-ref { font:400 10px var(--mono); letter-spacing:.03em; color:var(--ink-3); opacity:.75; padding-top:8px; border-top:1px solid var(--rule-soft); line-height:1.5; margin-top:8px; }
/* trend dot: same mechanism as .chart-pulse — ::after ring uses cb-pt-pulse */
.sh-trend-dot { position:absolute; top:14px; right:14px; width:9px; height:9px; border-radius:50%; z-index:2; box-shadow:0 0 0 2px var(--paper-bright); }
.sh-trend-dot::after { content:""; position:absolute; inset:0; border-radius:50%; background:inherit; opacity:.5; animation:cb-pt-pulse 1.9s cubic-bezier(.2,.6,.3,1) infinite; }
.sh-trend-dot--green { background:var(--success); }
.sh-trend-dot--red   { background:var(--danger); }
@media (prefers-reduced-motion:reduce) { .sh-trend-dot::after { animation:none; } }

/* country comparison cards */
.sh-compare-grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(240px,1fr)); gap:var(--gap-sm); margin-bottom:24px; }
.sh-compare-card { background:var(--paper-bright); border:1px solid var(--rule-soft); border-radius:var(--r-card); padding:var(--pad-card); box-shadow:var(--shadow-tile), var(--rim-inset); transition:box-shadow .2s cubic-bezier(.2,.7,.3,1), transform .2s cubic-bezier(.2,.7,.3,1), background .2s; }
@media (hover:hover) { .sh-compare-card:hover { background:#fff; box-shadow:var(--shadow-lift), var(--rim-inset); transform:translateY(-3px); } }
.sh-compare-card h3 { font:700 15px var(--display); letter-spacing:-0.01em; margin-bottom:12px; padding-bottom:10px; border-bottom:2px solid var(--rule-soft); color:var(--ink); }
.sh-compare-card h3 .country-code { font:400 10px var(--mono); letter-spacing:.08em; text-transform:uppercase; color:var(--ink-3); display:block; margin-bottom:2px; }
.sh-compare-row { display:flex; justify-content:space-between; align-items:baseline; padding:5px 0; border-bottom:1px solid var(--rule-soft); font-size:12.5px; }
.sh-compare-row:last-child { border-bottom:none; }
.sh-compare-row .metric { color:var(--ink-3); padding-right:8px; }
.sh-compare-row .val { font-weight:600; font-size:12.5px; text-align:right; }
.sh-compare-row .val--strong { color:var(--success); }
.sh-compare-row .val--mid { color:#8E6E2E; }
.sh-compare-row .val--weak { color:var(--danger); }

/* force / pressure grid */
.sh-force-grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(260px,1fr)); gap:var(--gap-sm); margin-bottom:24px; }
.sh-force { background:var(--paper-bright); border:1px solid var(--rule-soft); border-radius:var(--r-card); padding:var(--pad-card); box-shadow:var(--shadow-tile), var(--rim-inset); transition:box-shadow .2s cubic-bezier(.2,.7,.3,1), transform .2s cubic-bezier(.2,.7,.3,1), background .2s; }
@media (hover:hover) { .sh-force:hover { background:#fff; box-shadow:var(--shadow-lift), var(--rim-inset); transform:translateY(-3px); } }
.sh-force__dir { font:700 10.5px var(--mono); letter-spacing:.08em; text-transform:uppercase; margin-bottom:6px; }
.sh-force__dir--up   { color:var(--success); }
.sh-force__dir--down { color:var(--danger); }
.sh-force__dir--both { color:#8E6E2E; }
.sh-force h3 { font:700 14px var(--display); margin-bottom:6px; color:var(--ink); }
.sh-force p  { font-size:12.5px; color:var(--ink-2); line-height:1.5; margin-bottom:8px; }
.sh-force .stat { font:700 14px var(--display); color:var(--ink); margin-bottom:4px; }

/* ── Mobile audit fixes ── */
@media (max-width:640px) {
  /* 1. KPI value: allow wrapping so long dollar/percent strings don't bleed outside cards */
  .sh-kpi__value { white-space:normal; overflow-wrap:break-word; font-size:24px; }
  /* 2. KPI label: allow 3 lines on single-column mobile layout */
  .sh-kpi__label { -webkit-line-clamp:3; min-height:auto; }
  /* 3. All KPI rows: restore auto-fill responsive — overrides every inline repeat(N,1fr) */
  .sh-kpi-row { grid-template-columns:repeat(auto-fill, minmax(208px,1fr)) !important; }
  /* 4. Chart cards: 380px minimum exceeds phone width — force single column */
  .sh-chart-grid { grid-template-columns:1fr; }
  /* 5. Compare rows: reduce font so long metric labels don't crowd the value */
  .sh-compare-row { font-size:11.5px; }
  .sh-compare-row .val { font-size:11.5px; }
  /* 6. Overhead comparison bars: constrain label cell on narrow screens */
  .sh-oc__lbl-cell { flex:0 0 110px; }
  /* 7. Scroll margin: account for taller sticky nav stack on mobile */
  section.block { scroll-margin-top:120px; }
}

/* research overhead comparison bars (sh-oc) */
.sh-oc { padding:2px 0 4px; }
.sh-oc__scale { display:flex; margin-bottom:8px; }
.sh-oc__lbl-cell { flex:0 0 148px; padding-right:12px; }
.sh-oc__lbl-cell strong { font:700 13px var(--display); display:block; line-height:1.2; }
.sh-oc__lbl-cell em { font:400 10px var(--mono); color:var(--ink-3); font-style:normal; display:block; margin-top:1px; }
.sh-oc__lbl-cell--inst { font:400 11.5px var(--mono); color:var(--ink-3); padding-left:12px; }
.sh-oc__ticks { flex:1; position:relative; height:16px; }
.sh-oc__ticks span { position:absolute; font:400 9.5px var(--mono); color:var(--ink-3); transform:translateX(-50%); }
.sh-oc__ticks span:first-child { transform:none; }
.sh-oc__row { display:flex; align-items:center; margin-bottom:8px; min-height:28px; }
.sh-oc__row--sm { margin-bottom:5px; min-height:20px; }
.sh-oc__bars { flex:1; display:flex; align-items:center; position:relative; min-height:26px; background-image:linear-gradient(90deg,transparent calc(23.53% - 0.5px),var(--rule-soft) calc(23.53% - 0.5px),var(--rule-soft) calc(23.53% + 0.5px),transparent calc(23.53% + 0.5px),transparent calc(47.06% - 0.5px),var(--rule-soft) calc(47.06% - 0.5px),var(--rule-soft) calc(47.06% + 0.5px),transparent calc(47.06% + 0.5px),transparent calc(70.59% - 0.5px),var(--rule-soft) calc(70.59% - 0.5px),var(--rule-soft) calc(70.59% + 0.5px),transparent calc(70.59% + 0.5px),transparent calc(94.12% - 0.5px),var(--rule-soft) calc(94.12% - 0.5px),var(--rule-soft) calc(94.12% + 0.5px),transparent calc(94.12% + 0.5px)); }
.sh-oc__bar { height:26px; border-radius:2px; display:flex; align-items:center; flex-shrink:0; }
.sh-oc__bar--sm { height:18px; }
.sh-oc__bar--au   { background:var(--danger); }
.sh-oc__bar--uk   { background:#B08010; }
.sh-oc__bar--us   { background:var(--success); }
.sh-oc__bar--inst { background:#2D4A2D; opacity:.7; }
.sh-oc__pct { font:700 11px var(--mono); color:#fff; padding:0 8px; white-space:nowrap; }
.sh-oc__gap { height:26px; border:1.5px dashed var(--danger); border-radius:0 2px 2px 0; opacity:.6; display:flex; align-items:center; flex-shrink:0; margin-left:2px; }
.sh-oc__gap-txt { font:400 9.5px var(--mono); color:var(--danger); padding:0 7px; white-space:nowrap; }
.sh-oc__sect { font:700 10px var(--mono); letter-spacing:.07em; text-transform:uppercase; color:var(--ink-3); padding:10px 0 7px 148px; border-top:1px solid var(--rule-soft); margin-top:4px; }
@media (max-width:560px) { .sh-oc__lbl-cell { flex:0 0 90px; } .sh-oc__lbl-cell--inst { padding-left:6px; } .sh-oc__sect { padding-left:90px; } .sh-oc__gap-txt { display:none; } }

/* CLS fix (22 Jun 2026): reserve a viewport of height on #main so the page is
   full-height from first paint. Before app.js runs, #main holds only the
   "Loading verified data…" line, so the footer sat directly beneath it and
   jumped far down the page once a view rendered (real-user CLS ~0.69 on #main,
   ~0.31 on footer.site, Cloudflare Web Analytics). Reserving the height pushes
   the footer below the fold immediately, so the content fill happens off-screen
   and contributes ~0 to CLS. Screen-only: the print/PDF export (which hides
   everything except #main) keeps its natural height. */
@media screen {
  #main { min-height: 100vh; }
}
