/* Yoonet NZ design system tokens (DESIGN.md, v0.1.0). Do not invent values. */
@font-face {
  font-family: 'Manrope'; font-style: normal; font-weight: 400 800; font-display: block;
  src: url(assets/fonts/manrope.woff2) format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 400 700; font-display: block;
  src: url(assets/fonts/inter.woff2) format('woff2');
}

/* Light is locked. A dark system setting or theme toggle still gets this. */
:root, :root[data-theme="dark"], :root[data-theme="light"] {
  color-scheme: light only;
  --ink: #181925;
  --ink-90: #232538;
  --ink-70: #3a3d54;
  --ink-20: #e5e9f2;
  --ink-10: #f4f6fb;
  --pearl: #f6f6f9;
  --paper: #ffffff;
  --peri: #8a9eff;
  --peri-30: #d3daff;
  --peri-15: #e8ecff;
  --peri-08: #edf0ff;
  --mist: #6b7094;
  --pink: #ff6495;
  --tron: #98e9ed;
  --shadow-soft: 0 4px 18px -6px rgba(24, 25, 37, 0.14);
  --shadow-soft-strong: 0 6px 22px -8px rgba(24, 25, 37, 0.18);
  --shadow-glow: 0 4px 20px -6px rgba(138, 158, 255, 0.30);
  --r-lg: 0.75rem;
  --r-xl: 1.25rem;
  --r-3xl: 1.5rem;
  --display: 'Manrope', system-ui, sans-serif;
  --body: 'Inter', system-ui, sans-serif;
}

/* =====================================================================
   PRINTED LARGE. The shared foundation for the Mint board deck.
   Read _design/SYSTEM.md before using any of this. Contents:

     1. System properties   grid, page colours, font metrics, motion
     2. Reset and stage
     3. The page            .slide, .ink, .flood, .cover, .photo, keel, folio
     4. Placement           .at, .at-cap, .at-base, .at-last, .plot
     5. Type                .fig, display sizes, running text
     6. Rules and lists     .hair, .rule-6, .rule-peri, .rule-list, .ledger
     7. Photographs         .bleed, .panel, .edge, scrims
     8. Motion              rise, fade, glide, pop, draw, wipe, settle, count
     9. Draft marks         .owner, .todo, .notes
    10. Chrome and print    #hud, #notes, #help, grid overlay, @media print

   The tokens above are the Yoonet NZ design system and never change.
   Per slide CSS lives in slides/NN-name.css, scoped to .sNN.
   ===================================================================== */


/* ---------- 1. System properties ---------- */

/* Placement properties are registered so they never inherit: a child of a
   placed element starts again from the defaults instead of its parent's x, y. */
@property --x   { syntax: '<length>';        inherits: false; initial-value: 120px; }
@property --y   { syntax: '<length>';        inherits: false; initial-value: 0px; }
@property --w   { syntax: '<length> | auto'; inherits: false; initial-value: auto; }
@property --h   { syntax: '<length> | auto'; inherits: false; initial-value: auto; }
@property --max { syntax: '<length> | none'; inherits: false; initial-value: none; }
/* --i, the place in the running order, is registered for the same reason: a
   verb inside another verb (the full stop inside a rising line) starts again
   from 0 instead of adding its parent's place to its own delay. */
@property --i   { syntax: '<number>';        inherits: false; initial-value: 0; }

:root {
  /* Grid: 12 columns of 118 with 24 gutters, side margins 120. */
  --m: 120px; --gut: 24px; --colw: 118px;
  --c1: 120px;  --c2: 262px;  --c3: 404px;   --c4: 546px;
  --c5: 688px;  --c6: 830px;  --c7: 972px;   --c8: 1114px;
  --c9: 1256px; --c10: 1398px; --c11: 1540px; --c12: 1682px;
  --edge: 1800px;      /* right edge of the grid */
  --cap: 96px;         /* headline cap line */
  --floor: 940px;      /* content floor, no draft band */
  --keel: 984px;       /* the keel */

  /* Motion. One easing for everything. */
  --ease: cubic-bezier(0.2, 0.7, 0.1, 1);

  /* Font metrics, in em: ascent, descent, cap height. They let .at-cap and
     .at-base land a cap line or a baseline on an exact stage y. */
  --manrope-asc: 1.066;  --manrope-desc: 0.3;     --manrope-cap: 0.72;
  --inter-asc: 0.96875;  --inter-desc: 0.24121;   --inter-cap: 0.72754;
}


