/* =========================================================
   SLIDE TYPES — layouts per data-type
   ========================================================= */

/* --- TITLE ---------------------------------------------- */
.slide[data-type="title"] {
  display: none;
  background:
    radial-gradient(ellipse 60% 50% at 85% 15%, var(--c-amber-soft) 0%, transparent 60%),
    radial-gradient(ellipse 60% 60% at 5% 85%, var(--accent-soft) 0%, transparent 55%),
    var(--bg);
}
.slide[data-type="title"].is-active {
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: var(--sp-5);
  padding: 96px 140px;
}
.slide[data-type="title"] .title-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: var(--fs-tiny);
  color: var(--ink-2);
  letter-spacing: 0.06em;
}
.slide[data-type="title"] .title-header .course-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  text-transform: uppercase;
  font-weight: 600;
  white-space: nowrap;
  flex: 0 0 auto;
}
.slide[data-type="title"] .title-header .course-tag::before {
  content: "";
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--accent);
}
.slide[data-type="title"] .title-body {
  align-self: center;
  max-width: 1500px;
}
.slide[data-type="title"] .eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--accent);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: var(--sp-4);
}
.slide[data-type="title"] h1 {
  font-family: var(--font-serif);
  font-size: var(--fs-display);
  font-weight: 500;
  line-height: 0.98;
  letter-spacing: -0.02em;
  margin: 0 0 var(--sp-5);
}
.slide[data-type="title"] .subtitle {
  font-size: var(--fs-lead);
  font-family: var(--font-sans);
  color: var(--ink-2);
  line-height: 1.3;
  max-width: 1400px;
}
.slide[data-type="title"] .title-footer {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-6);
  align-items: end;
  padding-top: var(--sp-4);
  border-top: var(--hairline) solid var(--rule-strong);
}
.slide[data-type="title"] .title-footer .meta-label {
  font-size: var(--fs-tiny);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-3);
  margin-bottom: var(--sp-1);
}
.slide[data-type="title"] .title-footer .meta-value {
  font-family: var(--font-serif);
  font-size: var(--fs-lead);
  color: var(--ink);
}

/* --- AGENDA / TOC --------------------------------------- */
.slide[data-type="agenda"] .agenda-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-5) var(--sp-7);
  margin-top: var(--sp-5);
}
.toc-item {
  display: grid;
  grid-template-columns: 88px 1fr;
  gap: var(--sp-4);
  align-items: start;
  padding: var(--sp-3) 0;
  border-bottom: var(--hairline) solid var(--rule);
  cursor: pointer;
  transition: opacity var(--dur) var(--ease);
  text-decoration: none;
  color: inherit;
}
.toc-item, .toc-item * { text-decoration: none; }
.toc-item:hover { opacity: 0.7; }
.toc-item .toc-num {
  font-family: var(--font-mono);
  font-size: var(--fs-label-xl);
  font-weight: 500;
  color: var(--accent);
  padding-top: 4px;
}
.toc-item .toc-text { display: block; }
.toc-item .toc-title {
  display: block; /* was inline span → margin-bottom ignored, title glued to sub */
  font-family: var(--font-serif);
  font-size: var(--fs-lead);
  line-height: 1.1;
  margin-bottom: var(--sp-1);
  color: var(--ink);
}
.toc-item .toc-sub {
  display: block;
  font-family: var(--font-sans);
  font-size: var(--fs-caption);
  color: var(--ink-3);
}

/* --- HEADER KICKER GUARD -------------------------------- */
/* An overlong kicker must never starve the title. components.css gives
   .slide-kicker white-space:nowrap + flex:0 0 auto while the h2 is
   flex:1 1 auto / min-width:0 — so a sentence-length kicker (several decks
   author full subtitles there, up to ~1900px of text) claims the whole
   header row and the h2 collapses to word-per-line (headers 500–750px tall).
   That inflated header then cascades: global auto-fit fires, fitContainer
   sees no room below the header, and pre-flight reports spurious density /
   fit-clip warnings. Cap the kicker at 40% of the row and let it wrap;
   short kickers stay on one line and prose headers only get SHORTER
   (the h2 regains width → fewer 72px lines).
   `viz` slides are EXCLUDED: their aspect-ratio stages make the global
   auto-fit equilibrium path-dependent (verified on L5 "45 UMAP": any header
   perturbation — even a shorter one — re-lands the fit from 0.543× at
   exactly-1080px to 0.692× with a 34px spill), so they keep the legacy
   nowrap geometry byte-identically.
   (.slide prefix out-specifies components.css, which loads after this file.) */
.slide:not([data-type="viz"]) .slide-header .slide-kicker {
  white-space: normal;
  flex: 0 1 auto;
  max-width: 40%;
}

/* --- LEARNING OBJECTIVES -------------------------------- */
/* Distinct from `agenda` (logistics/timing): measurable outcomes,
   non-clickable, checkmark bullets. */
/* GLOBAL obj-list base — applies on ANY slide type (two-col, etc.), not just
   objectives. Without this the native <li> disc shows IN ADDITION to the
   ·/✓ marker span → duplicate bullets. Objectives slides override below. */
.obj-list { list-style: none; margin: var(--sp-3) 0 0; padding: 0; display: grid; gap: var(--sp-3); }
.obj-item { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-2); align-items: baseline; }
.obj-check { color: var(--accent); font-weight: 700; }
.obj-text { line-height: 1.4; }

