/* wafdc.css: the WAFDC workshop micro-site, built on house.css (ai.ravivasavan.com).
   Same tokens (Labil Grotesk 400, night #0d1b1e, orange #ff795c, white #fff5f5),
   same hairline rows and pill surfaces. Additions are only what a workshop needs:
   bigger body copy, big tap targets, photo pairs, the camera stage. */

:root {
  /* Small print needs more contrast than the house --dim (55%) for this audience. */
  --dim-strong: color-mix(in srgb, var(--fg) 72%, transparent);
  --radius: 16px;
  --tap: 64px;
  color-scheme: light;
}
/* UA parts (fields, scrollbars) follow data-theme, not the OS. Circadian sets it inline (circadian.js). */
[data-theme="night"] { color-scheme: dark; }
@media (prefers-color-scheme: dark) { [data-theme="system"] { color-scheme: dark; } }

html { -webkit-text-size-adjust: 100%; }
body { font-size: 20px; line-height: 1.4; }
[hidden] { display: none !important; }
/* as the deck (draft.css): focus looks like hover, plus a 2px orange outline that keeps each shape */
:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.row:focus-visible, .row:focus-visible .row-sub, .row:focus-visible .arrow { color: var(--orange); }
.row:focus-visible .arrow { transform: translateX(6px); }
/* headings that take focus on a screen change are a starting point for the keyboard, not a target */
.screen > [tabindex="-1"]:focus { outline: none; box-shadow: none; }
/* words land from strings.js (theme-init.js adds this, fill.js lifts it), so <main> never shows empty */
.wafdc-filling main { visibility: hidden; }

/* page shell: the house doc rail (880, as the hub and the takeaways); photos and the camera break out wider */
.site.wafdc { max-width: 880px; justify-content: flex-start; padding-top: clamp(130px, 18vh, 190px); }
.site.wafdc--narrow { max-width: 880px; }
.pair, .train-grid, .test-grid, .share-grid {
  --bleed: max(100%, min(1084px, 100vw - 2 * clamp(24px, 6vw, 48px) - 24px));
  width: var(--bleed); margin-inline: calc((100% - var(--bleed)) / 2);
}
.screen { display: flex; flex-direction: column; gap: 0; }

h2.q-title, .screen h2 {
  font-size: clamp(28px, 4vw, 44px); line-height: 1.1; font-weight: 400; margin: 0;
}
.lead { font-size: clamp(21px, 2.6vw, 28px); line-height: 1.35; margin: 18px 0 0; max-width: 34ch; }
.lead--wide { max-width: 48ch; }
.body { font-size: clamp(20px, 2.2vw, 24px); line-height: 1.45; margin: 14px 0 0; max-width: 46ch; }
.small { font-size: 18px; line-height: 1.45; color: var(--dim-strong); margin: 14px 0 0; max-width: 56ch; }
.small a, .body a, .lead a { border-bottom: 1px solid currentColor; }
.small a:hover, .body a:hover, .lead a:hover { color: var(--orange); }

/* start page: the house landing (one-line h1, dim site-line, door rows), fitted so all three
   doors sit above the fold on a laptop or an iPad */
.wafdc-start.site { padding-top: clamp(128px, 20vh, 220px); padding-bottom: clamp(24px, 5vh, 64px); }
.wafdc-start h1, .wafdc-start .site-line { text-wrap: balance; }
/* the house --dim (55%) is 3.9:1 on day paper, under AA for 18-21px; same --dim-strong as the row subs */
.wafdc-start .site-line { color: var(--dim-strong); }
.wafdc-start .rows { margin-top: clamp(28px, 5vh, 72px); }
.wafdc-start .row { padding-block: clamp(16px, 2.8vh, 32px); }
.wafdc-start .row-sub { font-size: clamp(16px, 1.9vw, 19px); color: var(--dim-strong); }
/* house row subtitles are 14-17px; a size up for a tablet room */
.wafdc .row-sub { font-size: clamp(18px, 2vw, 22px); color: var(--dim-strong); }

/* ── buttons: house pill surface, workshop-sized ── */
.actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: clamp(28px, 4vh, 40px); align-items: center; }
.btn {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: var(--tap); padding: 0 30px;
  border: 0; border-radius: 32px;
  font: inherit; font-size: 21px; line-height: 1.1; color: var(--fg);
  background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--row-separator), inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 22%, transparent);
  cursor: pointer; text-align: center;
  transition: background-color 160ms ease, color 160ms ease, transform 160ms var(--ease);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.btn:hover { color: var(--orange); }
.btn:active { transform: scale(0.98); }
.btn:focus-visible { color: var(--orange); }
.btn--primary { background: var(--orange); color: var(--night); box-shadow: none; }
.btn--primary:hover, .btn--primary:focus-visible { background: var(--fg); color: var(--bg); }
.btn--quiet { box-shadow: none; padding: 0 12px; color: var(--dim-strong); text-decoration: underline; text-underline-offset: 4px; }
.btn[disabled] { opacity: 0.4; cursor: not-allowed; }
.btn .arrow { width: 22px; height: 22px; }

/* ── Real or AI? ──
   One stage per round (quiz.js). The reveal lines keep their space from the start, so the
   heading, the photos and Next stay put when the answer shows. quiz.js sets --maxh from the
   screen; the calc is only the first frame. */