/* ---------- 2. Reset and stage ---------- */

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; background: var(--ink); overflow: hidden; }
body { font-family: var(--body); color: var(--ink); -webkit-font-smoothing: antialiased; }
body.idle, body.idle #stage { cursor: none; }

/* The stage is a fixed 1920 by 1080 canvas, scaled to fit by deck.js.
   Every size in this file is in px on that canvas. */
#stage {
  position: absolute; left: 50%; top: 50%;
  width: 1920px; height: 1080px;
  transform-origin: center center;
  cursor: pointer;
}


/* ---------- 3. The page ---------- */

.slide {
  position: absolute; inset: 0;
  display: none;
  padding: 0;
  overflow: hidden;
  background: var(--page);
  color: var(--fg);
  font: 400 30px/var(--lh) var(--body);
  font-kerning: normal;
  text-rendering: optimizeLegibility;

  /* Page colours. Shared classes read these, so .ink and .flood only
     need to change them here. */
  --page: var(--pearl);
  --fg: var(--ink);            /* headlines, figures, list items */
  --fg-soft: var(--ink-70);    /* body */
  --fg-quiet: var(--mist);     /* captions, labels, source, folio */
  /* Hairlines are the type colour at low strength: ink-20 itself is too
     close to pearl to be seen from the back of a boardroom. */
  --hair: color-mix(in srgb, var(--ink) 14%, transparent);
  --rule: var(--ink);          /* the 6px opener */

  /* Running text is Inter until a class says otherwise. */
  --lh: 1.45;
  --f-asc: var(--inter-asc); --f-desc: var(--inter-desc); --f-cap: var(--inter-cap);
}
.slide.active { display: block; z-index: 2; animation: slide-in 300ms var(--ease); }
/* The slide just left stays underneath for the length of the fade, so the
   new page fades in over the old one and never over the dark surround. */
.slide.was { display: block; z-index: 1; }

/* Ink page (01, 21, 24): pearl type on ink. */
.slide.ink, .slide.cover {
  --page: var(--ink);
  --fg: var(--pearl);
  --fg-soft: var(--peri-30);
  --fg-quiet: var(--peri-30);
  --hair: color-mix(in srgb, var(--pearl) 20%, transparent);
  --rule: var(--pearl);
}
/* The one tinted page (23): ink type on periwinkle. */
.slide.flood {
  --page: var(--peri-30);
  --hair: color-mix(in srgb, var(--ink) 16%, transparent);
}

/* The keel: a fine rule at the foot of every printed page. A split page
   sets --keel-x and --keel-w on the section to run it under the text only. */
.slide::before {
  content: ''; position: absolute; pointer-events: none;
  left: var(--keel-x, 120px); top: 984px;
  width: var(--keel-w, 1680px); height: 2px;
  background: var(--hair);
}
/* The folio: the page number, written by deck.js. Sits at the keel's left. */
.folio {
  position: absolute; left: var(--keel-x, 120px); top: 1006px;
  font: 500 26px/1.21 var(--body); font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: var(--fg-quiet); pointer-events: none;
}
.slide.nokeel::before, .slide.nokeel .folio { display: none; }


/* ---------- 4. Placement ----------
   Everything on a slide is absolutely placed in stage px with four
   properties: --x (default 120), --y, --w and --h. Set them inline or in
   the slide's CSS. They do not inherit.

   .at        box: left --x, top --y
   .at-cap    text: the cap line of the first line sits on --y
   .at-base   text: the baseline of the first line sits on --y
   .at-last   text: the baseline of the last line sits on --y
              (direct children of the section only)

   The three text helpers read --lh and the font metrics, so they are
   exact on every shared type class. On your own text set --lh, never
   line-height, and use .f-display or .f-text, never font-family. */
