/* Australian Portfolio Lab – IYI look (per PLAN_PUBLIC_WEBSITE.md).
 * Tokens on :root; dark theme via data-theme (toggle) with
 * prefers-color-scheme as the default signal. */

:root {
  --bg: #FCF8ED; --card: #ffffff; --ink: #14212e; --ink2: #4e5a66;
  --line: #E8DFD0; --hero-bg: #00305B; --hero-ink: #ffffff;
  --hero-ink2: #C9D8E8; --accent: #C1A06B; --accent-ink: #2b2416;
  --mark: #0F4C85; --mark-strong: #00305B; --grid: #e7e2d6;
  --chip-bg: #FBF2E6; --focusring: #C1A06B; --axis: #3f4a55;
  --s1: #6FA3DE; --s2: #A87B2F; --s3: #0E8A6D; --s4: #6B3FA0; --s5: #9C5A2A;
  --median: #001B33; --median-2: #2F5F8F;
  --neg: #B3552E; --pulse: rgba(193, 160, 107, .60);
  --pulse-strong: rgba(150, 112, 48, .95);
  --pulse-edge: rgba(0, 48, 91, .45); --pulse-tint: rgba(0, 48, 91, .14);
  --pulse-glow: rgba(193, 160, 107, .55);
  --display: "Avenir Next", Avenir, Futura, "Trebuchet MS", sans-serif;
  --body: "Avenir Next", Avenir, "Helvetica Neue", Arial, sans-serif;
  --brand-face: Georgia, "Times New Roman", serif;
  /* Fixed brand-band tokens – deliberately NOT redefined per theme, so the
     light header is identical in light and dark (the logo's navy elements
     would vanish on a dark band). Matches the white header at
     inyourinterest.com.au. */
  --band-bg: #ffffff; --band-line: #E8DFD0; --band-ink: #00305B;
  --band-ink-hover: #001b33; --band-accent: #C1A06B;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #001528; --card: #062138; --ink: #F3EDDD; --ink2: #B9C6D4; --axis: #B9C6D4;
    --line: #12324e; --hero-bg: #00203D; --hero-ink: #ffffff;
    --hero-ink2: #C9D8E8; --accent: #C1A06B; --accent-ink: #201a0e;
    --mark: #83B7E6; --mark-strong: #C1A06B; --grid: #103050;
    --chip-bg: #0b2a44;
    --s1: #5793D8; --s2: #B07A24; --s3: #188F68; --s4: #9B6FCF; --s5: #C98A4E;
  --median: #2F6FB5; --median-2: #8FCBFF;
    --neg: #D97A50; --pulse: rgba(193, 160, 107, .72);
    --pulse-strong: rgba(233, 206, 156, .95);
  --pulse-edge: rgba(255, 255, 255, .42); --pulse-tint: rgba(255, 255, 255, .18);
    --pulse-glow: rgba(193, 160, 107, .45);
  }
}
:root[data-theme="dark"] {
  --bg: #001528; --card: #062138; --ink: #F3EDDD; --ink2: #B9C6D4; --axis: #B9C6D4;
  --line: #12324e; --hero-bg: #00203D; --hero-ink: #ffffff;
  --hero-ink2: #C9D8E8; --accent: #C1A06B; --accent-ink: #201a0e;
  --mark: #83B7E6; --mark-strong: #C1A06B; --grid: #103050;
  --chip-bg: #0b2a44;
  --s1: #5793D8; --s2: #B07A24; --s3: #188F68; --s4: #9B6FCF; --s5: #C98A4E;
  --median: #2F6FB5; --median-2: #8FCBFF;
  --neg: #D97A50; --pulse: rgba(193, 160, 107, .72);
  --pulse-strong: rgba(233, 206, 156, .95);
  --pulse-edge: rgba(255, 255, 255, .42); --pulse-tint: rgba(255, 255, 255, .18);
  --pulse-glow: rgba(193, 160, 107, .45);
}
:root[data-theme="light"] {
  --bg: #FCF8ED; --card: #ffffff; --ink: #14212e; --ink2: #4e5a66; --axis: #3f4a55;
  --line: #E8DFD0; --hero-bg: #00305B; --hero-ink: #ffffff;
  --hero-ink2: #C9D8E8; --accent: #C1A06B; --accent-ink: #2b2416;
  --mark: #0F4C85; --mark-strong: #00305B; --grid: #e7e2d6;
  --chip-bg: #FBF2E6;
  --s1: #6FA3DE; --s2: #A87B2F; --s3: #0E8A6D; --s4: #6B3FA0; --s5: #9C5A2A;
  --median: #001B33; --median-2: #2F5F8F;
  --neg: #B3552E; --pulse: rgba(193, 160, 107, .60);
  --pulse-strong: rgba(150, 112, 48, .95);
  --pulse-edge: rgba(0, 48, 91, .45); --pulse-tint: rgba(0, 48, 91, .14);
  --pulse-glow: rgba(193, 160, 107, .55);
}

/* --median / --median-2: tab 5's median starting-year bar (Christoph,
   2 Aug: "make the median bar dark blue"). --median-2 is the lighter navy
   the pension stack's income segment uses, so a stacked median bar is
   still two readable pieces.

   LIGHT is the brand navy family, one step DOWN from #00305B: that exact
   navy is already --mark-strong, which tab 5 gives the best and worst
   bars, and three bars in one colour would say nothing. #001B33 is the
   band's own hover navy, unmistakably the darkest bar on the chart.

   DARK cannot go darker – the card is already near-black navy – so the
   median reads as the DEEPEST, most saturated blue instead of the darkest:
   #2F6FB5 against the #062138 card is 3.17:1, past the 3:1 floor for a
   graphical object, and clearly deeper than the ordinary #83B7E6 bars.
   Its income segment goes lighter (#8FCBFF, 2.99:1 against the residual)
   rather than darker, for the same reason. */

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; padding: 0; }
body { background: var(--bg); color: var(--ink);
       font: 15px/1.55 var(--body); }

.ribbon { background: var(--accent); color: var(--accent-ink);
  text-align: center; font: 600 12.5px/1 var(--display);
  letter-spacing: .06em; padding: 7px 12px; }

/* Light brand band – full-width, fixed colours in both light and dark. */
.band { background: var(--band-bg); border-bottom: 1px solid var(--band-line); }
.nav { max-width: 1160px; margin: 0 auto; display: flex; align-items: center;
  gap: 24px; padding: 12px 22px; flex-wrap: wrap; }
.brand { display: flex; align-items: center; text-decoration: none; }
.brand img { height: 52px; width: auto; display: block; }
.nav .links { margin-left: auto; display: flex; gap: 14px 20px;
  align-items: center; flex-wrap: wrap; justify-content: flex-end;
  font-family: var(--display); font-size: 12px; letter-spacing: .12em;
  text-transform: uppercase; }