#quiz .screen h1, #quiz .screen h2 { text-wrap: balance; }
.wafdc .kicker {
  font-size: clamp(13px, 1.9vh, 16px); line-height: 1.3; letter-spacing: .08em; text-transform: uppercase;
  color: var(--dim-strong); margin: 0 0 14px;
}
.pair {
  --maxh: calc(100svh - 520px);
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(14px, 2vw, 24px);
  margin-top: clamp(22px, 3vh, 32px); align-items: center; justify-items: start;
}
/* side by side: a photo capped by height hugs the centre gap, so the pair stays one centred unit */
.pair:not([data-orient="text"]) > .choice-wrap:first-child { justify-self: end; }
@media (orientation: portrait) {
  .pair[data-orient="landscape"] { grid-template-columns: 1fr; }
  .pair[data-orient="landscape"] > .choice-wrap:first-child { justify-self: start; }
}
/* a round fits the screen exactly (quiz.js reads this bottom space when it sizes the photos) */
#quiz.site.wafdc:has(> #round:not([hidden])) { padding-bottom: 32px; }
@media (max-width: 640px) { #quiz.site.wafdc:has(> #round:not([hidden])) { padding-bottom: 24px; } }
/* a projector or big screen: the pair takes the deck's 160px margins */
@media (min-width: 1600px) { #quiz .pair { --bleed: max(100%, min(1600px, 100vw - 320px)); } }
/* the photo's box comes from its ratio (--ar, from quiz-data), so a slow photo never collapses to 0x0 */
.choice-wrap { position: relative; display: block; max-width: 100%; width: min(100%, calc(max(var(--maxh), 160px) * var(--ar, 1.5))); }
.choice {
  -webkit-appearance: none; appearance: none;
  position: relative; display: block; width: 100%; padding: 0; margin: 0; border: 0; background: var(--separator);
  border-radius: var(--radius); overflow: hidden; cursor: pointer; font: inherit; color: inherit;
  box-shadow: inset 0 0 0 1px var(--separator);
  transition: transform 220ms var(--ease), box-shadow 160ms ease;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.choice img {
  display: block; width: 100%; height: auto; max-height: none;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
/* hover = focus: a 4px orange ring. Waits for the photos (aria-disabled) and for a real mouse move (.no-hover). */
.pair:not(.no-hover) button.choice:not([aria-disabled="true"]):hover,
button.choice:not([aria-disabled="true"]):focus-visible { box-shadow: 0 0 0 4px var(--orange); }
button.choice:not([aria-disabled="true"]):active { transform: scale(0.985); }
.choice[aria-disabled="true"], .text-card[aria-disabled="true"] { cursor: default; }
/* after the pick: orange ring = AI, ink ring = your pick (when it was the real one) */
.choice--ai { box-shadow: 0 0 0 4px var(--orange); }
.choice--picked:not(.choice--ai) { box-shadow: 0 0 0 4px var(--fg); }
.is-revealed .choice:focus-visible, .is-revealed .text-card:focus-visible { outline-color: var(--fg); }
.choice__tag {
  position: absolute; left: 12px; top: 12px;
  min-height: 44px; padding: 0 18px; border-radius: 22px;
  display: inline-flex; align-items: center; font-size: 20px; line-height: 1;
  background: var(--bg); color: var(--fg); box-shadow: var(--pill-edge);
  animation: tag-in 420ms var(--ease) both;
}
/* solid, so they read on any photo: Real is paper, AI is orange, Your pick is ink */
.choice__tag--pick { left: auto; right: 12px; background: var(--fg); color: var(--bg); box-shadow: none; }
.choice--ai .choice__tag:not(.choice__tag--pick) { background: var(--orange); color: var(--night); box-shadow: none; }
@keyframes tag-in { from { opacity: 0; } }
.zoom-btn {
  position: absolute; right: 12px; bottom: 12px; z-index: 2;
  width: 56px; height: 56px; border-radius: 28px; border: 0; padding: 0;
  display: grid; place-items: center; cursor: pointer; color: var(--fg);
  background: var(--bg); /* solid, as the tags: a see-through pill over a dark photo left the icon at 2.8:1 */
  box-shadow: var(--pill-edge);
  transition: color 160ms ease;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.zoom-btn svg { width: 24px; height: 24px; }
.zoom-btn:is(:hover, :focus-visible) { color: var(--orange); }
/* → on a round with no pick yet: the deck's gate nudge */
.pair.is-nudged { animation: nudge 460ms var(--ease); }
@keyframes nudge { 0%, 100% { transform: none; } 25% { transform: translateX(-7px); } 60% { transform: translateX(4px); } }

/* text rounds (optional, data-driven); the tag row is kept from the start */
.pair--text { align-items: stretch; }
.text-card {
  -webkit-appearance: none; appearance: none; font: inherit; color: inherit; text-align: left; cursor: pointer;
  width: 100%; min-height: 220px; padding: 76px clamp(22px, 3vw, 36px) clamp(22px, 3vw, 36px); margin: 0; border: 0;
  border-radius: var(--radius); background: transparent; box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 22%, transparent);
  font-size: clamp(22px, 2.6vw, 30px); line-height: 1.35; position: relative;
  display: flex; flex-direction: column; justify-content: flex-start; /* both sentences start on the same line, under the tag row */
  transition: box-shadow 160ms ease;
}
.pair:not(.no-hover) .text-card:not([aria-disabled="true"]):hover,
.text-card:not([aria-disabled="true"]):focus-visible { box-shadow: 0 0 0 4px var(--orange); }
.text-card.choice--ai { box-shadow: 0 0 0 4px var(--orange); }

/* the reveal lines: in the layout from the start, shown on the pick */
.screen .reveal-part { visibility: hidden; opacity: 0; }
.screen.is-revealed .reveal-part { visibility: visible; opacity: 1; transition: opacity 420ms var(--ease); }
/* Next and the credit share a row, so the photos get the height */
.reveal-row { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 28px; margin-top: clamp(20px, 3vh, 32px); }
.reveal-row .actions { margin-top: 0; }
.reveal-row .small { margin: 0; flex: 1 1 28ch; }
#answer-credit a:focus-visible { color: var(--orange); } /* as its hover (the shared .small a rule has hover only) */
@media (max-width: 640px) {
  /* a phone stacks the reveal: the Look for line, then Next, then the credit. quiz.js sizes the
     photos so Next is on screen; it is not sticky, because a stuck button would cover the Look for line */
  .reveal-row { display: contents; }
  .reveal-row .reveal-actions { margin-top: 24px; }
  .reveal-row .small { flex: none; margin-top: 18px; }
  /* two sentences side by side are 164px wide on a phone, and the Real and Your pick tags collide */
  .pair--text { grid-template-columns: 1fr; }
}

.tips { list-style: none; padding: 0; margin: clamp(22px, 3vh, 32px) 0 0; counter-reset: tip; }
.tips li { display: grid; grid-template-columns: auto 1fr; column-gap: 18px; padding: 22px 4px; border-top: 1px solid var(--row-separator); }
.tips li:last-child { border-bottom: 1px solid var(--row-separator); }
.tips li::before { counter-increment: tip; content: counter(tip); grid-column: 1; grid-row: 1 / span 2; font-size: clamp(24px, 3.6vw, 38px); line-height: 1.1; color: var(--orange); min-width: 1.2ch; }
.tips .row-title { grid-column: 2; grid-row: 1; font-size: clamp(24px, 3.4vw, 34px); line-height: 1.1; }
.tips .row-sub { grid-column: 2; grid-row: 2; font-size: clamp(19px, 2vw, 22px); line-height: 1.45; color: var(--dim-strong); margin-top: 6px; display: block; }

/* lightbox: tap-to-enlarge, pinch, drag, wheel, buttons */
.lightbox {
  position: fixed; inset: 0; z-index: 100;
  background: var(--bg); /* solid: only the photo, nothing of the page behind it */
  display: grid; grid-template-rows: 1fr auto;
  animation: lb-in 240ms var(--ease);
}
@keyframes lb-in { from { opacity: 0; } }
.lightbox__stage { position: relative; overflow: hidden; touch-action: none; cursor: grab; }
.lightbox__stage:focus { outline: none; }
.lightbox__stage:active { cursor: grabbing; }
/* width/height auto: the 1200x800 attributes give the ratio, the max caps scale it as one */
.lightbox__img {
  position: absolute; left: 50%; top: 50%; width: auto; height: auto; max-width: 94vw; max-height: calc(100svh - 140px);
  transform-origin: center center; will-change: transform;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; -webkit-user-drag: none;
}
.lightbox__bar { display: flex; justify-content: center; gap: 12px; padding: 16px 16px max(16px, env(safe-area-inset-bottom)); flex-wrap: wrap; }
.lightbox__bar .btn:not(.btn--primary) { background: var(--bg); }

.body--dim { color: var(--dim-strong); }

/* ── Teach a machine ──
   Eight screens, one at a time, each arriving like a deck line. Capture, test and swap share
   one camera stage (teach.js moves it between slots), so it keeps one size on all three: 4:3,
   sized by the screen's height, with a rail beside it and one action row under both. Every
   line keeps its place before it shows, so nothing under it moves. */
#teach .screen.is-entering { animation: teach-in 420ms var(--ease); }
@keyframes teach-in { from { opacity: 0; transform: translateY(12px); } }
#teach .screen > h1, #teach .screen > h2 { text-wrap: balance; }
#teach .screen > .body { max-width: 52ch; margin-top: 10px; text-wrap: pretty; }
#teach .why { margin: 0; font-size: 16px; line-height: 1.35; }
/* each step fits the screen (the quiz's round does the same): a short bottom space, and teach.js
   fit() trims the one flexible thing (stage, dots cards, QR) when a line wraps */
#teach.site.wafdc { padding-bottom: 32px; }
@media (max-width: 640px) { #teach.site.wafdc { padding-bottom: 24px; } }

.train-grid, .test-grid {
  /* the height left for the stage: the screen, less the page's top padding, 264px for the kicker,
     the one-line heading, its line, the gaps and the action row (measured, 768 to 1080 tall) and
     the page's 32px bottom space; teach.js fit() lowers it further if a heading wraps */
  --stage-h: calc(100svh - clamp(130px, 18vh, 190px) - 296px);
  --rail: clamp(220px, 24vw, 340px);
  --gap: clamp(18px, 2.4vw, 32px);
  /* the stage starts on the breakout's left edge (as the share grid and the quiz photos do) and the
     rail takes what is left, so the set ends on its right edge too */
  display: grid; align-items: start;
  grid-template-columns: min(calc(100% - var(--rail) - var(--gap)), max(280px, calc(var(--stage-h) * 4 / 3))) minmax(var(--rail), 1fr);
  column-gap: var(--gap); row-gap: clamp(12px, 2vh, 20px);
  margin-top: clamp(14px, 2vh, 24px);
}
.stage-slot { min-width: 0; }
.stage {
  position: relative; width: 100%; aspect-ratio: 4 / 3; height: auto;
  border-radius: var(--radius); overflow: hidden; background: var(--night);
}
.stage video, .stage canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transform: scaleX(-1); /* mirrored, like a mirror */
}
.stage__status {
  position: absolute; left: 12px; bottom: 12px; z-index: 2;
  min-height: 44px; padding: 0 18px; border-radius: 22px; display: inline-flex; align-items: center;
  max-width: calc(100% - 24px); padding-block: 10px; line-height: 1.3;
  font-size: 19px; -webkit-backdrop-filter: var(--pill-filter); backdrop-filter: var(--pill-filter);
  box-shadow: var(--pill-edge); color: var(--white); background: rgba(13, 27, 30, 0.55);
}
/* the 3, 2, 1 before recording: one big number in the middle of the camera */
.stage__count {
  position: absolute; inset: 0; z-index: 3; display: grid; place-items: center; pointer-events: none;
  font-size: clamp(120px, 22vw, 240px); line-height: 1; font-variant-numeric: tabular-nums;
  color: var(--white); text-shadow: 0 4px 32px rgba(13, 27, 30, 0.6); background: rgba(13, 27, 30, 0.25);
}
.stage__count.is-tick { animation: count-tick 900ms var(--ease) both; }
@keyframes count-tick { from { opacity: 0; transform: scale(1.25); } 30% { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .stage__count.is-tick { animation: none; } }
/* the deck's thinking dots (draft.css .typing) */
.think { display: inline-flex; gap: 6px; margin-left: 12px; }
.think i { width: 7px; height: 7px; border-radius: 50%; background: currentColor; animation: think 1.1s ease-in-out infinite; }
.think i:nth-child(2) { animation-delay: 0.15s; }
.think i:nth-child(3) { animation-delay: 0.3s; }
@keyframes think { 0%, 60%, 100% { opacity: 0.25; } 30% { opacity: 1; } }

.rail { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.rail .small { margin: 0; font-size: 17px; text-wrap: pretty; }
.class-tabs { display: flex; flex-direction: column; gap: 8px; }
.class-tab { min-height: 48px; width: 100%; padding: 0 20px; font-size: 19px; justify-content: space-between; }
.class-tab .name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.class-tab .count { display: inline-block; min-width: 2ch; text-align: end; opacity: 0.7; font-variant-numeric: tabular-nums; }
.class-tab[aria-pressed="true"] { background: var(--orange); color: var(--night); box-shadow: none; }
.class-tab[aria-pressed="true"]:is(:hover, :focus-visible) { background: var(--fg); color: var(--bg); }

/* a card of dots: capture, name and train all draw the same one (inline SVG, follows the theme) */
.dots-box {
  position: relative; display: block; aspect-ratio: 1; border-radius: var(--radius); color: var(--fg);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 18%, transparent);
}
.dots-box svg.dots { position: absolute; inset: 0; width: 100%; height: 100%; }
svg.dots path { fill: none; stroke: currentColor; stroke-opacity: 0.35; stroke-width: 2; stroke-linecap: round; vector-effect: non-scaling-stroke; }
svg.dots circle { fill: var(--orange); }
/* the rail never outgrows the stage: on a short screen the dots card shrinks first */
.dots-card { width: min(100%, max(96px, min(300px, calc(var(--stage-h) - 240px)))); }
.dots-empty {
  position: absolute; inset: 0; margin: 0; padding: 12px; display: grid; place-items: center;
  text-align: center; font-size: 16px; line-height: 1.3; color: var(--dim-strong);
}

/* one action row under the stage and the rail: the main control at the left, the way on at the right */
/* min-height: as tall as the capture row, so Next sits at one height on capture, test and swap */
.action-row { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 14px 24px; min-height: 88px; }
.action-end { margin-left: auto; display: flex; align-items: center; gap: 14px; text-align: right; }
.capture {
  display: inline-grid; min-height: 80px; width: clamp(290px, 25vw, 360px); padding: 0 20px; font-size: clamp(20px, 1.7vw, 24px);
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; touch-action: manipulation;
}
.capture[data-state="counting"] { background: var(--fg); color: var(--bg); }
/* the three labels share one cell, so the button never changes size */
.capture > span { grid-area: 1 / 1; visibility: hidden; }
.capture[data-state="idle"] > [data-for="idle"],
.capture[data-state="counting"] > [data-for="counting"],
.capture[data-state="holding"] > [data-for="holding"],
.capture[data-state="pending"] > [data-for="pending"] { visibility: visible; }
.capture.is-holding { background: var(--fg); color: var(--bg); transform: scale(0.98); }
.capture-progress { display: grid; gap: 4px; min-width: 0; }
.counter { font-size: clamp(24px, 2.4vw, 38px); line-height: 1.05; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#capture-why { visibility: hidden; }
#capture-why.is-shown { visibility: visible; }
.meter-slot { display: grid; align-items: center; height: 22px; }
.meter-slot > * { grid-area: 1 / 1; }
.meter { width: 200px; height: 10px; border-radius: 5px; background: var(--row-separator); overflow: hidden; }
.meter > span { display: block; height: 100%; width: 0; background: var(--orange); transition: width 160ms ease; }
.done-check { width: 22px; height: 22px; color: var(--orange); visibility: hidden; }
.capture-progress.is-done .meter { visibility: hidden; }
.capture-progress.is-done .done-check { visibility: visible; }

/* disabled says so plainly: a flat grey pill, with the reason in a dim line beside it */
#teach .btn[disabled] { opacity: 1; background: var(--row-separator); color: var(--dim); box-shadow: none; cursor: not-allowed; transform: none; }

/* one row of cards, one per shape (--n, from teach.js), so a fourth shape never wraps under the fold */
.name-cards {
  display: grid; grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); gap: clamp(16px, 2.4vw, 28px);
  margin-top: clamp(20px, 3vh, 30px);
}
.name-card { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
/* on a short screen fit() caps the card height (--box-h), so Train it stays in view; the dots stay centred */
.name-cards.is-capped .dots-box { aspect-ratio: auto; height: var(--box-h); }
.name-card .cap { font-size: 18px; color: var(--dim-strong); }
.name-card input {
  font: inherit; font-size: 24px; color: var(--fg); background: transparent; width: 100%;
  min-height: var(--tap); padding: 0 18px; border: 0; border-radius: 14px;
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 25%, transparent);
}
.name-card input::placeholder { color: var(--dim); opacity: 1; }
#teach [data-screen="name"] .actions .why { margin-left: 6px; }

/* one row, as the name cards: a fourth shape makes all four a little smaller instead of wrapping */
.train-cards { display: flex; gap: clamp(16px, 2.4vw, 28px); margin-top: clamp(22px, 3.4vh, 36px); }
.train-card { margin: 0; width: clamp(120px, 15vw, 200px); flex: 0 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.train-card figcaption { font-size: 19px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.train-meter { margin-top: clamp(28px, 4vh, 40px); max-width: 640px; height: 10px; border-radius: 5px; background: var(--row-separator); overflow: hidden; }
.train-meter > span { display: block; height: 100%; width: 0; background: var(--orange); transition: width 1400ms var(--ease); }
[data-screen="train"] { cursor: pointer; }

/* the guess: the name on two reserved lines, then how sure, so the bars never move */
.guess { display: grid; grid-template-rows: 2.1em 1.05em; font-size: clamp(28px, 2.8vw, 44px); line-height: 1.05; margin: 0; }
.guess__name { align-self: end; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-wrap: balance; overflow-wrap: anywhere; }
.guess__name.is-empty { color: var(--dim-strong); }
.guess .pct { color: var(--orange); }
.bars { list-style: none; padding: 0; margin: 4px 0 0; display: grid; gap: 12px; }
.bars li { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 10px; font-size: 19px; }
.bars .n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bars .v { font-variant-numeric: tabular-nums; }
.bars .bar { grid-column: 1 / -1; height: 12px; border-radius: 6px; background: var(--row-separator); overflow: hidden; }
.bars .bar > span { display: block; height: 100%; width: 0; background: color-mix(in srgb, var(--fg) 45%, transparent); transition: width 240ms var(--ease); }
.bars li.is-top .bar > span { background: var(--orange); }

/* swap: the question and its answer hold one slot, as tall as the taller of the two */
.reveal-slot { display: grid; margin-top: 8px; }
.reveal-slot > * { grid-area: 1 / 1; }
.reveal-ask { margin: 0; }
.reveal-text {
  margin: 0; font-size: clamp(22px, 2.1vw, 32px); line-height: 1.2;
  opacity: 0; visibility: hidden; transform: translateY(12px);
  transition: opacity 420ms var(--ease), transform 420ms var(--ease), visibility 0s linear 420ms;
}
.reveal-text em { color: var(--orange); }
.reveal-slot.is-open .reveal-ask, [data-screen="swap"]:has(.reveal-slot.is-open) .reveal-btn { visibility: hidden; }
.reveal-slot.is-open .reveal-text { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }

/* challenge: the hub's door rows, as buttons */
#teach .rows { margin-top: clamp(24px, 4vh, 44px); }
button.row {
  -webkit-appearance: none; appearance: none; width: 100%; margin: 0; background: none;
  border: 0; border-top: 1px solid var(--row-separator); font: inherit; color: inherit; text-align: left; cursor: pointer;
}

/* share: the QR is the thing to hand off, so it gets the room; the link is two lines and a Copy pill */
.share-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(20px, 4vw, 48px); align-items: start; margin-top: clamp(20px, 3vh, 30px); }
.share-link {
  font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 14px; line-height: 1.5; color: var(--dim-strong);
  padding: 14px 16px; border-radius: 12px; box-shadow: inset 0 0 0 1.5px var(--row-separator);
}
.share-link > span { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; word-break: break-all; }
.share-grid .actions { margin-top: 18px; }
.copy { display: inline-grid; }
.copy > span { grid-area: 1 / 1; display: inline-flex; align-items: center; justify-content: center; gap: 10px; transition: opacity 200ms ease; }
.copy__done { opacity: 0; }
.copy__done svg { width: 22px; height: 22px; }
#teach .copy.is-copied { background: transparent; color: var(--orange); box-shadow: inset 0 0 0 1.5px var(--orange); }
.copy.is-copied .copy__label { opacity: 0; }
.copy.is-copied .copy__done { opacity: 1; }
.qr-fig { margin: 0; }
/* --qr: 480, or less from fit() so the note under it (and Start over, side by side) is in view */
.qr { background: #fff; padding: 18px; border-radius: var(--radius); width: min(100%, var(--qr, 480px)); box-shadow: inset 0 0 0 1px var(--separator); }
.qr svg { display: block; width: 100%; height: auto; }
.qr-note { max-width: 40ch; }
.start-over { grid-column: 1 / -1; margin-top: clamp(8px, 2vh, 20px); padding-top: 14px; border-top: 1px solid var(--row-separator); }
.start-over .btn--quiet { padding-inline: 0; }

/* a short landscape screen (iPad Safari is 690 to 740 tall): the rail beside the stage packs tighter,
   so with four shapes the tabs and the bars still end above the action row (fit() does the rest) */
@media (min-width: 900px) and (max-height: 820px) {
  .class-tabs { gap: 6px; }
  .class-tab { min-height: 44px; }
  .class-tabs:has(> :nth-child(4)) { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .class-tabs:has(> :nth-child(4)) .class-tab { padding: 0 12px; gap: 6px; font-size: 17px; }
  .bars { gap: 6px; }
  .bars li { gap: 2px 10px; }
}
@media (min-width: 900px) {
  /* Start over closes the link's column, its foot level with the QR note's, so the whole step
     is one screen tall (fit() trims the QR on a short screen) */
  .share-grid { grid-template-columns: minmax(0, 1fr) minmax(0, var(--qr, 480px)); grid-template-rows: auto 1fr; }
  .share-grid > .qr-fig { grid-column: 2; grid-row: 1 / span 2; }
  .start-over { grid-column: 1; grid-row: 2; align-self: end; margin-top: 0; }
  .qr { width: 100%; }
}
/* one column under 900: the rail's parts in the flow, and the action row held at the bottom of the
   screen, so the button stays in reach beside the camera. The column is sized by the screen's height
   (704px: the page top, heading, tabs, dots row and action row on an upright iPad, measured), so on
   an iPad the whole step fits with nothing under the row; a phone keeps the full width and scrolls. */
@media (max-width: 899px) {
  .train-grid, .test-grid {
    max-width: min(100%, max(min(100%, 360px), calc((100svh - 704px) * 4 / 3)));
    grid-template-columns: minmax(0, 1fr);
  }
  .rail { display: contents; }
  /* capture: the dots card and its note side by side under the stage */
  .train-grid { grid-template-columns: 96px minmax(0, 1fr); }
  .train-grid > .stage-slot, .train-grid > .action-row, .train-grid .class-tabs { grid-column: 1 / -1; }
  .train-grid .rail > .small { align-self: center; }
  /* the tabs share one row above the stage (a long name ends in …) */
  .train-grid .class-tabs { order: -1; flex-direction: row; }
  .class-tab { flex: 1 1 0; min-width: 0; width: auto; min-height: 44px; padding: 0 10px; gap: 6px; font-size: 16px; }
  .dots-card { width: 96px; }
  /* the button across the top, then the count at the left and the way on at the right; a hairline
     on top, so what scrolls under it reads as passing under a bar */
  .action-row {
    position: sticky; bottom: 0; z-index: 3; background: var(--bg); box-shadow: 0 -1px 0 var(--row-separator);
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px 16px; min-height: 0;
    padding: 12px 0 max(12px, env(safe-area-inset-bottom));
  }
  .action-row > .btn:not(.capture) { justify-self: start; }
  .action-end { grid-column: 2; }
  .capture { grid-column: 1 / -1; width: 100%; min-height: 72px; }
  .counter { font-size: 22px; }
  .meter { width: min(100%, 200px); }
}
/* four name cards in one row on an upright iPad: the phone's field size, so "Type a name" still fits */
@media (max-width: 899px) {
  .name-cards:has(> :nth-child(4)) input { font-size: 20px; padding: 0 14px; }
}
@media (max-width: 640px) {
  .name-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
  .name-card input { font-size: 20px; padding: 0 14px; }
  .meter { width: 160px; }
}
@media (prefers-reduced-motion: reduce) {
  .think i { opacity: 0.5; }
}

.notice { margin: 16px 0 0; padding: 14px 18px; border-radius: 14px; background: color-mix(in srgb, var(--orange) 16%, transparent); font-size: 20px; max-width: 46ch; }

/* phones keep the house doc rail's top, clamp(130px, 18vh, 190px), as the takeaways do */
@media (max-width: 640px) {
  body { font-size: 18px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ── Interpreter notes (/ai-up-close/notes/): a house doc page, like the takeaways, that also prints as
   an A4 handout. Slide lines, numbers and the glossary are kept in step with slides.js by js/notes.js. ── */
html.notes-page { scroll-padding-top: 120px; } /* a link or anchor reached by Tab never lands under the header pills */
.notes section { margin-top: clamp(40px, 7vh, 64px); }
.notes h2 { font-size: clamp(28px, 3.6vw, 40px); line-height: 1.1; font-weight: 400; margin: 0 0 8px; }
.notes h3 { font-size: clamp(21px, 2.4vw, 26px); line-height: 1.15; font-weight: 400; margin: 36px 0 0; }
.notes .take-kicker { margin: 40px 0 8px; color: var(--dim-strong); } /* the site's kicker ink (.wafdc .kicker): 14px at the house 55% is under 4.5:1 */
.notes .take-kicker + h3 { margin-top: 0; }
.notes :is(p, li, th, td, dt, dd):not(.lead, .take-kicker, .small) { font-size: clamp(18px, 2vw, 21px); line-height: 1.45; }
.notes p { margin: 10px 0 0; max-width: 58ch; }
.notes .dim { color: var(--dim-strong); }
.notes .take-kicker + h3 + table, .notes h3 + table { margin-top: 12px; }
/* lists: the deck's facts dash, not browser bullets */
.notes ul { list-style: none; margin: 12px 0 0; padding: 0 0 0 34px; }
.notes ul li { position: relative; margin: 10px 0 0; max-width: 58ch; }
.notes ul li::before { content: ""; position: absolute; left: -34px; top: calc(0.725em - 1px); width: 14px; border-top: 2px solid var(--orange); } /* a border, so it prints without background graphics */
/* tables: hairline rows, a dim label column (time, slide number, fact) and the words in fg */
.notes table { width: 100%; border-collapse: collapse; margin-top: 14px; }
.notes :is(th, td) { text-align: left; vertical-align: top; font-weight: 400; padding: 14px 18px 14px 0; border-top: 1px solid var(--row-separator); }
.notes tr:last-child > * { border-bottom: 1px solid var(--row-separator); }
.notes th[scope="row"] { width: 1%; white-space: nowrap; color: var(--dim-strong); font-variant-numeric: tabular-nums; }
.notes .slides th.n { width: calc(1.25em + 18px); } /* one width for every part's table, so the quoted lines share an x */
.notes .line { display: block; }
.notes .desc { display: block; margin-top: 4px; color: var(--dim-strong); }
.notes :is(.desc, .row-sub) em { color: inherit; } /* quoted screen words keep the text colour */
.notes .term { color: var(--fg); }
/* Teach steps: the quiz's numbered tips, at doc size */
.notes .steps { margin-top: 14px; }
.notes .steps li { padding: 18px 4px; }
.notes .steps li::before, .notes .steps .row-title { font-size: clamp(21px, 2.4vw, 26px); line-height: 1.15; }
.notes .steps .row-sub { font-size: clamp(18px, 2vw, 21px); max-width: 58ch; }
/* glossary: each term grouped with its meaning, so neither prints alone */
.notes dl { margin: 12px 0 0; }
.notes .gl { display: grid; grid-template-columns: minmax(8em, 12em) 1fr; gap: 4px 18px; padding: 14px 0; border-top: 1px solid var(--row-separator); }
.notes .gl:last-child { border-bottom: 1px solid var(--row-separator); }
.notes dd { margin: 0; color: var(--dim-strong); }
@media (max-width: 640px) { .notes .gl { grid-template-columns: 1fr; } }
/* links: the hub's door rows, one size down */
.notes .rows { margin-top: 14px; }
.notes .row { padding-block: clamp(18px, 2.8vh, 26px); }
.notes .row-title { font-size: clamp(22px, 2.8vw, 30px); }
.notes .row-sub { margin-top: 6px; text-wrap: pretty; }
.notes :is(p, li, td, .desc) { text-wrap: pretty; }
.notes .row-keys { margin-top: 4px; }
.notes .row--keys .arrow { grid-row: 1 / span 3; }
.notes :is(.url-path, .nobr) { white-space: nowrap; } /* a URL breaks before its path, never at a hyphen */
.notes .small a:focus-visible { color: var(--orange); }
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* print: day ink on white whatever the screen theme (circadian sets its tokens inline, hence
   !important), handout sizes, and no term, row or step split across a page */
@page notes { size: A4; margin: 16mm 16mm 18mm; }
@media print {
  html.notes-page, html.notes-page[data-theme] {
    --bg: #fff !important; --fg: var(--night) !important;
    --separator: color-mix(in srgb, var(--night) 5%, transparent) !important;
    --row-separator: color-mix(in srgb, var(--night) 18%, transparent) !important;
    --dim: color-mix(in srgb, var(--night) 55%, transparent) !important;
    --dim-strong: color-mix(in srgb, var(--night) 72%, transparent) !important;
    color-scheme: light !important;
  }
  html.notes-page, .notes-page body { background: #fff !important; color: var(--night) !important; transition: none !important; }
  .notes-page .top-blur, .notes-page .header-pills { display: none !important; }
  main.notes { page: notes; }
  .site.wafdc.notes { min-height: 0; max-width: none; padding: 0; }
  .notes-page body { font-size: 11pt; }
  .notes h1 { font-size: 26pt; }
  .notes .lead { font-size: 13pt; max-width: none; margin-top: 3mm; }
  .notes section { margin-top: 7mm; break-inside: auto; }
  .notes h2 { font-size: 16pt; margin-bottom: 1mm; break-after: avoid; }
  .notes h2 + p { break-after: avoid; }
  .notes p { break-inside: avoid; orphans: 3; widows: 3; }
  .notes h3 { font-size: 12pt; margin-top: 5mm; break-after: avoid; }
  .notes .take-kicker { font-size: 8pt; margin: 6mm 0 1mm; break-after: avoid; }
  .notes :is(p, li, th, td, dt, dd):not(.lead, .take-kicker, .small) { font-size: 10pt; line-height: 1.35; }
  .notes :is(th, td) { padding: 1.4mm 4mm 1.4mm 0; }
  .notes .slides th.n { width: calc(1.25em + 4mm); }
  .notes .desc { margin-top: 0.5mm; }
  .notes ul li { margin-top: 1.2mm; }
  .notes :is(ul li, p) { max-width: none; }
  .notes :is(tr, li, .gl, .row) { break-inside: avoid; }
  .notes dl { columns: 2; column-gap: 8mm; break-inside: avoid; }
  .notes .gl { padding: 1.2mm 0; grid-template-columns: 26mm 1fr; column-gap: 3mm; border-bottom: 1px solid var(--row-separator); border-top: 0; }
  .notes .steps li { padding: 1.6mm 0; column-gap: 4mm; }
  .notes .steps li::before, .notes .steps .row-title { font-size: 12pt; color: var(--night); }
  .notes .steps .row-sub { font-size: 10pt; line-height: 1.35; margin-top: 0.5mm; max-width: none; }
  .notes .rows { margin-top: 2mm; }
  .notes .row { padding-block: 1.6mm; }
  .notes .row-title { font-size: 12pt; }
  .notes .row-sub, .notes .small { font-size: 10pt; max-width: none; }
  .notes .row .arrow { display: none; }
}

/* ── Guess the next word (next/) ──
   Candidate rows: word, a bar for its chance, and the %. Uses the page tokens only, so day and
   night both work. js/next.js sets the bar widths. */
#next h1, #next h2 { text-wrap: balance; }
.wafdc .nx-kicker { margin-top: clamp(26px, 4vh, 40px); }
.nx-sentence { font-size: clamp(30px, 5vw, 52px); line-height: 1.2; margin: 0; min-height: 2.4em; overflow-wrap: anywhere; }
.nx-sentence .nx-new { color: var(--orange); }
.nx-cands { display: grid; gap: 10px; margin-top: clamp(14px, 2vh, 22px); }
.nx-cand {
  -webkit-appearance: none; appearance: none; position: relative; overflow: hidden; width: 100%;
  display: grid; grid-template-columns: minmax(5ch, 11ch) 1fr 5ch; align-items: center; gap: 16px;
  min-height: 68px; padding: 8px 22px; border: 0; border-radius: 20px; text-align: left;
  font: inherit; font-size: clamp(24px, 3.4vw, 34px); line-height: 1.1; color: var(--fg); background: transparent;
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 22%, transparent);
  cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent;
  transition: color 160ms ease, transform 160ms var(--ease), box-shadow 160ms ease;
}
.nx-cand:hover, .nx-cand:focus-visible { color: var(--orange); box-shadow: inset 0 0 0 3px var(--orange); }
.nx-cand:active { transform: scale(0.99); }
.nx-cand__word { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nx-cand__track { height: 16px; border-radius: 8px; background: var(--row-separator); overflow: hidden; }
.nx-cand__bar { display: block; height: 100%; width: 0; border-radius: 8px; background: var(--orange); transition: width 260ms var(--ease); }
.nx-cand__pct { font-size: clamp(20px, 2.6vw, 26px); text-align: end; font-variant-numeric: tabular-nums; color: var(--dim-strong); }
.nx-cand.is-picked { background: var(--orange); color: var(--night); box-shadow: none; }
.nx-cand.is-picked .nx-cand__track { background: color-mix(in srgb, var(--night) 20%, transparent); }
.nx-cand.is-picked .nx-cand__bar { background: var(--night); }
.nx-cand.is-picked .nx-cand__pct { color: var(--night); }
.nx-empty { margin-top: clamp(14px, 2vh, 22px); padding: 24px; border-radius: 20px; box-shadow: inset 0 0 0 1.5px var(--row-separator); }
.nx-empty__title { margin: 0; font-size: clamp(24px, 3.2vw, 32px); line-height: 1.2; }
.nx-empty .small { margin-top: 10px; }
.nx-actions { margin-top: clamp(18px, 3vh, 28px); }
.nx-temp { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin-top: clamp(22px, 3.4vh, 34px); }
.nx-temp__label { font-size: 21px; margin-right: 6px; }
.nx-temp__end { font-size: 19px; color: var(--dim-strong); }
.nx-temp__val { font-size: 19px; min-width: 3ch; color: var(--dim-strong); font-variant-numeric: tabular-nums; }
.nx-range { flex: 1 1 200px; min-width: 160px; height: 44px; accent-color: var(--orange); cursor: pointer; touch-action: manipulation; }
.nx-help { margin-top: 6px; }
.nx-chips { display: flex; flex-wrap: wrap; gap: 10px; }
.nx-chips .btn { min-height: 52px; font-size: 19px; padding: 0 22px; }
.nx-own { margin-top: 16px; }
.nx-own__label { display: block; margin: 0 0 8px; }
.nx-own__row { display: flex; flex-wrap: wrap; gap: 12px; }
.nx-input {
  font: inherit; font-size: 22px; color: var(--fg); background: transparent; min-height: var(--tap);
  padding: 0 18px; border: 0; border-radius: 14px;
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 25%, transparent);
}
.nx-own__row .nx-input { flex: 1 1 240px; min-width: 0; }
.nx-input:focus-visible { outline: 3px solid var(--orange); outline-offset: 2px; }
.nx-textarea { display: block; width: 100%; padding: 14px 18px; line-height: 1.4; resize: vertical; }
.nx-textarea::placeholder, .nx-input::placeholder { color: var(--dim); opacity: 1; }
.screen h2.nx-h2 { font-size: clamp(30px, 4.6vw, 48px); line-height: 1.1; font-weight: 400; margin: clamp(44px, 8vh, 80px) 0 0; }
.nx-count { margin: 18px 0 0; }
.nx-mine { margin-top: 4px; }
.nx-msg { min-height: 1.45em; margin-top: 8px; }
.nx-foot { margin-top: clamp(44px, 8vh, 80px); padding-top: 8px; border-top: 1px solid var(--row-separator); }
/* one screen per step, as in Teach a machine */
#next .screen.is-entering { animation: teach-in 420ms var(--ease); }
#next .screen > h1, #next .screen > h2 { text-wrap: balance; }
#next .screen > .body { max-width: 52ch; margin-top: 10px; text-wrap: pretty; }
#next [data-screen="guess"] .nx-sentence { margin-top: clamp(28px, 5vh, 48px); min-height: 0; }
.nx-blank { display: inline-block; width: 3.2em; height: .9em; vertical-align: -.1em; border-bottom: 6px solid var(--orange); }
.nx-guesses { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; margin-top: clamp(24px, 4vh, 40px); max-width: 720px; }
.nx-guesses .btn { justify-content: center; font-size: clamp(22px, 2.8vw, 28px); min-height: 64px; }
.nx-cand:disabled { cursor: default; }
.nx-cand:disabled:not(.is-picked):hover { color: var(--fg); box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 22%, transparent); }
#next [data-screen="temp"] .nx-temp { margin-top: clamp(20px, 3vh, 28px); }
.wafdc .nx-foot .kicker { margin-top: 24px; }
@media (max-width: 560px) {
  .nx-cand { grid-template-columns: minmax(4ch, 8ch) 1fr 4.5ch; gap: 10px; padding: 8px 14px; }
}

/* ── Safe to share? (share/): the card, the three answer buttons, the reveal ──
   Uses the existing tokens only (--fg, --bg, --orange, --night, --radius, --row-separator),
   so day and night both work. Everything is prefixed sg- to stay clear of other pages. */
.sg-card {
  position: relative; margin-top: clamp(18px, 3vh, 28px);
  padding: 64px clamp(22px, 3vw, 36px) clamp(22px, 3vw, 32px);
  border-radius: var(--radius); box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 22%, transparent);
  font-size: clamp(22px, 2.8vw, 32px); line-height: 1.3; text-wrap: pretty; min-height: 160px;
}
.sg-card__kind {
  position: absolute; top: 14px; left: 14px; padding: 6px 12px; border-radius: 999px;
  font-size: 15px; line-height: 1; letter-spacing: 0.04em; text-transform: uppercase;
  background: var(--fg); color: var(--bg);
}
.sg-choices { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: 18px; }
.sg-choice {
  -webkit-appearance: none; appearance: none; font: inherit; cursor: pointer; margin: 0;
  min-height: var(--tap); padding: 14px 12px; border: 0; border-radius: var(--radius);
  background: transparent; color: var(--fg); font-size: clamp(20px, 2.4vw, 26px); line-height: 1.15;
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 40%, transparent);
  transition: box-shadow 160ms ease, background 160ms ease, color 160ms ease, transform 120ms ease;
}
.sg-choice:not([aria-disabled="true"]):hover, .sg-choice:focus-visible { box-shadow: 0 0 0 4px var(--orange); }
.sg-choice:not([aria-disabled="true"]):active { transform: scale(0.98); }
.sg-choice[aria-disabled="true"] { cursor: default; }
.sg-choice--right { background: var(--orange); color: var(--night); box-shadow: none; }
.sg-choice--picked:not(.sg-choice--right) { box-shadow: 0 0 0 4px var(--fg); }
.sg-choice__tag { display: block; margin-top: 6px; font-size: 15px; letter-spacing: 0.04em; text-transform: uppercase; min-height: 1em; }
.sg-why { min-height: 3.9em; }
.sg-mentor { margin-top: clamp(22px, 3vh, 32px); padding-top: 18px; border-top: 1px solid var(--row-separator); }
@media (max-width: 640px) {
  .sg-choices { grid-template-columns: 1fr; gap: 10px; }
}

/* ── How AI sees (pixels/) ──
   Two parts on one page: a photo as numbers, and a guess-as-it-sharpens game. All colours are
   the existing tokens, so day and night both work. The canvas is capped by screen height so it
   stays large on a projector without pushing the buttons off. */
#pixels .px-stage {
  --bleed: max(100%, min(1084px, 100vw - 2 * clamp(24px, 6vw, 48px) - 24px));
  width: min(var(--bleed), calc((100svh - 330px) * 1.5)); min-width: min(100%, 320px);
  margin: clamp(18px, 3vh, 28px) auto 0; aspect-ratio: 3 / 2;
}
@media (min-width: 1600px) { #pixels .px-stage { width: min(1400px, calc((100svh - 330px) * 1.5)); } }
#pixels .px-stage canvas {
  display: block; width: 100%; height: 100%; border-radius: var(--radius); background: var(--separator);
  image-rendering: pixelated; touch-action: manipulation;
}
#pixels .px-stage.is-tappable canvas { cursor: crosshair; }
#pixels .px-controls { display: flex; flex-wrap: wrap; gap: 14px 28px; align-items: center; margin-top: 18px; }
#pixels .px-slider { display: flex; flex-direction: column; gap: 6px; flex: 1 1 280px; max-width: 520px; }
#pixels .px-slider__label { font-size: 16px; letter-spacing: .08em; text-transform: uppercase; color: var(--dim-strong); }
#pixels .px-slider input { width: 100%; height: var(--tap); accent-color: var(--orange); margin: 0; }
#pixels .px-big { font-size: clamp(22px, 3vw, 32px); line-height: 1.2; margin: 14px 0 0; }
#pixels .px-controls .px-big { margin: 0; min-width: 12ch; }
#pixels .px-readout { display: flex; align-items: center; gap: 16px; margin-top: 8px; min-height: 3.2em; }
#pixels .px-readout .lead { margin: 0; }
#pixels .px-swatch { flex: none; width: 56px; height: 56px; border-radius: 12px; box-shadow: 0 0 0 2px var(--fg); }
#pixels .px-dots { display: flex; gap: 10px; margin-top: 16px; }
#pixels .px-dot { width: 18px; height: 18px; border-radius: 50%; box-shadow: inset 0 0 0 2px var(--dim-strong); }
#pixels .px-dot--on { background: var(--orange); box-shadow: none; }
/* one screen per step, as in Teach a machine; the game's four answers sit in a 2 x 2 grid */
#pixels .screen.is-entering { animation: teach-in 420ms var(--ease); }
#pixels .screen > h1, #pixels .screen > h2 { text-wrap: balance; }
#pixels .screen > .body { max-width: 52ch; margin-top: 10px; text-wrap: pretty; }
#pixels .px-answers { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: clamp(18px, 3vh, 28px); max-width: 720px; }
#pixels .px-answers .btn { justify-content: center; width: 100%; }
#pixels .px-answers .btn:disabled:not(.btn--primary) { opacity: .4; }
#pixels .px-feedback { min-height: 1.4em; margin: 14px 0 0; font-size: clamp(18px, 2.2vw, 22px); }
#pixels .actions:has(> .btn:only-child[hidden]) { display: none; }
@media (min-width: 900px) {
  #pixels .px-play { display: grid; grid-template-columns: minmax(0, 3fr) minmax(240px, 2fr); gap: 32px; align-items: start; margin-top: clamp(18px, 3vh, 28px); }
  #pixels .px-play .px-stage { width: 100%; min-width: 0; margin: 0; max-height: calc(100svh - 360px); max-width: calc((100svh - 360px) * 1.5); }
  #pixels .px-play .px-answers { grid-template-columns: 1fr; margin-top: 0; }
  #pixels .px-play .actions { margin-top: 18px; }
}

/* ── Make an app (app/): nine steps, one screen each, over one builder (a working phone, its memory,
   the pieces and rules editors, the code). All classes ap- ── */
#app .screen.is-entering, #app .ap-part1.is-entering { animation: teach-in 420ms var(--ease); }
#app .screen > h1, #app .screen > h2 { text-wrap: balance; }
#app .screen > .body { max-width: 52ch; margin-top: 10px; text-wrap: pretty; }
/* step one: one part at a time */
.ap-parts1 { margin-top: clamp(24px, 4vh, 36px); max-width: 640px; }
.ap-part1 .kicker { margin: 18px 0 0; }
.ap-part1 .ap-card__name { margin-top: 6px; }
.ap-card__ex { margin: 0; font-size: clamp(20px, 2.2vw, 24px); }
/* step two: the starters as big cards */
.ap-starters { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; margin-top: clamp(24px, 4vh, 36px); }
.ap-starter { -webkit-appearance: none; appearance: none; display: flex; flex-direction: column; gap: 8px; text-align: left; font: inherit; color: var(--fg); background: transparent; border: 0; padding: 26px 24px 28px; border-radius: var(--radius); box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 22%, transparent); cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent; transition: color 160ms ease, box-shadow 160ms ease; }
.ap-starter:hover, .ap-starter:focus-visible { color: var(--orange); box-shadow: inset 0 0 0 3px var(--orange); outline: none; }
.ap-starter__name { font-size: clamp(26px, 3vw, 34px); line-height: 1.1; }
.ap-starter__text { font-size: 20px; line-height: 1.4; color: var(--dim-strong); }
/* steps three to six: the phone alone, or beside the memory or an editor */
.ap-solo { margin-top: clamp(20px, 3vh, 32px); max-width: 380px; }
.ap-duo { display: grid; grid-template-columns: minmax(0, 1fr); gap: 32px; margin-top: clamp(20px, 3vh, 32px); }
@media (min-width: 860px) {
  .ap-duo { grid-template-columns: 380px minmax(0, 1fr); align-items: start; }
  .ap-duo--edit { grid-template-columns: minmax(0, 1fr) 380px; }
  .ap-sticky { position: sticky; top: 24px; }
}
.ap-duo .ap-mem { margin-top: 0; }
.ap-duo .ap-mem .ap-h3 { margin-top: 0; }
.ap-piece__name { font-size: 20px; overflow-wrap: anywhere; }
.screen h2.ap-h2 { margin: 0; }
.screen h3.ap-h3, .ap-h3 { font-size: clamp(24px, 3vw, 32px); line-height: 1.15; font-weight: 400; margin: clamp(32px, 5vh, 48px) 0 14px; }
.ap-label { font-size: 18px; line-height: 1.3; color: var(--dim-strong); margin: 20px 0 10px; }
.ap-tag { display: inline-block; font-size: 17px; line-height: 1; padding: 8px 14px 9px; border-radius: 20px; color: var(--orange); box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--orange) 55%, transparent); }

/* cards and example rows */
.ap-card { padding: 26px 24px 28px; border-radius: var(--radius); box-shadow: inset 0 0 0 1.5px var(--row-separator), inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 22%, transparent); }
.ap-icon { color: var(--orange); display: block; width: 52px; height: 52px; }
.ap-card__name { font-size: clamp(28px, 3.4vw, 38px); line-height: 1.1; font-weight: 400; margin: 18px 0 0; }
.ap-card__text { font-size: 21px; line-height: 1.4; color: var(--dim-strong); margin: 10px 0 0; }
.ap-ex { list-style: none; margin: 0; padding: 0; }
.ap-ex li { display: grid; grid-template-columns: 120px 1fr; align-items: baseline; column-gap: 18px; padding: 20px 4px; border-top: 1px solid var(--row-separator); font-size: clamp(20px, 2.2vw, 24px); line-height: 1.35; }
.ap-ex li:last-child { border-bottom: 1px solid var(--row-separator); }
.ap-ex .ap-tag { justify-self: start; }

/* the editors */
.ap-chips { display: flex; flex-wrap: wrap; gap: 10px; }
.ap-chips .btn { min-height: 52px; padding: 0 22px; font-size: 19px; }
.ap-pieces { display: flex; flex-direction: column; gap: 14px; }
.ap-piece { padding: 16px 18px 18px; border-radius: var(--radius); box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 22%, transparent); display: flex; flex-direction: column; gap: 4px; }
.ap-piece__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.ap-ctl { display: flex; gap: 6px; }
.ap-ibtn { -webkit-appearance: none; appearance: none; width: 48px; height: 48px; border: 0; border-radius: 24px; display: grid; place-items: center; background: transparent; color: var(--fg); cursor: pointer; box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 22%, transparent); touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.ap-ibtn:hover:not([disabled]) { color: var(--orange); }
.ap-ibtn[disabled] { opacity: 0.3; cursor: not-allowed; }
.ap-ico { display: grid; place-items: center; }
.ap-field { display: block; }
.ap-field .ap-label { margin: 10px 0 6px; }
.ap-in { width: 100%; font-size: 20px; min-height: 52px; }
.ap-select { padding-right: 14px; }
.ap-note { margin-top: 6px; }
.ap-rules { display: flex; flex-direction: column; gap: 10px; }
.ap-rule { margin: 0; padding: 16px 18px; border-radius: var(--radius); font-size: 21px; line-height: 1.4; background: color-mix(in srgb, var(--fg) 6%, transparent); }
.ap-rule strong { color: var(--orange); }

/* the phone: a rounded frame, readable from the back of the room */
.ap-phone { width: 100%; max-width: 380px; margin-inline: auto; padding: 12px; border-radius: 48px; background: var(--fg); }
.ap-screen { background: var(--bg); color: var(--fg); border-radius: 36px; min-height: 560px; padding: 44px 20px 24px; display: flex; flex-direction: column; gap: 14px; position: relative; overflow: hidden; }
.ap-screen::before { content: ""; position: absolute; top: 14px; left: 50%; width: 84px; height: 8px; margin-left: -42px; border-radius: 4px; background: color-mix(in srgb, var(--fg) 22%, transparent); }
.ap-p-h { font-size: 30px; line-height: 1.1; font-weight: 400; margin: 0; overflow-wrap: anywhere; }
.ap-p-in { font: inherit; font-size: 22px; color: var(--fg); background: transparent; min-height: 56px; width: 100%; padding: 0 16px; border: 0; border-radius: 14px; box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 30%, transparent); }
.ap-p-in::placeholder { color: var(--dim); opacity: 1; }
.ap-p-btn { -webkit-appearance: none; appearance: none; font: inherit; font-size: 22px; min-height: 56px; padding: 0 20px; border: 0; border-radius: 28px; background: var(--orange); color: var(--night); cursor: pointer; overflow-wrap: anywhere; touch-action: manipulation; -webkit-tap-highlight-color: transparent; transition: transform 160ms var(--ease); }
.ap-p-btn:active { transform: scale(0.97); }
.ap-p-list { list-style: none; margin: 0; padding: 0; font-size: 22px; line-height: 1.3; }
.ap-p-list li { padding: 10px 2px; border-top: 1px solid var(--row-separator); overflow-wrap: anywhere; }
.ap-p-list .ap-p-none { color: var(--dim); }
.ap-p-count { margin: 0; font-size: 24px; display: flex; gap: 8px; align-items: baseline; }
.ap-p-count b { font-weight: 400; color: var(--orange); font-size: 30px; font-variant-numeric: tabular-nums; }
.ap-p-msg { margin: auto 0 0; padding: 14px 16px; border-radius: 14px; font-size: 21px; line-height: 1.35; background: color-mix(in srgb, var(--orange) 18%, transparent); overflow-wrap: anywhere; }