.slide[data-type="objectives"] .obj-list {
  list-style: none;
  margin: var(--sp-5) 0 0;
  padding: 0;
  display: grid;
  gap: var(--sp-4);
}
.slide[data-type="objectives"] .obj-item {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: var(--sp-4);
  align-items: start;
  padding-bottom: var(--sp-4);
  border-bottom: var(--hairline) solid var(--rule);
}
.slide[data-type="objectives"] .obj-item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}
.slide[data-type="objectives"] .obj-check {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--c-green-soft);
  color: var(--c-green-ink);
  font-size: 32px;
  font-weight: 600;
  font-family: var(--font-sans);
}
.slide[data-type="objectives"] .obj-text {
  font-family: var(--font-serif);
  font-size: var(--fs-body);
  line-height: 1.2;
  color: var(--ink);
  align-self: center;
}

/* --- SECTION DIVIDER ------------------------------------ */
.slide[data-type="divider"] {
  display: none;
}
.slide[data-type="divider"].is-active {
  display: grid;
  place-items: center;
  background: var(--ink);
  color: var(--bg);
  padding: var(--slide-pad-top) var(--slide-pad-x);
}
.slide[data-type="divider"] .divider-num {
  font-family: var(--font-mono);
  font-size: var(--fs-label-xl);
  color: var(--c-amber);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  margin-bottom: var(--sp-4);
}
/* Dark-theme override: the divider's canvas flips to cream (`var(--ink)` =
   #ECE7D8), and the light-theme bright amber `#F4C975` against cream is a
   1.26:1 ghost — fails WCAG AA. Pin to a deep amber (~4.7:1 on cream) so
   the "Part 01" kicker reads in both themes. Caught by the contrast
   detector added to visual-gate.mjs after Session 2. */
:root[data-theme="dark"] .slide[data-type="divider"] .divider-num {
  color: #8a5d18;
}
.slide[data-type="divider"] h1 {
  font-family: var(--font-serif);
  font-size: 168px;
  font-weight: 500;
  line-height: 0.95;
  letter-spacing: -0.02em;
  color: var(--bg);
  max-width: 1500px;
  text-align: center;
}
.slide[data-type="divider"] .divider-sub {
  font-size: var(--fs-lead);
  /* Colour/opacity now lives in wbw-art.css (per-theme tokens) — keep layout
     (font-size, margin, max-width) here so wbw-art only carries the design
     decision, not the chrome. */
  margin-top: var(--sp-5);
  max-width: 1100px;
  text-align: center;
}

/* --- DEFINITION ----------------------------------------- */
.slide[data-type="definition"] .def-card {
  margin-top: var(--sp-4);
  background: var(--bg-card);
  border: var(--line) solid var(--ink);
  border-radius: var(--r-lg);
  padding: var(--sp-6) var(--sp-7);
  box-shadow: 12px 12px 0 var(--accent-soft);
  position: relative;
}
.slide[data-type="definition"] .def-tag {
  position: absolute;
  top: -22px; left: 64px;
  background: var(--ink);
  color: var(--bg);
  font-family: var(--font-mono);
  font-size: var(--fs-tiny);
  text-transform: uppercase;
  letter-spacing: 0.15em;
  padding: 8px 20px;
  border-radius: var(--r-pill);
}
.slide[data-type="definition"] .def-term {
  font-family: var(--font-serif);
  font-size: 88px;
  font-style: italic;
  line-height: 1;
  margin: 0 0 var(--sp-4);
  color: var(--ink);
}
.slide[data-type="definition"] .def-term .term-en {
  display: block;
  font-style: normal;
  font-family: var(--font-mono);
  font-size: var(--fs-label-xl);
  font-style: normal;
  color: var(--ink-3);
  margin-top: var(--sp-2);
  letter-spacing: 0.02em;
}
.slide[data-type="definition"] .def-body {
  font-size: var(--fs-body);
  line-height: 1.4;
  color: var(--ink);
}
.slide[data-type="definition"] .def-body p { margin-bottom: var(--sp-3); }
.slide[data-type="definition"] .def-body p:last-child { margin-bottom: 0; }

/* Short, claim-adjacent provenance shared by tables and worked cases. */
.slide-source {
  margin: var(--sp-3) 0 0;
  font: 600 var(--fs-label-sm)/1.3 var(--font-sans);
  color: var(--ink-2);
}
.slide-source a { color: var(--accent-ink); text-decoration: underline; }

/* --- THEOREM / LEMMA / PROOF ---------------------------- */
.thm-card {
  margin-top: var(--sp-4);
  border-left: 8px solid var(--accent);
  padding: var(--sp-4) var(--sp-6);
  background: var(--accent-soft);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  margin-bottom: var(--sp-4);
}
.thm-card[data-kind="lemma"]   { border-color: var(--c-violet); background: var(--c-violet-soft); }
.thm-card[data-kind="cor"]     { border-color: var(--c-green); background: var(--c-green-soft); }
.thm-card[data-kind="proof"]   { border-color: var(--ink-3); background: var(--bg-alt); }
.thm-card .thm-label {
  font-family: var(--font-mono);
  font-size: var(--fs-caption-lg);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent-ink);
  margin-bottom: var(--sp-2);
  font-weight: 600;
}
.thm-card[data-kind="lemma"] .thm-label { color: var(--c-violet); }
.thm-card[data-kind="cor"] .thm-label { color: var(--c-green); }
.thm-card[data-kind="proof"] .thm-label { color: var(--ink-3); }
.thm-card .thm-statement {
  font-family: var(--font-serif);
  font-size: var(--fs-lead);
  font-style: italic;
  line-height: 1.3;
  color: var(--ink);
}
.thm-card .thm-statement strong { font-style: normal; }
.thm-card[data-kind="proof"] .thm-statement {
  font-style: normal; font-family: var(--font-sans);
  font-size: var(--fs-body);
}
.thm-card[data-kind="proof"] .thm-statement::after {
  content: "∎";
  display: inline-block;
  margin-left: 0.4em;
  font-family: var(--font-serif);
  font-style: normal;
}