.nav .links a { color: var(--band-ink); text-decoration: none; }
.nav .links a:hover { color: var(--band-ink-hover); text-decoration: underline; }
.nav .links a.on { color: var(--band-ink);
  border-bottom: 2px solid var(--band-accent); padding-bottom: 3px; }
.nav .links a.on:hover { text-decoration: none; }
#themeToggle { background: transparent; border: 1.5px solid var(--band-ink);
  color: var(--band-ink); border-radius: 999px; padding: 6px 12px;
  font: 600 12px/1 var(--display); cursor: pointer; }
#themeToggle:hover { background: var(--band-ink); color: var(--band-bg); }

/* Mobile menu toggle – hidden on desktop, shown ≤640px. Styled to sit on the
   fixed light band exactly like #themeToggle (navy on white, both themes). */
#navToggle { display: none; align-items: center; gap: 8px;
  background: transparent; border: 1.5px solid var(--band-ink);
  color: var(--band-ink); border-radius: 999px; padding: 7px 13px;
  font: 600 12px/1 var(--display); letter-spacing: .06em; cursor: pointer; }
#navToggle:hover { background: var(--band-ink); color: var(--band-bg); }
#navToggle .nav-glyph { font-size: 15px; line-height: 1; }

@media (max-width: 640px) {
  .brand img { height: 40px; }
  #navToggle { display: inline-flex; margin-left: auto; }
  /* Collapse the nav links behind the button (full-width dropdown). Scoped to
     the sibling of #navToggle, so assumptions.html's single back-link – which
     has no toggle button – is left inline and untouched. */
  #navToggle ~ .links { display: none; width: 100%; margin-left: 0;
    gap: 0; padding-top: 4px; flex-direction: column; align-items: stretch;
    border-top: 1px solid var(--band-line); }
  #navToggle ~ .links.open { display: flex; }
  #navToggle ~ .links a,
  #navToggle ~ .links #themeToggle { display: block; width: 100%;
    text-align: left; padding: 13px 6px; border: 0;
    border-bottom: 1px solid var(--band-line); border-radius: 0;
    background: transparent; color: var(--band-ink); }
  #navToggle ~ .links a.on { border-left: 3px solid var(--band-accent);
    padding-left: 12px; }
  #navToggle ~ .links #themeToggle { border-bottom: 0; font-weight: 700; }
}

.hero { background: var(--hero-bg); color: var(--hero-ink);
  padding: 26px 0 30px; }
.hero-in { max-width: 1160px; margin: 0 auto; padding: 0 22px; }
/* Constant hero height on desktop: a min-height sized to the tallest real
   content (measured across all seven tabs, both contexts – the peak is
   tab 1's long headline plus the two-line after-CGT gold line, 261px once
   the h1 hits its 36px clamp ceiling at >=1000px; small margin added).
   Keeps the blue band a fixed height so toggling the after-CGT line or
   switching tabs moves only the chart below – the after-CGT toggle must
   not shift the chart. Below 900px it is unset so mobile heroes may grow. */
@media (min-width: 900px) { .hero-in { min-height: 264px; } }
.eyebrow { font-family: var(--display); font-size: 12px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--accent); margin: 0 0 8px; }
.hero h1 { font-family: var(--display); font-weight: 700; margin: 0 0 12px;
  font-size: clamp(24px, 3.6vw, 36px); max-width: 40ch; text-wrap: balance; }
.headline { font-size: clamp(15.5px, 2vw, 18px); line-height: 1.55;
  max-width: 68ch; color: var(--hero-ink2); margin: 0; }
.headline strong { color: var(--hero-ink); }
/* after-CGT stat line under the headline (personal, Outside super) */
.cgtline { font-size: clamp(13.5px, 1.7vw, 15px); line-height: 1.5;
  max-width: 68ch; margin: 10px 0 0; color: var(--hero-ink2); }
.cgtline strong { color: var(--accent); font-variant-numeric: tabular-nums; }

.tabs { max-width: 1240px; margin: 18px auto 0; padding: 0 22px;
  display: flex; gap: 8px; flex-wrap: wrap; }
.tabs button { font: 600 13px/1.2 var(--display); padding: 10px 14px;
  border-radius: 999px; border: 1.5px solid var(--line);
  background: var(--card); color: var(--ink); cursor: pointer; }
/* On wide viewports the seven tabs fit on one line: the wider cap above
   plus a modestly tighter gap/padding here keep them single-line at
   1280px and up. Narrow screens keep the base gap/padding and wrap. */