.at, .at-cap, .at-base, .at-last,
.slide > :where(h1, h2) {
  position: absolute;
  left: var(--x);
  width: var(--w); height: var(--h); max-width: var(--max);
}
/* A headline placed straight in the section hangs from column 1 with its
   cap line at y 96 and a 1500 measure, with no class at all. Give it
   .at, .at-base or .at-last and it is placed that way instead. */
.slide > :where(h1, h2):where(:not(.at, .at-base, .at-last)) {
  --y: 96px; --max: 1500px;
  top: calc(var(--y) - ((var(--lh) - var(--f-asc) - var(--f-desc)) / 2 + var(--f-asc) - var(--f-cap)) * 1em);
}
.at { top: var(--y); }
.at-cap, .at-base, .at-last { line-height: var(--lh); }
.at-cap {
  top: calc(var(--y) - ((var(--lh) - var(--f-asc) - var(--f-desc)) / 2 + var(--f-asc) - var(--f-cap)) * 1em);
}
.at-base {
  top: calc(var(--y) - ((var(--lh) - var(--f-asc) - var(--f-desc)) / 2 + var(--f-asc)) * 1em);
}
.at-last {
  bottom: calc(1080px - var(--y) - ((var(--lh) - var(--f-asc) - var(--f-desc)) / 2 + var(--f-desc)) * 1em);
}

/* A full stage SVG at 1:1, so every coordinate inside it is a stage px. */
.plot {
  position: absolute; left: 0; top: 0; width: 1920px; height: 1080px;
  overflow: visible; pointer-events: none;
}

/* Font family helpers. They carry the metrics the text helpers need. */
.f-display { font-family: var(--display);
  --f-asc: var(--manrope-asc); --f-desc: var(--manrope-desc); --f-cap: var(--manrope-cap); }
.f-text { font-family: var(--body);
  --f-asc: var(--inter-asc); --f-desc: var(--inter-desc); --f-cap: var(--inter-cap); }


/* ---------- 5. Type ---------- */

/* Figures: Manrope 800, tight, tabular. One hero figure per slide. */
.fig {
  display: block; white-space: nowrap;
  font-family: var(--display); font-weight: 800; font-size: 160px;
  letter-spacing: -0.05em;
  color: var(--fg);
  --lh: 0.85; line-height: var(--lh);
  --f-asc: var(--manrope-asc); --f-desc: var(--manrope-desc); --f-cap: var(--manrope-cap);
}
.fig-xl  { font-size: 340px; }
.fig-l   { font-size: 230px; }
.fig-m   { font-size: 160px; }
.fig-s   { font-size: 132px; }
.fig-xs  { font-size: 84px; }
.fig-row { font-size: 72px; }
/* Figures are proportional: tabular ones leave a hole beside every 1 at
   this size. .fig.tab sets them tabular, for a column that must line up. */
.fig.tab { font-variant-numeric: tabular-nums; }
/* A trailing plus or percent is an <i> inside the figure, set in peri. */
.fig i { font-style: normal; color: var(--peri); }

/* Display: Manrope 800. h1 and h2 are 88 unless a size class says otherwise.
   The size classes also work on any other element. */
h1, h2,
.d-150, .d-140, .d-112, .d-104, .d-96, .d-88, .d-80, .d-76, .d-72, .d-64 {
  font-family: var(--display); font-weight: 800; font-size: 88px;
  letter-spacing: -0.03em; text-wrap: balance;
  color: var(--fg);
  --lh: 1.04; line-height: var(--lh);
  --f-asc: var(--manrope-asc); --f-desc: var(--manrope-desc); --f-cap: var(--manrope-cap);
}
.d-150 { font-size: 150px; }
.d-140 { font-size: 140px; }
.d-112 { font-size: 112px; }
.d-104 { font-size: 104px; }
.d-96  { font-size: 96px; }
.d-88  { font-size: 88px; }
.d-80  { font-size: 80px; }
.d-76  { font-size: 76px; }
.d-72  { font-size: 72px; }
.d-64  { font-size: 64px; }
/* The two stacked poster headlines (06, 22) set solid. */
.d-150, .d-140 { --lh: 1; }