/* --- BIG FORMULA ---------------------------------------- */
.slide[data-type="formula"] {
  display: none;
}
/* The formula slide is now wrapped in a `.slide-body` (deck.js wrapSlideBody),
   so the three-row grid lives on the BODY (not the slide) — this lets the global
   auto-fit scale the whole formula content as one block when it would overflow
   1080 (the b-dial: header + 280% math + caption + footnote). The slide keeps the
   base `display:block` from `.slide.is-active`; the body fills it (`height:100%`)
   so the `1fr` math row still absorbs slack and centres the equation. */
.slide[data-type="formula"].is-active { display: block; }
.slide[data-type="formula"].is-active > .slide-body {
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: var(--sp-5);
  height: 100%;
}
.slide[data-type="formula"] .formula-stage {
  display: grid;
  place-items: center;
  text-align: center;
}
.slide[data-type="formula"] .formula-stage mjx-container,
.slide[data-type="formula"] .formula-stage .katex {
  font-size: 280% !important;
}
/* Warm "formula card" — echoes the Book's display-math card so the hero formula reads
   as a lifted object, not loose text. Theme-aware via deck-native --c-amber-soft (cream
   in light, deep-amber in dark); warm left-rule. KaTeX keeps --ink, so contrast holds in
   both themes (dark-on-cream / light-on-deep-amber). The formula-stage is place-items:center,
   so the card hugs the formula and stays centred; autofit absorbs any width growth. */
.slide[data-type="formula"] .formula-stage mjx-container,
.slide[data-type="formula"] .formula-stage .katex {
  padding: var(--sp-4) var(--sp-7);
  background: var(--c-amber-soft);
  border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
  border-left: 6px solid var(--warm, #E8743B);
  border-radius: var(--r-md);
}
.slide[data-type="formula"] .formula-caption {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--sp-6);
  padding: var(--sp-4);
  background: var(--bg-alt);
  border-radius: var(--r-md);
}
/* Reusable single-prose caption variant for a worked equation's assumptions/omissions. */
.slide[data-type="formula"] .formula-caption:not(:has(.var-block)) {
  display: block;
  font-size: var(--fs-small);
  line-height: 1.35;
  color: var(--ink-2);
}
.slide[data-type="formula"] .formula-caption .var-block {
  text-align: center;
}
.slide[data-type="formula"] .formula-caption .var-symbol {
  display: block;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 64px;
  color: var(--accent);
  line-height: 1;
  margin-bottom: var(--sp-2);
}
.slide[data-type="formula"] .formula-caption .var-desc {
  display: block;
  font-size: var(--fs-small);
  color: var(--ink-2);
  line-height: 1.3;
}

/* Worked formula: equation -> units/meaning -> calculation -> limits.
   Use native math/body tokens and bounded content, never auto-shrink this pattern. */
.slide[data-type="formula"].formula-worked > .slide-body {
  display: grid;
  grid-template-rows: auto auto auto auto auto;
  align-content: start;
  gap: var(--sp-3);
  height: 100%;
}
.formula-worked .formula-stage { min-height: 120px; }
.slide.formula-worked .formula-stage .katex,
.slide.formula-worked .formula-stage mjx-container {
  font-size: var(--fs-math) !important;
  padding: var(--sp-2) var(--sp-4);
}
.slide.formula-worked .formula-caption { gap: var(--sp-4); padding: var(--sp-3); }
.slide.formula-worked .formula-caption .var-block { text-align: left; }
.slide.formula-worked .formula-caption .var-symbol { font-size: var(--fs-h3); }
.formula-worked .var-unit {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--accent-ink);
  margin-bottom: var(--sp-1);
}
.formula-example {
  font-size: var(--fs-body);
  line-height: 1.25;
  border-left: 6px solid var(--c-green);
  padding-left: var(--sp-3);
}
.formula-example strong { color: var(--accent-ink); }
.formula-limit { font-size: var(--fs-small); line-height: 1.3; color: var(--ink-2); }
.formula-limit a { color: var(--accent-ink); }
@media print {
  .slide[data-type="formula"].formula-worked > .slide-body { display: grid !important; }
  .formula-worked .formula-caption { break-inside: avoid; }
}

/* --- CODE ----------------------------------------------- */
.code-block {
  background: var(--bg-inset);
  border: var(--hairline) solid var(--rule);
  border-radius: var(--r-md);
  font-family: var(--font-mono);
  font-size: var(--fs-code-sm);
  line-height: 1.4;
  overflow: hidden;
  position: relative;
  margin: var(--sp-3) 0;
}
:root[data-theme="dark"] .code-block { background: #0B0E14; }
.code-block .code-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-2) var(--sp-4);
  background: var(--bg-alt);
  border-bottom: var(--hairline) solid var(--rule);
  font-family: var(--font-sans);
  font-size: var(--fs-tiny);
  color: var(--ink-3);
}
:root[data-theme="dark"] .code-block .code-header { background: #161A22; }
.code-block .code-lang {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.code-block .code-lang::before {
  content: "";
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--c-green);
}
.code-block pre {
  margin: 0;
  padding: var(--sp-3) var(--sp-5);
  overflow-x: auto;
  font-size: inherit;
}
.code-block.is-wrap pre,
.code-block.is-wrap code { white-space: pre-wrap; overflow-wrap: anywhere; }
.code-block code { background: transparent; border: none; padding: 0; font-size: inherit; }
.code-block.is-dense pre { font-size: var(--fs-code-sm); }

/* Prism token colors — Distill-friendly */
.code-block .token.comment,
.code-block .token.prolog,
.code-block .token.doctype,
.code-block .token.cdata { color: var(--ink-4); font-style: italic; }
.code-block .token.punctuation { color: var(--ink-2); }
.code-block .token.property,
.code-block .token.tag,
.code-block .token.constant,
.code-block .token.symbol,
.code-block .token.deleted { color: var(--c-red); }
.code-block .token.boolean,
.code-block .token.number { color: var(--c-violet); }
.code-block .token.selector,
.code-block .token.attr-name,
.code-block .token.string,
.code-block .token.char,
.code-block .token.builtin,
.code-block .token.inserted { color: var(--c-green); }
.code-block .token.operator,
.code-block .token.entity,
.code-block .token.url,
.code-block .token.variable { color: var(--c-cyan); }
.code-block .token.atrule,
.code-block .token.attr-value,
.code-block .token.function,
.code-block .token.class-name { color: var(--accent); }
.code-block .token.keyword { color: var(--c-pink); font-weight: 600; }
.code-block .token.regex,
.code-block .token.important { color: var(--c-amber); }

/* --- TWO-COLUMN ----------------------------------------- */
.slide[data-type="two-col"] .twocol {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-7);
  margin-top: var(--sp-4);
  align-items: start;
}
.slide[data-type="two-col"] .twocol > * { min-width: 0; }
.slide[data-type="two-col"] .twocol-col h3 {
  font-size: var(--fs-h3);
  margin-bottom: var(--sp-3);
  color: var(--accent-ink);
}
:root[data-theme="dark"] .slide[data-type="two-col"] .twocol-col h3 { color: var(--accent); }