@media (min-width: 900px) {
  .tabs { gap: 7px; }
  .tabs button { padding: 10px 12px; }
}
.tabs button[aria-selected="true"] { background: var(--mark-strong);
  border-color: var(--mark-strong); color: #fff; }
:root[data-theme="dark"] .tabs button[aria-selected="true"],
[data-dark] .tabs button[aria-selected="true"] { color: #06121f; }
.tabs button.dim { opacity: .75; font-weight: 500; }
/* Responsive tab label: "How tax works" on desktop, "Tax" on mobile. */
.tabs .tshort { display: none; }
@media (max-width: 640px) {
  .tabs .tlong { display: none; }
  .tabs .tshort { display: inline; }
}
.tabs button:focus-visible, .chips button:focus-visible,
button:focus-visible, a:focus-visible, input:focus-visible,
select:focus-visible, summary:focus-visible {
  outline: 3px solid var(--focusring); outline-offset: 2px; }
/* the brand band is fixed white in both themes; the gold ring reads
 * under 3:1 there, so focus on the band uses navy instead */
.band a:focus-visible, .band button:focus-visible {
  outline-color: #00305B; }

main { max-width: 1160px; margin: 16px auto 40px; padding: 0 22px;
  display: grid; grid-template-columns: minmax(280px, 26em) minmax(0, 1fr);
  gap: 18px; align-items: start; }
@media (max-width: 900px) { main { grid-template-columns: 1fr; } }
.slider-row { flex-wrap: wrap; }
.slider-row input[type="range"] { flex: 1 1 150px; min-width: 120px; }

.panel { display: grid; gap: 14px; }
.card { background: var(--card); border: 1px solid var(--line);
  border-radius: 10px; padding: 16px 18px; }
.card h2 { font-family: var(--display); font-size: 15px; margin: 0 0 10px; }
.card h3 { font-family: var(--display); font-size: 14.5px; margin: 0 0 4px; }
.card h4 { font-family: var(--display); font-size: 13px; margin: 14px 0 4px; }
.sub { color: var(--ink2); font-size: 13px; margin: 0 0 12px; }
/* left control panel dialled between the body 15px and the chart-text
 * 13px (Christoph 28 Jul) */
.panel { font-size: 14px; }
.panel input, .panel select, .panel .chips button { font-size: 14px; }
.note { color: var(--ink2); font-size: 12.5px; margin: 8px 0 0; }

.row { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin: 8px 0; }
.row label { font-size: 13.5px; }
input[type="number"], select { font: inherit; color: var(--ink);
  background: var(--card); border: 1px solid var(--line); border-radius: 7px;
  padding: 6px 8px; max-width: 130px; font-variant-numeric: tabular-nums; }
input[type="checkbox"] { width: 17px; height: 17px; accent-color: var(--mark); }
.slider-row { display: flex; align-items: center; gap: 12px; margin: 6px 0; }
.slider-row input[type="range"] { flex: 1; accent-color: var(--mark);
  height: 30px; }
.slider-row input[type="number"] { max-width: 82px; }
.mixdot { width: 11px; height: 11px; border-radius: 3px; flex: none; }

/* R16's label selector: five options whose wording is a full sentence, so
   they stack one per line rather than sharing a .row with a narrow select.
   The label wraps under itself, never under its own radio. */
.radiolist { display: grid; gap: 8px; margin: 2px 0 0; }
.radiolist label { display: grid; grid-template-columns: 16px 1fr; gap: 9px;
  align-items: start; font-size: 13.5px; line-height: 1.35; cursor: pointer; }
.radiolist input[type="radio"] { width: 15px; height: 15px; margin: 2px 0 0;
  accent-color: var(--mark); }
/* disabled where the option cannot mean anything (no inflation selected) –
   dimmed like the R13 switch's .off state */
.radiolist label.off { opacity: .45; cursor: default; }
.card h2 button.info { vertical-align: 0; }

/* Shown only on the wide layout: below 900px the control panel stacks
   UNDER the chart, so "in the left sidebar" would point at nothing. */
.desk-only { display: none; }
@media (min-width: 900px) { .desk-only { display: block; } }

.chips { display: flex; gap: 7px; flex-wrap: wrap; margin: 8px 0 2px; }
.chips button { font: 600 12px/1 var(--display); padding: 7px 11px;
  border-radius: 999px; border: 1.5px solid var(--line);
  background: var(--chip-bg); color: var(--ink); cursor: pointer; }
.chips button[aria-pressed="true"] { background: var(--mark); color: #fff;
  border-color: var(--mark); }
:root[data-theme="dark"] .chips button[aria-pressed="true"] { color: #06121f; }
.preset-sub { color: var(--ink2); font-size: 12.5px; margin: 6px 0 0; }
/* relocated regime selector (in the You card): the two chips sit beside
 * their label, wrapping under it on a cramped panel; drop the .chips
 * vertical margin so the row height matches the other control rows */
#stressRegimeRow { flex-wrap: wrap; }
#stressRegimeRow .chips { margin: 0; }

details.more { border-top: 1px dashed var(--line); padding-top: 10px; }
details.more summary { cursor: pointer; color: var(--ink2);
  font: 600 13px var(--display); }
details.more .row label { color: var(--ink2); }
/* the two bold section headings inside More options: Investment Variables,
   then the relocated Costs block. Same weight as a card's own h2 so the
   accordion reads as two labelled groups rather than one long list. */
details.more .optgroup { font-family: var(--display); font-size: 13.5px;
  font-weight: 700; color: var(--ink); margin: 14px 0 6px;
  padding-top: 10px; border-top: 1px solid var(--line); }
details.more .optgroup:first-of-type { margin-top: 8px; padding-top: 0;
  border-top: 0; }
/* A control group nested INSIDE More options: the three-way defensive
   split expands from the bonds row it belongs to, so it is indented and
   its own summary is quieter than the accordion's. Progressive
   disclosure, one level deeper (Christoph, 21 Aug 2026: numerous
   controls are fine when they hide and show as needed). */
details.subopt { margin: 2px 0 8px 10px; padding-left: 8px;
  border-left: 2px solid var(--line); }
details.subopt summary { cursor: pointer; color: var(--ink2);
  font: 600 12.5px var(--display); padding: 3px 0; }
details.subopt .chips { margin: 6px 0 2px; }
details.subopt .note { margin: 6px 0 2px; }

.focus-note { font-size: 12px; color: var(--ink2); font-style: italic; }

.stage { display: grid; gap: 16px; min-width: 0; }
.stat-row { display: grid; grid-template-columns: repeat(3, minmax(0,1fr));
  gap: 12px; }
@media (max-width: 700px) { .stat-row { grid-template-columns: 1fr; } }
.stat .big { font-family: var(--display); font-size: 30px; font-weight: 700;
  font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.stat .lbl { color: var(--ink2); font-size: 12.5px; line-height: 1.45;
  margin-top: 3px; }

.chart-wrap { position: relative; }
.chart-wrap svg { width: 100%; height: auto; display: block; }
.legend { display: flex; gap: 14px; flex-wrap: wrap; margin: 2px 0 8px;
  font-size: 13px; }
.legend .key { display: inline-flex; align-items: center; gap: 6px; }
.legend .swatch { width: 12px; height: 12px; border-radius: 3px; }
.tip { position: absolute; pointer-events: none; background: var(--card);
  color: var(--ink); border: 1px solid var(--line); border-radius: 8px;
  padding: 8px 11px; font-size: 12.5px; line-height: 1.5;
  box-shadow: 0 3px 14px rgba(0,0,0,.16); opacity: 0; max-width: 260px;
  font-variant-numeric: tabular-nums; z-index: 5; }
@media (prefers-reduced-motion: no-preference) {
  .tip { transition: opacity .12s ease; }
}
.takeaway { border-left: 4px solid var(--accent); }
.takeaway ul { margin: 4px 0 2px; padding-left: 20px; }
.takeaway li { margin: 7px 0; line-height: 1.55; }
/* R11's two-orderings note, at the bottom of tab 4: quiet and collapsed,
   in the same family as the data-table disclosure. */
details.orders summary { cursor: pointer; color: var(--ink2);
  font: 600 13px var(--display); }
details.orders p { color: var(--ink2); font-size: 13px; line-height: 1.6;
  max-width: 78ch; margin: 9px 0 0; }
details.orders strong { color: var(--ink); font-variant-numeric: tabular-nums; }

details.tbl { font-size: 13px; margin-top: 10px; }
details.tbl summary { cursor: pointer; color: var(--ink2); }
.tbl-scroll { overflow-x: auto; }
table { border-collapse: collapse; margin-top: 10px; min-width: 480px;
  font-variant-numeric: tabular-nums; }
th, td { text-align: right; padding: 5px 12px;
  border-bottom: 1px solid var(--line); }
th:first-child, td:first-child { text-align: left; }
th { font-family: var(--display); font-size: 11.5px; text-transform: uppercase;
  letter-spacing: .06em; color: var(--ink2); }

.cardactions { float: right; display: flex; gap: 8px; margin: -2px 0 6px 12px; }
.cardactions button { font: 600 11.5px/1 var(--display); padding: 7px 10px;
  border-radius: 999px; border: 1.5px solid var(--line);
  background: var(--chip-bg); color: var(--ink); cursor: pointer; }
.cardactions button:hover { border-color: var(--mark); }

/* "Rescale chart" affordance: sits just under the chart, right-aligned, in
   the cardactions family but smaller and quieter. Hidden until the current
   data falls outside the sticky scale's 35–100% band (see frame()). */
.rescale-row { display: flex; justify-content: flex-end; gap: 8px;
  margin: 6px 0 0; }
#investedBtn,
#rescaleBtn, #arrowsBtn { font: 600 11px/1 var(--display); padding: 5px 10px;
  border-radius: 999px; border: 1.5px solid var(--line);
  background: var(--chip-bg); color: var(--ink2); cursor: pointer; }
#investedBtn:hover,
#rescaleBtn:hover, #arrowsBtn:hover { border-color: var(--mark);
  color: var(--ink); }
/* R13's display lens, sitting beside Rescale because the two are a
   conversation: switch on, the bars clip, rescale, switch off, watch them
   drop. Disabled (.off) when no inflation is selected. */
.rescale-row .nomswitch { display: inline-flex; align-items: center; gap: 6px;
  font: 600 11px/1 var(--display); color: var(--ink2); cursor: pointer; }
.rescale-row .nomswitch:hover { color: var(--ink); }
.rescale-row .nomswitch input { width: 15px; height: 15px; }
.rescale-row .nomswitch.off { opacity: .45; cursor: default; }
.rescale-row #nominalInfo { margin-left: 0; }
#nominalNote, #nominalNone { max-width: 92ch; }

/* Controls a view cannot act on (tab 1 charts a lump sum): dimmed, but
   deliberately still operable – a visitor may set them up for other tabs,
   so no pointer-events blocking and no disabled attribute. */
.row.inert { opacity: .45; }

/* a button that reads as a link: the one on tab 5 that opens the recycling
 * preset on tab 8 (4 September 2026) */
button.linky { background: none; border: 0; padding: 0; text-align: left;
  color: var(--mark); text-decoration: underline; cursor: pointer;
  font: inherit; }
button.linky:hover { text-decoration: none; }
button.info { width: 17px; height: 17px; border-radius: 50%; padding: 0;
  border: 1.5px solid var(--ink2); background: transparent;
  color: var(--ink2); font: italic 700 11px/1 Georgia, serif;
  cursor: pointer; flex: none; margin-left: 6px; vertical-align: 1px; }
button.info[aria-expanded="true"] { background: var(--mark); color: #fff;
  border-color: var(--mark); }
.tipnote { color: var(--ink2); font-size: 12.5px; line-height: 1.5;
  margin: 2px 0 8px; padding: 8px 10px; background: var(--chip-bg);
  border-radius: 8px; }

/* ── app note: something the APP did, or a reminder it computed ───────
   Distinct from .tipnote, which answers a question the visitor asked by
   pressing ⓘ. An .appnote appears on its own – an auto-untick, a kept
   override, the pension-age reminder – so it is tinted with the accent and
   carries role="status" from the JS side. Two flavours: transient (faded out
   by the JS after ~6s) and standing (cleared by an event). */
.appnote { color: var(--ink2); font-size: 12px; line-height: 1.5;
  margin: 0 0 8px; padding: 7px 10px; background: var(--chip-bg);
  border-left: 3px solid var(--accent); border-radius: 0 8px 8px 0;
  opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .appnote { transition: opacity .38s ease; }
}
.appnote.fading { opacity: 0; }

/* ── attention pulse (REUSABLE – R17 reuses this) ─────────────────────
   The one way the app draws the eye to a control it has just changed on the
   visitor's behalf. Motion is OPT-IN, the same way .tip's fade is: under
   prefers-reduced-motion the class instead leaves a brief STATIC ring, which
   the JS removes on the same timer, so the affordance is never lost and
   nothing ever moves.

   REDESIGNED 12 Aug, after Christoph reported that the two- and three-cycle
   nudges were invisible while the single-cycle one worked. Two faults, both
   fixed here:

   1. THE PEAK CAME TOO LATE. The old curve was a symmetric 1.5s breathe
      peaking at 50%, i.e. 750ms in. A nudge is restarted from 0% whenever
      the visitor moves to another view, and someone exploring the tabs
      clicks every second or two – so the longer nudges were being reset
      during their fade-IN, over and over, and never reached the bright half
      of the curve at all. The one-cycle nudge looked fine purely because it
      is the LAST in the session and nothing interrupts it.

      The curve is now a radar ping: full brightness by 18% of a 900ms cycle
      (about 160ms), then an expanding fade. An interrupted pulse has already
      flashed before it is cut, and three cycles now cost 2.7s rather than
      4.5s, so there is far less to interrupt.

   2. IT WAS GOLD ON GOLD. #tourBtn's background is --accent, and --pulse is
      the same brand gold at 60-72% – a quiet halo around a control of its
      own colour. The ring is now a denser gold (--pulse-strong, pitched
      DARKER in light mode and LIGHTER in dark mode, so it separates from the
      button in both) over a wide soft --pulse-glow.

   REBUILT AGAIN, same day, after Christoph saw NOTHING AT ALL in his VM's
   Safari. Two independent causes, both addressed:

   3. THE ANIMATION IS NOW SAFARI-PROOF. It used to interpolate box-shadow,
      with var() colours inside the keyframes. Both halves of that are
      fragile in Safari: shadow interpolation is the least-exercised path in
      any engine, and a custom property referenced from within an
      interpolated value can resolve to nothing and render – silently – no
      shadow at all. There is no error and no fallback; the element simply
      stays bare, which is exactly what he described.

      So the ring moved to a ::after pseudo-element that carries its colours
      on a STATIC box-shadow, resolved once, never interpolated. The
      animation now touches ONLY opacity and transform: the two properties
      every engine composites on the GPU and neither of which can fail to
      interpolate. If var() somehow resolved to nothing the ring would be
      colourless but the geometry and timing would still run – it cannot
      silently no-op the way the old shadow animation could.

      The pseudo is position:absolute with pointer-events:none, so it is out
      of flow: it cannot move the chart and cannot swallow a click. The
      cycle count reaches it through the inherited --pulse-cycles custom
      property, because inline styles cannot address a pseudo-element.

   4. THE NO-MOTION PRESENTATION IS A REAL AFFORDANCE NOW, not a consolation
      prize. Parallels macOS commonly ships with Reduce Motion ON, so that
      branch may be the ONLY thing he has ever been shown – and a 3px ring
      is easy to miss. It is now a 5px high-contrast ring with a second
      --pulse-edge outline around it AND a held --pulse-tint wash over the
      control itself. It appears, holds for the whole timer, and clears.
      Nothing moves, nothing flashes, no opacity changes over time – the
      promise prefers-reduced-motion actually makes.

   Applied to a .row, whose flex layout the ring does not disturb, or to a
   button, which keeps its own border-radius (the pseudo inherits it). */
.pulse-attn { border-radius: 8px; position: relative; }
/* BASE = the no-motion presentation. Deliberately the default rather than
   the exception, so a browser that never matches the query below still gets
   a complete, visible affordance. */
.pulse-attn::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  border-radius: inherit; opacity: 1;
  background: var(--pulse-tint);
  box-shadow: 0 0 0 5px var(--pulse-strong), 0 0 0 8px var(--pulse-edge);
}
@media (prefers-reduced-motion: no-preference) {
  .pulse-attn::after {
    background: none;
    box-shadow: 0 0 0 6px var(--pulse-strong), 0 0 16px 12px var(--pulse-glow);
    opacity: 0;
    /* longhands, not the shorthand: a var() iteration count inside the
       animation shorthand is another thin-ice parse in older engines */
    animation-name: pulseAttn;
    animation-duration: 900ms;
    animation-timing-function: ease-out;
    animation-iteration-count: var(--pulse-cycles, 2);
    animation-fill-mode: none;
  }
}
/* opacity and transform ONLY – see note 3 above */
@keyframes pulseAttn {
  0% { opacity: 0; transform: scale(.97); }
  18% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.42); }
}