/* The pink full stop from the mark. 01 and 24 only. */
.dot { color: var(--pink); }

/* Standfirst: the one sentence under a headline. */
.standfirst {
  font-family: var(--display); font-weight: 500; font-size: 38px;
  letter-spacing: -0.01em; text-wrap: pretty;
  color: var(--fg);
  --lh: 1.3; line-height: var(--lh);
  --f-asc: var(--manrope-asc); --f-desc: var(--manrope-desc); --f-cap: var(--manrope-cap);
}
.standfirst.sm { font-size: 34px; }

/* Sub title: step titles, "Scholarships", the 12 trio. */
.sub {
  font-family: var(--display); font-weight: 800; font-size: 44px;
  letter-spacing: -0.02em;
  color: var(--fg);
  --lh: 1.15; line-height: var(--lh);
  --f-asc: var(--manrope-asc); --f-desc: var(--manrope-desc); --f-cap: var(--manrope-cap);
}

/* Body: Inter 30. */
.body {
  font-family: var(--body); font-weight: 400; font-size: 30px; text-wrap: pretty;
  color: var(--fg-soft);
  --lh: 1.45; line-height: var(--lh);
  --f-asc: var(--inter-asc); --f-desc: var(--inter-desc); --f-cap: var(--inter-cap);
}
.body + .body { margin-top: 24px; }

/* Label: the line that names a figure. Inter 500, 30. */
.label {
  font-family: var(--body); font-weight: 500; font-size: 30px;
  color: var(--fg-quiet);
  --lh: 1.3; line-height: var(--lh);
  --f-asc: var(--inter-asc); --f-desc: var(--inter-desc); --f-cap: var(--inter-cap);
}
/* Caption: Inter 500, 28. .cap.dark sets it in the body colour. */
.cap {
  font-family: var(--body); font-weight: 500; font-size: 28px;
  color: var(--fg-quiet);
  --lh: 1.35; line-height: var(--lh);
  --f-asc: var(--inter-asc); --f-desc: var(--inter-desc); --f-cap: var(--inter-cap);
}
.label.dark, .cap.dark { color: var(--fg-soft); }
/* Source: where a number came from. The smallest type on screen, 26.
   Its measure is --max (1600 unless the slide says otherwise). */
.source {
  --max: 1600px; max-width: var(--max);
  font-family: var(--body); font-weight: 400; font-size: 26px;
  color: var(--fg-quiet);
  --lh: 1.4; line-height: var(--lh);
  --f-asc: var(--inter-asc); --f-desc: var(--inter-desc); --f-cap: var(--inter-cap);
}
/* A figure inside running text is a <b>: Manrope 800 in the type colour. */
.body b, .standfirst b, .label b, .cap b, .source b {
  font-family: var(--display); font-weight: 800; color: var(--fg);
}


/* ---------- 6. Rules and lists ---------- */

/* Three rules. Each is a block the slide places with --x, --y and --w
   (default: the full grid, 120 to 1800). Add .v and --h for an upright. */
.hair, .rule-6, .rule-peri {
  position: absolute; left: var(--x); top: var(--y);
  --w: 1680px; width: var(--w); height: 2px;
  background: var(--hair);
}
.rule-6    { height: 6px; background: var(--rule); }
.rule-peri { height: 6px; background: var(--peri); }
.hair.v, .rule-6.v, .rule-peri.v { --h: 400px; height: var(--h); width: 2px; }
.rule-6.v, .rule-peri.v { width: 6px; }

/* Rule list: the bullet list without bullets. Hairlines between items.
   --row-pad is the space above and below each item: set it on the list to
   change the row height (row = text + 2 * --row-pad + the 2px hairline). */