/* --- CHART / VIZ PLACEHOLDER ---------------------------- */
.viz-frame {
  margin-top: var(--sp-4);
  height: 720px;
  border: var(--hairline) solid var(--rule);
  border-radius: var(--r-md);
  position: relative;
  overflow: hidden;
  display: grid;
  place-items: center;
  /* UNIVERSAL CONTRAST RULE: hand-authored inline-SVG diagrams are designed
     against the LIGHT palette. Pin the canvas + colour tokens to their light
     values in BOTH themes so every diagram renders with correct, high contrast
     regardless of the global light/dark setting (a light chart card on a dark
     deck reads cleanly and avoids dark-on-dark / invisible shapes). */
  --bg: #FBFAF6; --bg-alt: #F2EFE6; --bg-card: #FFFFFF; --bg-inset: #EBE7DA;
  --ink: #14181F; --ink-2: #3D434E; --ink-3: #6B7280; --ink-4: #9CA3AF;
  --rule: #DDD7C7; --rule-strong: #B8B19E;
  --accent: #2A6FDB; --accent-ink: #1B4FA0; --accent-soft: #DCE8F8;
  --c-red: #D7522C; --c-red-soft: #FBE3D8;
  --c-green: #3A8A5C; --c-green-soft: #DDEDDF;
  --c-amber: #E0A82E; --c-amber-soft: #F8ECCB;
  --c-violet: #7D5BA6; --c-violet-soft: #E7DEF1;
  --c-cyan: #1AA7B5; --c-cyan-soft: #D2EDEF;
  --c-pink: #C9447A; --c-pink-soft: #F6DCE5;
  background: #FFFFFF;
  color: var(--ink);
}
.viz-frame .viz-placeholder {
  text-align: center;
  color: var(--ink-3);
  font-family: var(--font-mono);
  font-size: var(--fs-caption-lg);
}
.viz-frame .viz-placeholder::before {
  content: "↑";
  display: block;
  font-size: 64px;
  margin-bottom: var(--sp-2);
  color: var(--accent);
}
.viz-caption {
  font-size: var(--fs-small);
  color: var(--ink-3);
  text-align: center;
  margin-top: var(--sp-2);
  font-style: italic;
}

/* --- INTERACTIVE DEMO ----------------------------------- */
.demo-frame {
  margin-top: var(--sp-4);
  display: grid;
  grid-template-columns: 1fr 460px;
  gap: var(--sp-5);
}
.demo-frame .demo-canvas {
  background: var(--bg-card);
  border: var(--hairline) solid var(--rule);
  border-radius: var(--r-md);
  height: 720px;
  position: relative;
  overflow: hidden;
  padding: var(--sp-3);
}
.demo-frame .demo-controls {
  background: var(--bg-alt);
  border-radius: var(--r-md);
  padding: var(--sp-4);
  display: flex; flex-direction: column;
  gap: var(--sp-4);
}
.demo-frame .demo-controls h3 {
  font-size: var(--fs-label-xl);
  font-family: var(--font-serif);
  margin: 0 0 var(--sp-1);
}
.demo-knob { display: block; }
.demo-knob .knob-label {
  display: flex; justify-content: space-between;
  align-items: baseline;
  font-family: var(--font-sans);
  font-size: var(--fs-caption-lg);
  margin-bottom: 8px;
}
.demo-knob .knob-label .knob-name { color: var(--ink-2); }
.demo-knob .knob-label .knob-value {
  font-family: var(--font-mono);
  color: var(--accent);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.demo-knob input[type="range"] {
  width: 100%;
  -webkit-appearance: none;
  appearance: none;
  height: 10px;
  background: var(--bg-card);
  border: var(--hairline) solid var(--rule);
  border-radius: var(--r-pill);
  cursor: pointer;
}
.demo-knob input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--accent);
  border: 4px solid var(--bg);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}
.demo-knob input[type="range"]::-moz-range-thumb {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--accent);
  border: 4px solid var(--bg);
  cursor: pointer;
}