/* ── guided tour ─────────────────────────────────────────────────────
   The whole overlay is position:fixed, so it never enters the layout the
   charts' high-water reservations measure. The dimming is done with one
   enormous spread shadow on the spotlight box, which needs no canvas and
   leaves the highlighted element fully interactive-looking. */
#tourLayer { position: fixed; inset: 0; z-index: 60; pointer-events: none; }
#tourHole { position: absolute; border-radius: 8px;
  box-shadow: 0 0 0 9999px rgba(2, 12, 22, .58);
  outline: 2.5px solid var(--accent); outline-offset: 0; }
/* deliberately NOT transitioned: the spotlight must be exactly where the
   caption says it is the instant the step changes, and a tab that is not
   rendering frames (backgrounded, or a reduced-motion setting) would leave
   an animated outline stranded between two targets. */
#tourCard { position: absolute; pointer-events: auto; width: 360px;
  max-width: calc(100vw - 24px); background: var(--card); color: var(--ink);
  border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px 12px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, .28); font-size: 14px; }
#tourCard .tour-head { display: flex; align-items: center; gap: 10px; }
#tourCard .tour-step { font: 700 11px/1.3 var(--display); letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink2); }
#tourCard #tourEndX { margin-left: auto; background: transparent; border: 0;
  color: var(--ink2); font-size: 20px; line-height: 1; cursor: pointer;
  padding: 0 2px; }