.rule-list { list-style: none; --row-pad: 20px; }
.rule-list li {
  font-family: var(--display); font-weight: 600; font-size: 34px;
  letter-spacing: -0.01em; text-wrap: pretty;
  color: var(--fg);
  --lh: 1.3; line-height: var(--lh);
  padding: var(--row-pad) 0;
  border-top: 2px solid var(--hair);
}
.rule-list li:first-child { border-top: 0; }
.rule-list.sm { --row-pad: 16px; }
.rule-list.sm li { font-size: 32px; }

/* Ledger: a 6px opener, then rows on hairlines. --cols sets the columns. */
.ledger::before {
  content: ''; display: block; height: 6px; background: var(--rule);
}
.ledger .row {
  display: grid; grid-template-columns: var(--cols, 1fr auto);
  column-gap: 24px; align-items: baseline;
  padding: 22px 0;
  border-top: 2px solid var(--hair);
}
/* A figure still to be supplied: dashed pink rule, pink figure. */
.ledger .row.gap { border-top: 3px dashed var(--pink); }
.ledger .row.gap .fig { color: var(--pink); }
/* A closing row under a 6px rule instead of a hairline. */
.ledger .row.heavy { border-top: 6px solid var(--rule); }
/* The opener already rules off the first row, whatever kind of row it is:
   a second rule hard under the 6px opener reads as a fault. */
.ledger .row:first-child { border-top: 0; }


/* ---------- 7. Photographs ----------
   Square corners, no filters, full bleed or hard against two stage edges. */

/* Full stage photograph. --pos sets the crop. */
.bleed {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: var(--pos, 50% 50%);
}
/* A photograph in a box the slide places with --x, --y, --w and --h. */
.panel {
  position: absolute; left: var(--x); top: var(--y);
  width: var(--w); height: var(--h);
  overflow: hidden;
}
.panel > img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: var(--pos, 50% 50%);
}
/* A one pixel edge for screenshots and pale photos. Drawn inside the box. */
.edge { outline: 1px solid color-mix(in srgb, var(--ink) 14%, transparent); outline-offset: -1px; }

/* Scrims: ink gradients over ceiling, canopy, road or desk. Never a face.
   --a is the strongest alpha (0.92 at most). The gradient is eased, and
   reaches zero exactly where the slide says.
     .scrim-top     ink at y 0, clear by --to
     .scrim-bottom  clear until --from, ink at y 1080
     .scrim-left    solid until --solid, clear by --to                  */
.scrim-top, .scrim-bottom, .scrim-left {
  position: absolute; inset: 0; pointer-events: none;
  --ink-a: color-mix(in srgb, var(--ink) calc(var(--a, 0.92) * 100%), transparent);
  --ink-b: color-mix(in srgb, var(--ink) calc(var(--a, 0.92) * 68%), transparent);
  --ink-c: color-mix(in srgb, var(--ink) calc(var(--a, 0.92) * 26%), transparent);
  --ink-0: color-mix(in srgb, var(--ink) 0%, transparent);
}
.scrim-top {
  background: linear-gradient(180deg,
    var(--ink-a) 0,
    var(--ink-b) calc(var(--to, 480px) * 0.35),
    var(--ink-c) calc(var(--to, 480px) * 0.7),
    var(--ink-0) var(--to, 480px));
}
.scrim-bottom {
  background: linear-gradient(180deg,
    var(--ink-0) var(--from, 780px),
    var(--ink-c) calc(var(--from, 780px) + (1080px - var(--from, 780px)) * 0.3),
    var(--ink-b) calc(var(--from, 780px) + (1080px - var(--from, 780px)) * 0.65),
    var(--ink-a) 1080px);
}
.scrim-left {
  background: linear-gradient(90deg,
    var(--ink-a) 0, var(--ink-a) var(--solid, 480px), var(--ink-0) var(--to, 640px));
}