/* Declarative <interactive-demo> bits */
interactive-demo {
  display: block;
}
.demo-readouts {
  border-top: var(--hairline) solid var(--rule);
  padding-top: var(--sp-3);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
  margin-top: auto;
}
.demo-readout .readout-label {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.demo-readout .readout-value {
  font-family: var(--font-mono);
  font-size: var(--fs-label-xl);
  font-weight: 600;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.demo-readout:nth-child(2) .readout-value { color: var(--c-green); }
.demo-error {
  padding: var(--sp-4);
  background: var(--c-red-soft);
  color: var(--c-red);
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  border-radius: var(--r-md);
}

/* --- QUIZ / QUESTION ------------------------------------ */
.quiz-frame { margin-top: var(--sp-3); }
.quiz-q {
  font-family: var(--font-serif);
  font-size: var(--fs-h3);
  font-style: italic;
  line-height: 1.2;
  color: var(--ink);
  margin-bottom: var(--sp-4);
}
/* 2×2 grid (was 4 stacked rows) — halves the vertical footprint so the
   revealed explanation fits within the slide. Equal-height rows keep the
   long/short options aligned. */
.quiz-options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  gap: var(--sp-3);
  font-size: var(--fs-body);
}
.quiz-option {
  display: grid;
  grid-template-columns: 72px 1fr auto;
  gap: var(--sp-3);
  align-items: center;
  background: var(--bg-card);
  border: var(--line) solid var(--rule);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4);
  cursor: pointer;
  transition: all var(--dur) var(--ease);
  font-family: var(--font-sans);
}
.quiz-option:hover { border-color: var(--rule-strong); transform: translateX(4px); }
.quiz-option .quiz-letter {
  width: 56px; height: 56px;
  border-radius: 50%;
  background: var(--bg-alt);
  display: grid; place-items: center;
  font-family: var(--font-mono);
  font-size: 32px;
  font-weight: 600;
  color: var(--ink-2);
}
.quiz-option[data-correct="true"].is-revealed {
  border-color: var(--c-green);
  background: var(--c-green-soft);
}
.quiz-option[data-correct="true"].is-revealed .quiz-letter {
  background: var(--c-green); color: white;
}
.quiz-option[data-correct="false"].is-revealed {
  opacity: 0.5;
}

/* --- Multi-attempt quiz feedback ---
   Wrong pick → red + struck through, stays clickable for OTHER options;
   correct pick → green + locks the group. Correct is NOT revealed by a
   wrong pick (students keep trying). */
.quiz-option.is-correct {
  border-color: var(--c-green);
  background: var(--c-green-soft);
}
.quiz-option.is-correct .quiz-letter { background: var(--c-green); color: #fff; }
.quiz-option.is-wrong {
  border-color: var(--c-red);
  background: var(--c-red-soft);
  opacity: 0.6;
  cursor: not-allowed;
}
.quiz-option.is-wrong .quiz-letter { background: var(--c-red); color: #fff; }
.quiz-option.is-wrong:hover,
.quiz-options.is-solved .quiz-option:hover { transform: none; }
/* ✓ / ✗ marker in the trailing (auto) cell */
.quiz-option.is-correct > :last-child::after { content: "✓"; color: var(--c-green); font-weight: 700; font-size: 1.4em; }
.quiz-option.is-wrong   > :last-child::after { content: "✗"; color: var(--c-red);   font-weight: 700; font-size: 1.4em; }
/* once solved, the rest go neutral & non-interactive */
.quiz-options.is-solved .quiz-option { cursor: default; }
.quiz-options.is-solved .quiz-option:not(.is-correct):not(.is-wrong) { opacity: 0.5; }

/* --- ARCHITECTURE DIAGRAM ------------------------------- */
.arch-diagram {
  /* Size to the row's CONTENT and centre as a block. When the row is wider
     than the slide, it overflows to the RIGHT only, so the deck's auto-fit
     measures the true width (body.scrollWidth) and scales the whole slide to
     fit — no symmetric centre-overflow that clips both ends, no squished
     boxes. Narrow rows stay centred via margin-inline:auto. */
  width: max-content;
  margin: var(--sp-4) auto 0;
  height: 660px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);
  padding: var(--sp-4);
  background: var(--bg-card);
  border-radius: var(--r-md);
  border: var(--hairline) solid var(--rule);
}
.arch-node {
  /* Size each node to its CONTENT (no shrink): text never overflows the box.
     When many nodes make the row wider than the slide, the deck's auto-fit
     (scaleW in deck.js) shrinks the whole row to fit — proportions preserved,
     no squished boxes, no clipped words. Few nodes stay centred. */
  flex: 0 0 auto;
  min-width: 150px;
  max-width: 300px;
  box-sizing: border-box;
  background: var(--bg);
  border: var(--line) solid var(--ink);
  border-radius: var(--r-md);
  padding: var(--sp-4) var(--sp-3);
  text-align: center;
  font-family: var(--font-sans);
  position: relative;
  box-shadow: 4px 4px 0 var(--bg-alt);
}
.arch-node .arch-icon {
  font-family: var(--font-mono);
  font-size: 46px;
  color: var(--accent);
  margin-bottom: var(--sp-2);
  line-height: 1.05;
}
.arch-node .arch-name {
  font-family: var(--font-serif);
  font-size: var(--fs-caption-lg);
  line-height: 1.15;
  margin-bottom: 4px;
  overflow-wrap: break-word;
  hyphens: auto;
}
.arch-node .arch-shape {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  color: var(--ink-3);
  overflow-wrap: break-word;
}
.arch-node[data-color="red"]    { border-color: var(--c-red);    box-shadow: 4px 4px 0 var(--c-red-soft); }
.arch-node[data-color="red"] .arch-icon { color: var(--c-red); }
.arch-node[data-color="green"]  { border-color: var(--c-green);  box-shadow: 4px 4px 0 var(--c-green-soft); }
.arch-node[data-color="green"] .arch-icon { color: var(--c-green); }
.arch-node[data-color="amber"]  { border-color: var(--c-amber);  box-shadow: 4px 4px 0 var(--c-amber-soft); }
.arch-node[data-color="amber"] .arch-icon { color: var(--c-amber); }
.arch-node[data-color="violet"] { border-color: var(--c-violet); box-shadow: 4px 4px 0 var(--c-violet-soft); }
.arch-node[data-color="violet"] .arch-icon { color: var(--c-violet); }
/* `current` — orange accent ring for the currently-active node on a course-arc
   reused at the start of each lecture; default chips stay monochrome ink so
   the eye reads "where am I now?" not "what colour is this stage?" */
.arch-node[data-color="current"] {
  border-color: var(--c-red);
  box-shadow: 0 0 0 4px var(--c-red-soft), 4px 4px 0 var(--c-red-soft);
}
.arch-node[data-color="current"] .arch-icon { color: var(--c-red); }

.arch-arrow {
  flex: 0 0 60px;
  height: 4px;
  background: var(--ink-3);
  position: relative;
  align-self: center;
}
.arch-arrow::after {
  content: "";
  position: absolute;
  right: -2px; top: 50%;
  transform: translateY(-50%);
  border: 12px solid transparent;
  border-left-color: var(--ink-3);
}

/* --- QUOTE / KEY MESSAGE -------------------------------- */
.slide[data-type="quote"] {
  display: none;
}
.slide[data-type="quote"].is-active {
  display: grid;
  place-items: center;
  background: var(--bg-alt);
  padding: var(--slide-pad-top) calc(var(--slide-pad-x) + 80px);
}
.slide[data-type="quote"] .quote-mark {
  font-family: var(--font-serif);
  font-size: 320px;
  line-height: 0.6;
  color: var(--accent);
  text-align: center;
  margin-bottom: var(--sp-4);
}
.slide[data-type="quote"] blockquote {
  margin: 0;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--fs-quote);
  line-height: 1.2;
  text-align: center;
  color: var(--ink);
  max-width: 1500px;
}
.slide[data-type="quote"] .quote-attr {
  margin-top: var(--sp-6);
  text-align: center;
  font-family: var(--font-sans);
  font-size: var(--fs-small);
  letter-spacing: 0.06em;
  color: var(--ink-3);
  text-transform: uppercase;
}
.slide[data-type="quote"] .quote-attr::before {
  content: "— ";
}