#tourCard #tourEndX:hover { color: var(--ink); }
#tourCard p { margin: 7px 0 11px; line-height: 1.5; }
#tourCard .tour-btns { display: flex; gap: 8px; }
#tourCard .tour-btns button { font: 600 12px/1 var(--display);
  padding: 8px 13px; border-radius: 999px; border: 1.5px solid var(--line);
  background: var(--chip-bg); color: var(--ink); cursor: pointer; }
#tourCard .tour-btns #tourNext { background: var(--mark-strong);
  border-color: var(--mark-strong); color: #fff; }
:root[data-theme="dark"] #tourCard .tour-btns #tourNext { color: #06121f; }
#tourCard .tour-btns #tourEnd { margin-left: auto; }
#tourCard .tour-btns button:disabled { opacity: .4; cursor: default; }
/* the tour drives the controls itself; block stray clicks underneath */
body.tour-on { overflow-x: hidden; }
#tourBtn { background: var(--accent); border-color: var(--accent);
  color: var(--accent-ink); font-weight: 700; }
@media (max-width: 520px) { #tourCard { width: calc(100vw - 24px); } }

/* ── "Tour & videos" popup + video lightbox ─────────────────────────
   Both position:fixed and outside every measured container, so neither can
   disturb the charts' high-water reservations. */
#tourMenu { position: fixed; z-index: 70; min-width: 250px;
  max-width: calc(100vw - 16px); background: var(--card);
  border: 1px solid var(--line); border-radius: 10px; padding: 5px;
  box-shadow: 0 10px 34px rgba(0, 0, 0, .26); display: grid; gap: 2px; }
#tourMenu button { display: grid; gap: 1px; text-align: left; width: 100%;
  background: transparent; border: 0; border-radius: 7px; cursor: pointer;
  padding: 9px 11px; color: var(--ink); font: inherit; }
#tourMenu button:hover, #tourMenu button:focus-visible {
  background: var(--chip-bg); }
#tourMenu .tm-l { font: 600 13.5px/1.35 var(--display); }
#tourMenu .tm-s { font-size: 12px; color: var(--ink2); }

#videoLayer { position: fixed; inset: 0; z-index: 80; display: flex;
  align-items: center; justify-content: center; padding: 16px;
  background: rgba(2, 12, 22, .74); }
#videoBox { width: min(1000px, 100%); background: var(--card);
  border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
  box-shadow: 0 14px 50px rgba(0, 0, 0, .4); }
.video-head { display: flex; align-items: center; gap: 12px;
  padding: 10px 12px 8px 14px; }
.video-head h3 { margin: 0; font: 700 14.5px/1.3 var(--display);
  color: var(--ink); }
#videoClose { margin-left: auto; background: transparent; border: 0;
  color: var(--ink2); font-size: 24px; line-height: 1; cursor: pointer;
  padding: 0 4px; }
#videoClose:hover { color: var(--ink); }
#videoEl { display: block; width: 100%; max-height: calc(100vh - 130px);
  background: #000; }

/* ── floating player (fine pointers, wide screens) ──────────────────
 * The layer stays fixed and fullscreen but lets clicks through; only the
 * box itself is interactive, so the calculator keeps working behind the
 * video. Drag by the header, resize from the native corner handle,
 * double-click the header to restore the default dock. */
#videoLayer.float { background: transparent; pointer-events: none;
  padding: 0; align-items: flex-start; justify-content: flex-start; }
#videoLayer.float #videoBox { pointer-events: auto; position: fixed;
  resize: both; overflow: hidden; min-width: 360px; min-height: 260px;
  box-shadow: 0 10px 36px rgba(0, 0, 0, .45); }
#videoLayer.float .video-head { cursor: grab; user-select: none;
  touch-action: none; }
#videoLayer.float.dragging .video-head { cursor: grabbing; }
#videoLayer.float #videoEl { width: 100%;
  height: calc(100% - 42px); max-height: none; object-fit: contain; }