.ap-mem { margin-top: 8px; }
.ap-mem .ap-h3 { margin-top: 22px; margin-bottom: 4px; font-size: 26px; }
.ap-memrows { margin-top: 10px; }
.ap-memrow { display: grid; grid-template-columns: minmax(80px, 30%) 1fr; gap: 12px; padding: 12px 4px; border-top: 1px solid var(--row-separator); align-items: baseline; }
.ap-memrow:last-child { border-bottom: 1px solid var(--row-separator); }
.ap-memk { font-size: 19px; color: var(--dim-strong); overflow-wrap: anywhere; }
.ap-memv { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 18px; overflow-wrap: anywhere; }
.ap-codewrap { margin-top: clamp(28px, 5vh, 44px); }
.ap-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 16px; line-height: 1.5; margin: 16px 0 0; padding: 22px; border-radius: var(--radius); background: color-mix(in srgb, var(--fg) 6%, transparent); overflow-x: auto; white-space: pre; tab-size: 2; max-height: 70vh; overflow-y: auto; }

/* step eight: the prompt */
.ap-prompt { font: inherit; font-size: clamp(21px, 2.4vw, 26px); line-height: 1.5; margin: 0; padding: clamp(20px, 3vw, 32px); border-radius: var(--radius); white-space: pre-wrap; overflow-wrap: anywhere; box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--fg) 25%, transparent); }
.ap-copymsg { margin: 0; }
.ap-tips { margin-top: 8px; }
.ap-safe { margin-top: clamp(28px, 4vh, 40px); }
.ap-safe a { border-bottom: 1px solid currentColor; }
.ap-safe a:hover { color: var(--orange); }
.ap-todo { margin-top: clamp(20px, 3vh, 32px); }