/* --- REFERENCES ----------------------------------------- */
.ref-list {
  margin-top: var(--sp-4);
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--sp-3);
  font-size: 32px;
  counter-reset: ref;
}
.ref-list li {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  gap: var(--sp-3);
  padding: var(--sp-3) 0;
  border-bottom: var(--hairline) solid var(--rule);
  line-height: 1.35;
  align-items: baseline;
  counter-increment: ref;
}
.ref-list li::before {
  content: "[" counter(ref) "]";
  font-family: var(--font-mono);
  color: var(--accent);
  font-size: var(--fs-caption);
  font-weight: 600;
  grid-column: 1;
}
.ref-list .ref-body { grid-column: 2; }
.ref-list .ref-year { grid-column: 3; }
.ref-list .ref-authors { color: var(--ink); font-weight: 500; }
.ref-list .ref-title { color: var(--ink); font-style: italic; }
.ref-list .ref-venue { color: var(--ink-3); font-size: var(--fs-caption-lg); }
.ref-list .ref-year {
  font-family: var(--font-mono);
  color: var(--ink-3);
  font-size: var(--fs-caption-lg);
}

/* --- WALKTHROUGH (step-by-step worked example) ---------- */
.slide[data-type="walkthrough"] .walk-flow {
  display: grid;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
}
.walk-step {
  display: grid;
  grid-template-columns: 88px 1fr auto;
  gap: var(--sp-3);
  align-items: center;
  padding: 18px var(--sp-4);
  background: var(--bg-card);
  border: var(--hairline) solid var(--rule);
  border-radius: var(--r-md);
  border-left: 8px solid var(--rule-strong);
  transition: transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
  position: relative;
}
.walk-step + .walk-step::before {
  content: "";
  position: absolute;
  left: 44px;
  top: -14px;
  width: 2px;
  height: 14px;
  background: var(--rule-strong);
}
.walk-step[data-color="accent"] { border-left-color: var(--accent); }
.walk-step[data-color="green"]  { border-left-color: var(--c-green); }
.walk-step[data-color="amber"]  { border-left-color: var(--c-amber); }
.walk-step[data-color="violet"] { border-left-color: var(--c-violet); }
.walk-step[data-color="red"]    { border-left-color: var(--c-red); }
.walk-step[data-color="cyan"]   { border-left-color: var(--c-cyan); }