/* ---------- 8. Motion ----------
   One contract. Every verb is a FROM keyframe that plays to the element's
   natural CSS, so with no animation the page is simply complete.

   Timing:
     --i     place in the running order (0, 1, 2 ...). On the element
             itself: it does not inherit.
     --step  gap between places, 80ms
     --d     delay before place 0, 150ms (0 for settle)
     --dur   length. Leave it alone unless the brief gives a number.
   --step, --d and --dur may sit on the element or any ancestor.
   The delay is --d + --i * --step. Everything is at rest by 1.6s.      */

.rise, .fade, .glide, .pop, .draw, .grow, .draw-svg, .wipe {
  animation-timing-function: var(--ease);
  animation-delay: calc(var(--d, 150ms) + var(--i, 0) * var(--step, 80ms));
  animation-fill-mode: backwards;
}
/* rise: up 24 and in. The default entrance for type. */
.rise  { animation-name: rise;  animation-duration: var(--dur, 600ms); }
/* fade: in, without moving. Logos, the core of the venn, the full stop. */
.fade  { animation-name: fade;  animation-duration: var(--dur, 600ms); }
/* glide: in from --from-x, --from-y (default 120 to the left). --from-o: 1
   keeps it opaque, for a mark that travels along a scale. */
.glide { animation-name: glide; animation-duration: var(--dur, 900ms); }
/* pop: a dot arriving. No overshoot. */
.pop   { animation-name: pop;   animation-duration: var(--dur, 300ms);
         transform-box: fill-box; transform-origin: 50% 50%; }
/* draw: a rule or a bar grows from its left end. .v grows from the top.
   grow is the same verb, named for bars. */
.draw, .grow { animation-name: draw-x; animation-duration: var(--dur, 700ms);
         transform-box: fill-box; transform-origin: 0 50%; }
.draw.v, .grow.v { animation-name: draw-y; transform-origin: 50% 0; }
/* The ledger draws its opener, not itself. */
.ledger.draw { animation: none; }
.ledger.draw::before {
  --i: inherit;   /* the opener takes the ledger's place in the order */
  transform-origin: 0 50%;
  animation: draw-x var(--dur, 700ms) var(--ease) calc(var(--d, 150ms) + var(--i, 0) * var(--step, 80ms)) backwards;
}
/* draw-svg: a stroke draws along its length. The shape needs pathLength="1". */
.draw-svg { stroke-dasharray: 1; animation-name: draw-stroke; animation-duration: var(--dur, 900ms); }
/* wipe: revealed left to right. For dotted lines and anything draw-svg
   cannot do. .v reveals top to bottom. */
.wipe  { animation-name: wipe-x; animation-duration: var(--dur, 900ms); }
.wipe.v { animation-name: wipe-y; }
/* settle: a photograph eases down from 1.03 and in. On a .panel the image
   moves inside the box and the box stays put. */
.settle:not(.panel), .panel.settle > img {
  animation: settle var(--dur, 1600ms) var(--ease) calc(var(--d, 0ms) + var(--i, 0) * var(--step, 80ms)) backwards;
  transform-origin: 50% 50%;
}
/* The image inside a panel takes the panel's place in the order. */
.panel.settle > img { --i: inherit; }
/* count: [data-count] is run by deck.js. Nothing to style. */

@keyframes slide-in    { from { opacity: 0; } }
@keyframes rise        { from { opacity: 0; translate: 0 24px; } }
@keyframes fade        { from { opacity: 0; } }
@keyframes glide       { from { opacity: var(--from-o, 0); translate: var(--from-x, -120px) var(--from-y, 0px); } }
@keyframes pop         { from { opacity: 0; scale: 0.4; } }
@keyframes draw-x      { from { scale: 0 1; } }
@keyframes draw-y      { from { scale: 1 0; } }
@keyframes draw-stroke { from { stroke-dashoffset: 1; } }
@keyframes wipe-x      { from { clip-path: inset(-60px 100% -60px -60px); } to { clip-path: inset(-60px); } }
@keyframes wipe-y      { from { clip-path: inset(-60px -60px 100% -60px); } to { clip-path: inset(-60px); } }
@keyframes settle      { from { opacity: 0; scale: 1.03; } }