/* CAPTION SIZE. Left to the browser these swamped the picture: the default
   cue size is a percentage of the ELEMENT height, and these cues run to
   nearly 200 characters, so the longest wrapped to five or six lines. The
   intro compounds it – its source is square (2044x2066), so inside a
   998x770 element the picture is pillarboxed while the cue box still spans
   the full width.

   Measured against the real cue text (longest 198 characters, 21 cues in
   the intro): at lightbox width 22px puts the worst cue on two lines, 59px,
   7.7% of the element – inside the 15% target, against 26% at the browser
   default. 24px was measured too: it tips that cue onto a third line
   (12.6%), so 22px is the last step that still holds two. Below 700px the element is only ~192px tall for a 16:9 source
   and 198 characters simply need three lines however they are set, so 11px
   was measured WORSE than the default (four lines, 31%) and 10px is the
   true floor: three lines, 21%, the same count the default reaches
   without being oversized. Both sizes carry the usual translucent plate so
   they stay legible over a light chart.

   WHAT IS CONTROLLABLE: ::cue takes only an allow-list – colour, the font
   and background shorthands, text-shadow, opacity, visibility. Chrome and
   Edge honour all of this. Safari honours it too, EXCEPT that a viewer who
   has set their own style in Accessibility > Subtitles & Captioning
   overrides the author, by design – that is an accessibility preference and
   should win. Firefox supports a subset. Positioning is not author-
   controllable here at all; the cues carry no position settings of their
   own (checked: no cue settings and no STYLE blocks in any of the four
   .vtt files), so nothing fights this. */
#videoEl::cue {
  font-size: 22px;
  line-height: 1.35;
  background-color: rgba(0, 0, 0, .72);
  color: #fff;
}
@media (max-width: 700px) {
  /* Cues are now re-chunked to ≤84 characters (two lines of ~42), so the
     phone size takes its step up: 12px holds the worst cue to two lines
     inside the ~343px element (42 chars × ~6.3px ≈ 265px in a ~308px cue
     box). */
  #videoEl::cue { font-size: 12px; }
}
/* the page must not scroll behind the lightbox on a phone */
body.video-on { overflow: hidden; }

/* ══ SLICE 3 ═══════════════════════════════════════════════════════
   The situation-led front layer, the caution notice (the audience fork
   until 2 September 2026), the professionals section and presentation
   mode. Everything here is layout, type and
   visibility: no rule in this block changes a number. */

/* ── the draft tag ───────────────────────────────────────────────────
   Every piece of front-layer copy that is waiting on Christoph's
   rewording carries one. It is a build-time marker and comes out with
   the sign-off, so it is deliberately loud enough to be impossible to
   ship by accident. */
.draft { display: inline-block; margin-left: 7px; vertical-align: 2px;
  background: var(--accent); color: var(--accent-ink); border-radius: 4px;
  font: 700 9.5px/1 var(--display); letter-spacing: .08em;
  text-transform: uppercase; padding: 3px 5px; white-space: nowrap; }

/* ── the front layer ─────────────────────────────────────────────── */
.front { max-width: 1240px; margin: 16px auto 0; padding: 0 22px; }
.front > summary { cursor: pointer; font: 700 14px/1.3 var(--display);
  color: var(--ink); list-style: none; display: inline-flex;
  align-items: center; padding: 8px 14px; border-radius: 999px;
  border: 1.5px solid var(--line); background: var(--card); }
.front > summary::-webkit-details-marker { display: none; }
.front > summary::before { content: "▾"; margin-right: 8px;
  color: var(--ink2); font-size: 11px; }
.front:not([open]) > summary::before { content: "▸"; }
.front > summary:hover { border-color: var(--mark); }
.front-in { margin-top: 12px; }
.front-lede { color: var(--ink2); font-size: 13.5px; max-width: 76ch;
  margin: 0 0 12px; }

/* Three cards since the fees and tax question came out (Christoph,
   23 Aug 2026). Three across where three fit, one per row where they do
   not: an odd count in an auto-fit grid leaves the last card sitting alone
   beside a gap, and three questions of equal standing should not be read as
   two and a straggler. The cap stops three cards stretching into three
   billboards on a very wide screen. */
.front-qs { display: grid; gap: 10px; grid-template-columns: 1fr;
  max-width: 1100px; }
@media (min-width: 920px) {
  .front-qs { grid-template-columns: repeat(3, 1fr); }
}
.front-q { display: block; text-decoration: none; color: var(--ink);
  background: var(--card); border: 1.5px solid var(--line);
  border-left: 4px solid var(--accent); border-radius: 10px;
  padding: 13px 15px; }
.front-q:hover { border-color: var(--mark); border-left-color: var(--mark); }
.fq-q { display: block; font: 700 14.5px/1.35 var(--display);
  color: var(--mark-strong); }
:root[data-theme="dark"] .fq-q { color: var(--ink); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .fq-q { color: var(--ink); }
}
.fq-what { display: block; color: var(--ink2); font-size: 12.5px;
  line-height: 1.5; margin-top: 6px; }
.fq-try { display: block; color: var(--ink2); font-size: 12px;
  line-height: 1.45; margin-top: 6px; font-style: italic; }

/* ── speed two, the wizard ───────────────────────────────────────── */
.front-wiz { margin-top: 14px; background: var(--card);
  border: 1.5px solid var(--line); border-radius: 10px; padding: 12px 15px; }
.front-wiz > summary { cursor: pointer; font: 700 13.5px var(--display);
  color: var(--ink); }
.front-wiz .note { margin: 8px 0 4px; max-width: 76ch; }
.wiz-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 7px 0; border-bottom: 1px solid var(--line); }
.wiz-row label { flex: 1 1 260px; font-size: 13.5px; }
.wiz-row input, .wiz-row select { font-size: 14px; padding: 4px 6px; }
.wiz-row input[type="number"] { width: 10em; }
.wiz-skip { font: 600 11px var(--display); color: var(--ink2);
  text-transform: uppercase; letter-spacing: .06em; }
.wiz-now { margin-top: 12px; }
.wiz-now h3 { font-family: var(--display); font-size: 13px; margin: 0 0 4px; }
.wiz-now ul { margin: 0; padding-left: 18px; color: var(--ink2);
  font-size: 12.5px; line-height: 1.6; }
.wiz-go { margin: 12px 0 2px; }
.front-cta { display: inline-block; text-decoration: none;
  background: var(--mark-strong); color: #fff; border-radius: 999px;
  padding: 9px 16px; font: 700 13px var(--display); }