.walk-step .walk-num {
  font-family: var(--font-mono);
  font-size: 40px;
  font-weight: 600;
  color: var(--ink-3);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.walk-step[data-color="accent"] .walk-num { color: var(--accent); }
.walk-step[data-color="green"]  .walk-num { color: var(--c-green); }
.walk-step[data-color="amber"]  .walk-num { color: var(--c-amber); }
.walk-step[data-color="violet"] .walk-num { color: var(--c-violet); }
.walk-step[data-color="red"]    .walk-num { color: var(--c-red); }
.walk-step[data-color="cyan"]   .walk-num { color: var(--c-cyan); }

.walk-step .walk-content {
  display: grid;
  gap: 6px;
  min-width: 0;
}
.walk-step .walk-label {
  font-family: var(--font-serif);
  font-size: 32px;
  line-height: 1.15;
  color: var(--ink);
  font-weight: 500;
}
.walk-step .walk-detail {
  font-family: var(--font-sans);
  font-size: var(--fs-tiny);
  line-height: 1.35;
  color: var(--ink-3);
}
/* Opt-in readable walkthrough: shorten the copy instead of shrinking labels. */
.walk-flow[data-size="body"] .walk-label { font-size: var(--fs-body); }
.walk-flow[data-size="body"] .walk-detail { font-size: var(--fs-small); }
.walk-flow[data-size="body"] .walk-step { padding-top: 12px; padding-bottom: 12px; }
.walk-step .walk-detail code,
.walk-step .walk-state {
  font-family: var(--font-mono);
  background: var(--bg-inset);
  padding: 2px 10px;
  border-radius: 6px;
  font-size: 0.95em;
  color: var(--ink);
  border: 1px solid var(--rule);
}
.walk-step .walk-state {
  font-size: var(--fs-caption-lg);
  background: var(--bg-alt);
  color: var(--ink);
  border: none;
  padding: 6px 16px;
  border-radius: var(--r-sm);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.walk-step[data-color="accent"] .walk-state { background: var(--accent-soft);   color: var(--accent-ink); }
.walk-step[data-color="green"]  .walk-state { background: var(--c-green-soft);  color: var(--c-green-ink); }
.walk-step[data-color="amber"]  .walk-state { background: var(--c-amber-soft);  color: var(--c-amber-ink); }
.walk-step[data-color="violet"] .walk-state { background: var(--c-violet-soft); color: var(--c-violet); }
.walk-step[data-color="red"]    .walk-state { background: var(--c-red-soft);    color: var(--c-red); }
.walk-step[data-color="cyan"]   .walk-state { background: var(--c-cyan-soft);   color: var(--c-cyan-ink); }

/* Final-result step: filled, more emphasis */
.walk-step[data-final="true"] {
  background: var(--ink);
  color: var(--bg);
  border-color: var(--ink);
}
.walk-step[data-final="true"] .walk-num,
.walk-step[data-final="true"] .walk-label,
.walk-step[data-final="true"] .walk-detail,
.walk-step[data-final="true"] .walk-detail strong { color: var(--bg); }
.walk-step[data-final="true"] .walk-detail { opacity: 0.92; }
.walk-step[data-final="true"] .walk-state {
  background: var(--c-amber);
  /* Amber stays light in both themes; theme-dependent ink becomes pale in dark. */
  color: #14181F;
}

/* Progressive reveal driven by data-current-step on slide.
   By default reveal everything; CSS in components.css fades [data-step="N"]
   beyond the current step. Highlight the currently-revealed step. */
.slide[data-current-step="1"] .walk-step[data-step="1"],
.slide[data-current-step="2"] .walk-step[data-step="2"],
.slide[data-current-step="3"] .walk-step[data-step="3"],
.slide[data-current-step="4"] .walk-step[data-step="4"],
.slide[data-current-step="5"] .walk-step[data-step="5"],
.slide[data-current-step="6"] .walk-step[data-step="6"] {
  transform: translateX(6px);
  box-shadow: var(--shadow-md);
}

/* ================================================================
   STEP-SYNCED DIAGRAM HIGHLIGHT  (data-arch-step)
   Give ANY element — an inline <svg> shape or a DOM box — the
   attribute data-arch-step="k". The deck engine (applyStepVisibility)
   tags it `.is-arch-current` at step k, `.is-arch-past` before it, and
   `.is-arch-future` after it — for ANY number of steps, no per-slide JS.
   Use it to light up a hand-authored architecture diagram in lock-step
   with a walkthrough / e2e ledger. (KaTeX can't typeset inside <svg>:
   keep SVG labels to safe text like "28×28×6" and put real \(d_k\) /
   \(W_Q\) math in the side panel.)
   ================================================================ */
[data-arch-step] {
  transition: opacity var(--dur) var(--ease), fill var(--dur) var(--ease),
              stroke var(--dur) var(--ease), stroke-width var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
[data-arch-step].is-arch-future { opacity: 0.4; }

/* SVG shapes: recolour the current step. Default = accent; opt into a
   per-shape colour with data-arch-color (same palette as walk-step). */
svg [data-arch-step].is-arch-current { stroke: var(--accent); stroke-width: 4; fill: var(--accent-soft); }
svg [data-arch-step][data-arch-color="green"].is-arch-current  { stroke: var(--c-green);  fill: var(--c-green-soft); }
svg [data-arch-step][data-arch-color="amber"].is-arch-current  { stroke: var(--c-amber);  fill: var(--c-amber-soft); }
svg [data-arch-step][data-arch-color="violet"].is-arch-current { stroke: var(--c-violet); fill: var(--c-violet-soft); }
svg [data-arch-step][data-arch-color="cyan"].is-arch-current   { stroke: var(--c-cyan);   fill: var(--c-cyan-soft); }
svg [data-arch-step][data-arch-color="red"].is-arch-current    { stroke: var(--c-red);    fill: var(--c-red-soft); }

/* DOM boxes: opt in with class="arch-box" — current step lifts + rings. */
.arch-box[data-arch-step] { border: var(--hairline) solid var(--rule); border-radius: var(--r-sm); }
.arch-box[data-arch-step].is-arch-current { border-color: var(--accent); box-shadow: var(--shadow-md); }

/* ================================================================
   BUDGET ACCUMULATOR  (.walk-budget)
   A running parameter / FLOP / cost tally for an architecture walk.
   Per-step chips carry data-step (revealed cumulatively by the step
   engine) and data-budget="<number>"; js/budget.js sums the revealed
   chips and writes the running total into [data-walk-total]. Optional
   data-budget-format="si" (→ 51.9K / 1.2M / 3B), data-budget-cap
   (turns the total red past the cap), data-budget-prefix/suffix.
   ================================================================ */
.walk-budget {
  margin-top: var(--sp-3);
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--sp-3);
  padding: 14px var(--sp-4);
  background: var(--ink);
  color: var(--bg);
  border-radius: var(--r-md);
}
.walk-budget-head {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  opacity: 0.7;
  white-space: nowrap;
}
.walk-budget-track { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; min-width: 0; }
.walk-budget-item {
  font-family: var(--font-mono);
  font-size: 23px;
  padding: 4px 12px;
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, 0.10);
  color: var(--bg);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.walk-budget-item b { color: #fff; font-weight: 600; }
/* On the dark bar, the global [data-step].is-step-hidden fade reads as
   "not yet counted" — fully dim it so the tally feels live. */
.walk-budget-item[data-step].is-step-hidden { opacity: 0.18; }
.walk-budget-total {
  font-family: var(--font-mono);
  font-size: 34px;
  font-weight: 600;
  background: var(--c-amber);
  color: var(--ink);
  padding: 6px 18px;
  border-radius: var(--r-sm);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.walk-budget-total.is-over { background: var(--c-red); color: #fff; }

/* Two-column architecture walk: a diagram on the left (typically an inline
   <svg> using data-arch-step) and a compact step-ledger on the right. The
   ledger rows tighten so a 5–6 step forward-pass fits beside the diagram. */
.walk-layout {
  display: grid;
  grid-template-columns: 40% 1fr;
  gap: var(--sp-4);
  align-items: start;
  margin-top: var(--sp-3);
}
.walk-layout .walk-flow { margin-top: 0; gap: 10px; }
.walk-layout .walk-diagram { align-self: stretch; }
/* Cap the diagram height so a tall vertical stack doesn't dominate the layout
   and push the budget bar off-canvas; it letterboxes within the column. */
.walk-layout .walk-diagram svg { width: 100%; height: auto; max-height: 560px; display: block; margin: 0 auto; }
.walk-layout .walk-step { grid-template-columns: 60px 1fr auto; padding: 11px var(--sp-3); gap: var(--sp-2); }
.walk-layout .walk-step .walk-num { font-size: var(--fs-caption-lg); }
.walk-layout .walk-step .walk-label { font-size: 25px; }
.walk-layout .walk-step .walk-detail { font-size: 19px; line-height: 1.3; }
.walk-layout .walk-step .walk-state { font-size: 21px; padding: 4px 12px; }
.walk-layout .walk-step + .walk-step::before { left: 30px; }

.cmp-table {
  width: 100%;
  margin-top: var(--sp-4);
  border-collapse: separate;
  border-spacing: 0;
  font-family: var(--font-sans);
  font-size: 32px;
}
/* Контейнер .cmp-table держит рамку и занимает всю ширину, а вложенная <table> ширину не
   наследует и ужимается по содержимому. На слайдах с длинными ячейками разницы не видно, но
   там, где текст короткий, правый край карточки повисает пустым: строки кончаются раньше
   рамки. Найдено глазами на контакт-листе деки 13 (слайд «У PQ нет границы ошибки»),
   не поймано ни одним гейтом — переполнения нет там, где содержимое НЕ достаёт до края. */
.cmp-table > table { width: 100%; }
.cmp-table thead th {
  text-align: left;
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: var(--fs-body);
  padding: var(--sp-3);
  border-bottom: var(--line-thick) solid var(--ink);
  color: var(--ink);
}
.cmp-table thead th:first-child {
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-3);
}
.cmp-table tbody td {
  padding: var(--sp-3);
  border-bottom: var(--hairline) solid var(--rule);
  vertical-align: top;
  line-height: 1.35;
}
.cmp-table tbody td:first-child {
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-3);
  width: 280px;
}
/* …but NEVER uppercase rendered maths. text-transform is inherited, so the label column silently
   rewrote KaTeX output: \tau_i → Τ_I, o_i → O_I, \vartheta_i → Θ_I, \mathrm{cue}_{start} → CUE_START.
   The deck then contradicted itself — its own headline said "what o_i is" above a table saying O_I —
   and the paper's notation was misquoted. A symbol is not a label: opt maths out of the transform
   (and out of the label letter-spacing, which shreds subscripts). Found on L16 s25, fixed globally
   because every deck's first column is exposed to it. Code is also case-sensitive:
   data: and literal \\r\\n must never turn into DATA: and \\R\\N. */
.cmp-table tbody td:first-child .katex,
.cmp-table thead th:first-child .katex,
.cmp-table tbody td:first-child code,
.cmp-table thead th:first-child code {
  text-transform: none;
  letter-spacing: normal;
}
.cmp-table .cell-good { color: var(--c-green-ink); font-weight: 600; }
.cmp-table .cell-bad  { color: var(--c-red); font-weight: 600; }
.cmp-table .cell-meh  { color: var(--c-amber-ink); font-weight: 600; }
.cmp-table tbody tr:hover td { background: var(--bg-alt); }

/* --- FINAL / Q&A ---------------------------------------- */
.slide[data-type="final"] {
  display: none;
}
.slide[data-type="final"].is-active {
  display: grid;
  place-items: center;
  background:
    radial-gradient(circle at 80% 80%, var(--c-amber-soft) 0%, transparent 50%),
    radial-gradient(circle at 20% 20%, var(--accent-soft) 0%, transparent 50%),
    var(--bg);
  text-align: center;
}
.slide[data-type="final"] .final-body { max-width: 1400px; }
.slide[data-type="final"] h1 {
  font-family: var(--font-serif);
  font-size: 240px;
  font-weight: 500;
  line-height: 0.95;
  letter-spacing: -0.03em;
  margin: 0 0 var(--sp-6);
}
.slide[data-type="final"] .final-sub {
  font-size: var(--fs-lead);
  color: var(--ink-2);
  margin-bottom: var(--sp-7);
}
.slide[data-type="final"] .contact-grid {
  display: grid;
  grid-template-columns: repeat(3, auto);
  gap: var(--sp-6);
  justify-content: center;
  margin-top: var(--sp-5);
}
.slide[data-type="final"] .contact-item {
  text-align: left;
}
.slide[data-type="final"] .contact-label {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-3);
  margin-bottom: 4px;
}
.slide[data-type="final"] .contact-value {
  font-family: var(--font-sans);
  font-size: 34px;
  color: var(--ink);
}