/* The kill switch. ?static, reduced motion, and a slide reached by going
   back all show the finished page at once. */
body.static *, body.static *::before, body.static *::after,
.slide.settled *, .slide.settled *::before, .slide.settled *::after,
.slide.settled::before {
  animation: none !important; transition: none !important;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}


/* ---------- 9. Draft marks. D or ?clean hides them, and nothing moves. ---------- */

/* The owner pill sits top right. A slide whose photograph puts a face there
   moves it with --owner-r and --owner-t on the section (stage px from the
   right and top edges). */
.owner {
  position: absolute; right: var(--owner-r, 48px); top: var(--owner-t, 40px); z-index: 5;
  font: 700 22px/1.2 var(--display);
  background: var(--peri-15); color: var(--ink);
  border-radius: 999px; padding: 10px 20px;
}
.slide.photo .owner, .slide.cover .owner {
  background: color-mix(in srgb, var(--paper) 90%, transparent);
}
/* The to do band sits on the floor, bottom edge at y 964, and never pushes
   content. A split page sets --todo-l and --todo-r (stage x) on the note. */
.todo {
  position: absolute; z-index: 4;
  left: var(--todo-l, 120px); width: calc(var(--todo-r, 1800px) - var(--todo-l, 120px));
  bottom: 116px;
  font: 400 22px/1.4 var(--body); color: var(--ink);
  background: var(--paper); border: 3px dashed var(--pink);
  padding: 16px 24px;
}
.clean .owner, .clean .todo { display: none; }
.notes { display: none; }


/* ---------- 10. Chrome outside the stage, and print ---------- */

/* The "5 / 24" counter. The folio is the page number the room sees, so the
   counter stays off the projected page and shows only while the speaker has
   the notes or the key panel open. */
#hud { display: none; position: fixed; right: 18px; bottom: 12px; font: 500 13px var(--body); color: var(--mist); z-index: 10; pointer-events: none; }
body:has(#notes:not([hidden]), #help:not([hidden])) #hud { display: block; }
#notes {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
  width: min(900px, 90vw); background: var(--ink); color: var(--pearl);
  border: 1px solid var(--ink-70); border-radius: var(--r-xl); padding: 18px 24px;
  font: 400 17px/1.5 var(--body); z-index: 20; box-shadow: var(--shadow-soft-strong);
}
#help {
  position: fixed; left: 24px; bottom: 24px; background: var(--pearl); color: var(--ink);
  border-radius: var(--r-xl); padding: 18px 22px; font: 500 14px/1.8 var(--body);
  display: grid; z-index: 20; box-shadow: var(--shadow-soft-strong);
}
#help[hidden], #notes[hidden] { display: none; }
#help b { font-family: var(--display); }

/* ?grid in the address lays the twelve columns and the four fixed lines
   (cap 96, floor 940, to do 964, keel 984) over the slide. A builder's
   tool: it never shows unless asked for. */
body.grid #stage::after {
  content: ''; position: absolute; inset: 0; z-index: 9; pointer-events: none;
  background:
    linear-gradient(var(--pink), var(--pink)) 0 96px / 100% 1px no-repeat,
    linear-gradient(var(--pink), var(--pink)) 0 940px / 100% 1px no-repeat,
    linear-gradient(var(--pink), var(--pink)) 0 964px / 100% 1px no-repeat,
    linear-gradient(var(--pink), var(--pink)) 0 984px / 100% 1px no-repeat,
    repeating-linear-gradient(90deg,
      color-mix(in srgb, var(--pink) 12%, transparent) 0 118px,
      transparent 118px 142px) 120px 0 / 1680px 100% no-repeat;
}

@media print {
  html, body { overflow: visible; background: none; height: auto; }
  #stage { position: static; transform: none !important; width: auto; height: auto; }
  .slide {
    display: block; position: relative; width: 1920px; height: 1080px;
    break-after: page; page-break-after: always;
  }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  #hud, #notes, #help, #stage::after { display: none !important; }
  @page { size: 1920px 1080px; margin: 0; }
}