:root[data-theme="dark"] .front-cta { color: #06121f; }
.front-foot { margin: 12px 0 0; }
.front-skip { font: 600 12px var(--display); color: var(--mark);
  letter-spacing: .04em; }

/* ── the caution notice (the audience fork until 2 September 2026) ──
   One paragraph in Christoph's words and one control reading "Next",
   always present whether the strip above is open or closed. The class
   name is slice 3's and is kept so the mode rules below and the print
   rules still apply; what it holds is the caution notice, not a
   question, and anyone may pass it. Low-key on purpose: no box. */
/* The caution notice, framed and set a size up, with a bold lead, on
 * Christoph's ruling of 2 September 2026 ("too small and needs emphasising
 * in some way, perhaps via a frame or with a bold Important"). */
.front-fork { max-width: 1240px; margin: 14px auto 0; padding: 0 22px;
  font-size: 15.5px; line-height: 1.6; color: var(--ink); }
.front-fork p { max-width: 82ch; margin: 0; padding: 12px 16px;
  border: 1.5px solid var(--mark); border-radius: 10px; background: var(--card); }
.caution-lead { color: var(--mark); margin-right: 4px; }
.caution-next { display: inline-block; margin-left: 10px; vertical-align: 1px;
  border: 1.5px solid var(--line); border-radius: 999px; padding: 4px 12px;
  font: 700 11px var(--display); color: var(--mark);
  text-transform: uppercase; letter-spacing: .06em; text-decoration: none;
  white-space: nowrap; }
.caution-next:hover { border-color: var(--mark); background: var(--chip-bg); }

/* ── the professionals section, at this same address ─────────────── */
.prosec { grid-column: 1 / -1; background: var(--card);
  border: 1px solid var(--line); border-radius: 10px; padding: 20px 24px; }
.pro-back { margin: 0 0 10px; font: 600 12px var(--display); }
.pro-back a { color: var(--mark); text-decoration: none; }
.prosec h2 { font-family: var(--display); font-size: 22px; margin: 0 0 10px; }
.prosec h3 { font-family: var(--display); font-size: 15px;
  margin: 22px 0 8px; }
.pro-lede { max-width: 78ch; margin: 0; }
.pro-nav { display: flex; gap: 10px; flex-wrap: wrap; margin: 16px 0 0; }
.pro-nav a { font: 700 12.5px var(--display); text-decoration: none;
  color: var(--ink); background: var(--chip-bg);
  border: 1.5px solid var(--line); border-radius: 999px; padding: 8px 14px; }
.pro-nav a:hover { border-color: var(--mark); color: var(--mark); }
.pro-plan { margin: 0; padding-left: 22px; max-width: 82ch; }
.pro-plan li { margin: 12px 0; }
.pp-name { display: block; font: 700 14px var(--display);
  color: var(--mark-strong); }
:root[data-theme="dark"] .pp-name { color: var(--ink); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .pp-name { color: var(--ink); }
}
.pp-what { display: block; color: var(--ink2); font-size: 13px;
  line-height: 1.55; margin-top: 3px; }
.pp-when { display: block; font: 600 11.5px var(--display); color: var(--ink2);
  text-transform: uppercase; letter-spacing: .06em; margin-top: 5px; }
.pro-note { color: var(--ink2); font-size: 12px; max-width: 78ch;
  margin: 24px 0 0; }

body.pro-mode .tabs, body.pro-mode .front, body.pro-mode .front-fork,
body.pro-mode .panel, body.pro-mode .stage,
body.pro-mode .present-bar { display: none !important; }
body.pro-mode main { grid-template-columns: minmax(0, 1fr); }
/* the hero's constant height is sized for the tallest CHART headline, so
   the professionals section's two-line one would sit under 150px of empty
   navy */
@media (min-width: 900px) { body.pro-mode .hero-in { min-height: 0; } }

/* ── D11, PRESENTATION MODE ──────────────────────────────────────────
   Bigger type, fewer controls, for showing a client in a meeting. One
   class on <body>: no second set of views, and nothing removed from the
   page that the mode cannot put back.

   The chart grows because the control column moves BELOW it, which hands
   the stage the full page width. Everything inside the SVG scales with
   its box, so the axis labels, the bar numbers and the callouts all step
   up together without a single font size being restated per element. */
.present-bar { max-width: 1240px; margin: 14px auto 0; padding: 10px 18px;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  background: var(--mark-strong); color: #fff; border-radius: 10px; }
.present-bar .pb-lbl { font: 700 13px var(--display);
  text-transform: uppercase; letter-spacing: .1em; }
.present-bar .pb-note { font-size: 12.5px; color: var(--hero-ink2);
  flex: 1 1 260px; }
.present-bar button { font: 700 12px var(--display); cursor: pointer;
  background: transparent; color: #fff; border: 1.5px solid #fff;
  border-radius: 999px; padding: 7px 13px; }
.present-bar button:hover { background: #fff; color: var(--mark-strong); }

body.presenting { font-size: 17px; }
body.presenting main { grid-template-columns: minmax(0, 1fr);
  max-width: 1320px; }
body.presenting .stage { order: 1; }
body.presenting .panel { order: 2; font-size: 16px; }
body.presenting .hero h1 { font-size: clamp(30px, 4.4vw, 46px);
  max-width: 46ch; }
body.presenting .headline { font-size: clamp(18px, 2.4vw, 24px);
  max-width: 76ch; }
body.presenting .cgtline { font-size: clamp(15px, 2vw, 19px); }
body.presenting .stat .big { font-size: 42px; }
body.presenting .stat .lbl { font-size: 15px; }
body.presenting .card h3 { font-size: 20px; }
body.presenting .sub { font-size: 16px; }
body.presenting .legend { font-size: 16px; }
body.presenting .takeaway li { font-size: 17px; line-height: 1.6; }
/* the constant-height hero is sized for the small type; presentation
   type needs the room, so the floor is released here */
@media (min-width: 900px) {
  body.presenting .hero-in { min-height: 0; }
}
/* fewer controls. Hidden, not removed: leaving the mode brings every one
   of them back with its state untouched. */
body.presenting .front, body.presenting .front-fork,
body.presenting details.more, body.presenting #labelcard,
body.presenting details.tbl, body.presenting #rescaleBtn,
body.presenting #investedBtn, body.presenting #arrowsBtn,
body.presenting #nominalInfo, body.presenting #tourBtn,
body.presenting #shareBtn, body.presenting #presentBtn,
body.presenting .panel .note, body.presenting .panel .tipnote,
body.presenting .focus-note { display: none !important; }

/* ── D12, the printable exhibit pack ─────────────────────────────── */
.pack { max-width: 1060px; margin: 22px auto 48px; padding: 0 22px; }
.pack h1 { font-family: var(--display); }
.pack > p { max-width: 80ch; }
.pack-actions { display: flex; gap: 12px; align-items: center;
  flex-wrap: wrap; margin: 16px 0 22px; padding: 12px 0;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.pack-actions button { font: 700 12.5px var(--display); cursor: pointer;
  background: var(--chip-bg); color: var(--ink);
  border: 1.5px solid var(--line); border-radius: 999px; padding: 8px 14px; }
.pack-actions button:hover { border-color: var(--mark); }
.pack-actions label { font-size: 13px; display: inline-flex;
  align-items: center; gap: 7px; }
.exhibit { border-top: 1px solid var(--line); padding: 16px 0 4px;
  break-inside: avoid; }
.exhibit h2 { font-family: var(--display); font-size: 17px; margin: 0; }
.ex-num { color: var(--accent); font-weight: 700; margin-right: 8px; }
.ex-what, .ex-try { color: var(--ink2); font-size: 13px; line-height: 1.55;
  max-width: 82ch; margin: 7px 0 0; }
.ex-try { font-style: italic; }
.ex-open { margin: 10px 0 0; font: 700 12.5px var(--display); }
.ex-open a { color: var(--mark); text-decoration: none; }
.ex-link { display: none; }        /* on paper only: see @media print */
.pack-foot { margin-top: 28px; border-top: 1px solid var(--line);
  padding-top: 14px; color: var(--ink2); font-size: 12.5px; }

@media print {
  /* paper is white: force the light tokens even in dark mode (the app
   * also re-renders charts light around the print snapshot) */
  :root, :root[data-theme="dark"] {
    --bg: #fff; --card: #fff; --ink: #14212e; --ink2: #4e5a66; --axis: #3f4a55;
    --line: #E8DFD0; --hero-bg: #fff; --hero-ink: #14212e;
    --hero-ink2: #4e5a66; --accent: #C1A06B; --accent-ink: #2b2416;
    --mark: #0F4C85; --mark-strong: #00305B; --grid: #e7e2d6;
    --chip-bg: #fff;
    --s1: #6FA3DE; --s2: #A87B2F; --s3: #0E8A6D; --s4: #6B3FA0; --s5: #9C5A2A;
  --median: #001B33; --median-2: #2F5F8F;
    --neg: #B3552E;
  }
  .ribbon, .tabs, .panel, #themeToggle, #navToggle, .cardactions,
  .rescale-row, details.tbl, #tourLayer, #tourMenu, #videoLayer,
  .nav .links a,
  /* slice 3: the front layer, the caution notice and the mode bar are
     ways of getting somewhere. On paper you are already there. */
  .front, .front-fork, .present-bar, .pack-actions,
  .pro-back { display: none !important; }
  main { display: block; }
  .card { border: none; box-shadow: none; padding: 0; }
  body { background: #fff; }
  /* D12: each exhibit prints its own address beside it, so a printed
     pack can be typed back in. The <a> stays a link on screen and the
     full address appears only on paper, written by exhibits.html from
     the origin the page was served from, so it cannot go stale. */
  .exhibit { break-inside: avoid; page-break-inside: avoid; }
  .ex-link { display: block; font-size: 11px; line-height: 1.5;
    word-break: break-all; color: #4e5a66; margin: 6px 0 0; }
  .ex-open { display: none !important; }
  .pack { max-width: none; padding: 0; }
}

footer.site { border-top: 1px solid var(--line); margin-top: 8px;
  color: var(--ink2); font-size: 12.5px; line-height: 1.6; }
.foot-in { max-width: 1160px; margin: 0 auto; padding: 18px 22px 26px; }
.foot-in p { margin: 6px 0; max-width: 92ch; }
.foot-in a { color: var(--mark); }
/* Index footer: (a) and (b) side by side, AFSL line spans full width below.
   Single column (current order) under 900px. Column width bounds the lines,
   so the 92ch cap is dropped here to avoid fighting the two-column layout. */
@media (min-width: 900px) {
  .foot-cols { display: grid; grid-template-columns: 1fr 1fr;
    column-gap: 34px; }
  .foot-cols p { max-width: none; }
  .foot-cols .afsl { grid-column: 1 / -1; margin-top: 12px;
    padding-top: 12px; border-top: 1px solid var(--line); }
}

/* ── the footer word "Caution" (2 September 2026, purpose amendment) ──
   One word in the footer of every page. Click or tap opens Christoph's
   context sentence in a small panel above the word; hover does the same
   through site/caution.mjs, and without that script the word still
   opens on click, because it is a <details>. His ruling is that the less
   clutter in an interface the better, so the word sits in the footer's
   own muted type and the panel is the only thing that appears. */
details.caution { position: relative; display: inline-block; margin: 8px 0 0; }
details.caution > summary { cursor: pointer; list-style: none;
  display: inline-block; font: 600 12px var(--display); color: var(--ink2);
  letter-spacing: .04em; text-transform: uppercase;
  border-bottom: 1px dotted var(--ink2); }
details.caution > summary::-webkit-details-marker { display: none; }
details.caution > summary:hover,
details.caution[open] > summary { color: var(--mark);
  border-bottom-color: var(--mark); }
details.caution > p { position: absolute; left: 0; bottom: 100%;
  z-index: 30; width: min(54ch, calc(100vw - 44px)); margin: 0;
  padding: 10px 14px; background: var(--card); color: var(--ink);
  border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 6px 22px rgba(0, 0, 0, .14); font-size: 13px;
  line-height: 1.55; }
/* The panel abuts the word rather than floating 8px above it: any gap
 * between the two is outside the <details> box, so a pointer crossing it
 * fires mouseleave and closes what hover had just opened (review finding,
 * 2 September 2026). The separation is drawn as a transparent border on
 * the panel instead, which stays inside the box the hover script watches. */
details.caution > p { border-bottom: 8px solid transparent; background-clip: padding-box; }
@media (min-width: 900px) { .foot-cols details.caution { grid-column: 1 / -1; } }
@media print { details.caution { display: none !important; } }

/* ── tab 6, the costs-and-tax step-down (slice 7, C1) ─────────────── */
.coststep { display: grid; grid-template-columns: minmax(150px, 1.3fr) 3fr auto auto auto;
  gap: 10px; align-items: center; padding: 6px 0; border-bottom: 1px dashed var(--line);
  font-size: 13px; }
.coststep:last-child { border-bottom: none; }
.cs-label { color: var(--ink); }
.cs-bar { height: 14px; background: var(--chip-bg); border-radius: 7px; overflow: hidden; }
.cs-fill { height: 100%; background: var(--s2); border-radius: 7px; }
.cs-val { font-family: var(--display); font-weight: 700; white-space: nowrap; }
.cs-took, .cs-alone { color: var(--ink2); white-space: nowrap; font-size: 12px; }
@media (max-width: 640px) { .coststep { grid-template-columns: 1fr 2fr auto; }
  .cs-took, .cs-alone { display: none; } }

/* ── tab 8, the life-events builder (slice 7c) ─────────────────────── */
.row.sub { padding-left: 18px; }
.row.sub label { color: var(--ink2); font-size: 12.5px; }
