/* ==========================================================================
   home.css — PlansFlow homepage v12.0 (2026-09-30)
   --------------------------------------------------------------------------
   v12: section 04 is now the project folder, "Your canvas, in a folder.",
   and lives in its own file (folder.css, folder.js). The continuity figure
   it replaces left with its rules: §7 (.memory-*), their responsive lines in
   §11 and the greenhouse figure styles (.gh-*) that closed this file. §5's
   tokens and block grammar are reused by the new figure, unchanged.
   --------------------------------------------------------------------------
   v11 adds section 02, "Create. Refine. Plan." (the Ember Gambit game
   project: its boards reuse §5's grammar and add the app's image engine,
   Markdown block, repository link card and three task states), and makes
   both canvas demos follow the page's theme with the app's own light and
   dark palettes (§5 tokens). The wide sheet of 02 is 124 × 52 em and its
   narrow sheet 78 × 75 em; 01 keeps 124 × 49 and 78 × 70.5 (its tablet
   connections now use the 70.5 em viewBox they were drawn for).
   --------------------------------------------------------------------------
   v9 touches nothing above section 01 (the hero, film and logo band are
   byte- and pixel-identical to v8.5). It adds: the no-script board column
   and the data-step board switch (§5), the travelling step indicator and
   the connection draw (§5, §10), the Line → Field figures (§6), the stacked
   memory layout below 1100px (§11), and the closing button's ink (§9).
   --------------------------------------------------------------------------
   Loaded by index.html only, after styles.css, shapes.css and swiss.css.
   The page's own layer: a Swiss editorial composition on the site's tokens,
   with the reference homepage's voice — IBM Plex Sans at regular weight, set
   large and tight; Plex Mono eyebrows; one orange; flat surfaces; one dark
   product panel that mirrors the canvas.

   Shared blocks keep their rules in styles.css: the header, the composer
   (#pf-prompt), the logo loop lists, the footer. Shapes come from the
   library (assets/shapes) and follow the theme through shapes.css.

   Typography contract for the two highlighted words:
     .sw mark   inline-block, line-height .9, padding-bottom .2em, negative
                bottom margin — the box is derived from the face's metrics so
                a descender (the g of "grows", the word it was first
                drawn for) sits inside it with clearance,
                without clipping and without changing the line rhythm.
     h1 lines   each line is a block with white-space: nowrap and a size that
                fits the longest line at every width, so "chat" cannot move.

   Fonts are self-hosted with font-display: block and the hero waits for
   them (html.fonts-ready, set by the inline snippet in <head>), so the
   first visible frame is already set in the final face.
   ========================================================================== */

/* ---------- 0–1. Faces and tokens ------------------------------------------- */
/* Moved to swiss.css (v7.4, 2026-09-17): the self-hosted Plex faces, the .sw
   tokens, the editorial type rules, .sw mark, the page chrome (.sw-hero
   padding, .hero-meta, .hero-foot), .section / .section-label /
   .section-heading, .button and the footer re-housing are shared with
   pricing.html and live there. This file is the homepage only. */

/* ---------- 2. Hero ---------------------------------------------------------- */
/* The right half is the film (film.css, 2026-09-24): a live replica of the
   workspace. The headline's longest line is ~500 px at 1440, so an equal
   split costs the copy nothing and gives the product room to be read.
   (Was 7fr 5fr around the greenhouse figure; see index.backup-pre-film.html.) */
.hero-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 32px; align-items: stretch; }
.hero-copy { min-width: 0; display: flex; flex-direction: column; }
/* v10: the hero's foot line is gone; the logo band's rule now closes the
   hero, at the distance the foot's rule used to sit from the film. */
.sw-hero { padding-bottom: 40px; }

.sw h1 { font-size: clamp(56px, 6.6vw, 110px); line-height: 0.99; letter-spacing: -0.065em; padding-top: 8px; }
.sw h1 > span { display: block; white-space: nowrap; }
.sw h1 .last-line { padding-top: 0.08em; }

/* The real composer, at its real size, under the statement. */
.hero-composer {
  margin-top: 40px;
  --hero-gap-sub: 0px;
  --hero-gap-prompt: 14px;
  --hero-prompt-w: 768px;
  --hero-prompt-h: 108px;
  --hero-prompt-size: 17.5px;
  --hero-prompt-radius: 20px;
  --hero-chip-size: 12.5px;
}
.hero-composer .pf-prompt { margin: 0; }

/* Plani stickers: section-relative positions reproduce the owner's desktop
   placements at a 1600px CSS viewport, without depending on page height. */
#game, #anywhere { position: relative; }
.plani-sticker {
  position: absolute;
  z-index: 5;
  display: block;
  height: auto;
  pointer-events: none;
  user-select: none;
  image-rendering: pixelated;
}
#game .plani-sticker--chess {
  top: 196px;
  left: calc(50% - 74px);
  width: 390px;
}
#anywhere .plani-sticker--teaching {
  top: 347px;
  right: max(2.7vw, calc((100vw - 1600px) / 2 + 43px));
  width: 448px;
}
.hero-composer .pf-starters { align-items: flex-start; }
.hero-composer .pf-starters-row { justify-content: flex-start; }
.hero-composer .pf-starter { font-family: var(--sw-mono); font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; }

.thought-art {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 400px;
  padding: 24px;
  background: var(--sw-accent);
  color: var(--sw-on-accent);
  --pfs-accent: var(--sw-accent);
}
.thought-art .pfs { display: block; width: 100%; height: auto; max-height: 370px; }
/* The figure sits on orange in both themes, so its contract is fixed here:
   ink for lines, labels and the insight (the accent would vanish on orange),
   cream paper for the blocks, the page's mono face for the labels. */
.thought-art .pfs {
  color: var(--sw-on-accent);
  --pfs-accent: var(--sw-on-accent);
  --pfs-paper: #F7F5F0;
  --pfs-line: .55; --pfs-wire: .85; --pfs-dot: .45;
  --pfs-mono: var(--sw-mono);
}
.thought-art.pfs-live { cursor: default; }
.thought-art.pfs-live:focus-visible { outline: 2px solid var(--sw-on-accent); outline-offset: -8px; }
.art-bottom { display: flex; justify-content: space-between; align-items: end; gap: 16px; }
.art-bottom > span:last-child { font-family: var(--sw-mono); font-size: 22px; line-height: 1; }

/* ---------- 3. Used by people at ------------------------------------------- */
.sw-built { padding: 8px 0 8px; }
.sw-built .sw-rule-row { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding-top: 16px; margin-bottom: 20px; border-top: 1px solid var(--sw-line); color: var(--sw-muted); }
.sw-built .logoloop-heading { margin: 0; padding: 0; text-align: left; color: var(--sw-ink); }
.sw-built .logoloop-note-wrap { padding-top: 12px; }
.sw-built .logoloop-note { margin: 0; padding: 0; max-width: 60ch; text-align: left; font-family: var(--sw-sans); font-size: 10px; line-height: 1.5; color: var(--sw-muted); }
@media (max-width: 559px) { .sw-built .sw-rule-row > .eyebrow:last-child { display: none; } }

/* ---------- 5. The canvas demos — the product, in its own colours ------------ */
/* Both demos (01 and 02) draw the app's canvas in the app's own palettes and
   follow the page's theme: Light, or System resolved by the OS (theme.js
   writes data-theme on <html>). Light is the app's light canvas, dark is its
   graphite canvas; blocks, text, frames, connections and the selection
   change together. Sources: src/styles/base.css (:root, .dark), canvas.css
   (.canvas-image-frame, .canvas-selection-border, InfiniteGrid's dots),
   note-block.css and text-block.css (html.light), TaskBlock.tsx,
   LinkCardBlock.tsx, MarkdownBlock.tsx, ImageEngineBlock.tsx. Small status
   text uses deeper steps of the app's emerald, amber, green and orange in
   light, so it keeps 4.5 : 1 on its tinted cream.
   The dark palette is written twice, like styles.css §1: explicit dark, and
   System without scripting. KEEP THE TWO DARK BLOCKS IN SYNC. */
.demo {
  --pd-page: #F4F3F0;
  --pd-frame: rgb(24 22 18 / 0.13);
  --pd-surface: #EEECE7;
  --pd-line: rgb(24 22 18 / 0.1);
  --pd-line-2: rgb(24 22 18 / 0.16);
  --pd-hair: rgb(24 22 18 / 0.07);
  --pd-ink: #2A2A2A;
  --pd-text: #3F3D39;
  --pd-body: rgb(42 42 42 / 0.88);
  --pd-text-2: #56534E;
  --pd-text-3: #66635E;
  --pd-accent: #FF773D;
  --pd-accent-ink: #9A3412;
  --pd-grid: rgb(102 102 102 / 0.2);
  --pd-wire: rgb(42 42 42 / 0.42);
  --pd-wire-tip: rgb(42 42 42 / 0.62);
  --pd-well: rgb(24 22 18 / 0.045);
  --pd-well-2: rgb(24 22 18 / 0.03);
  --pd-chip: rgb(42 42 42 / 0.1);
  --pd-pill-bg: #E6E3DD;
  --pd-pill-line: rgb(24 22 18 / 0.1);
  --pd-pill-ink: rgb(42 42 42 / 0.82);
  --pd-img-line: rgb(24 22 18 / 0.13);
  --pd-img-bg: #E6E3DD;
  --pd-task-line: rgb(24 22 18 / 0.1);
  --pd-shadow: 0 1em 1.5em -0.4em rgb(40 30 10 / 0.14);
  --pd-shadow-soft: 0 0.1em 0.2em rgb(0 0 0 / 0.04), 0 0.4em 1.5em rgb(0 0 0 / 0.04);
  --pd-focus: rgb(42 42 42 / 0.6);
  --pd-green-ink: #05664A;
  --pd-amber-ink: #9A4A0B;
  --pd-done-ink: #157036;
  --pd-tint: 5%;
  --note-bg: #FBF8F0;
  --note-edge: rgb(70 55 25 / 0.14);
  --note-rule: rgb(70 55 25 / 0.2);
  --note-ink: #26221C;
  --note-text: #3E3930;
  --note-muted: #6B655A;
  --note-shadow: 0 1px 2px rgb(40 30 10 / 0.06), 0 10px 22px -14px rgb(40 30 10 / 0.25);
  --mark-insight: #4E8A5F;
  --mark-verify: #A87A2A;
  --mark-caveat: #BF4F44;
  color: var(--pd-ink);
  background: var(--pd-page);
  border: 1px solid var(--pd-frame);
  font-family: Inter, var(--sw-sans);
}
:root[data-theme="dark"] .demo {
  --pd-page: #101214;
  --pd-frame: rgb(255 255 255 / 0.1);
  --pd-surface: #16181B;
  --pd-line: rgb(255 255 255 / 0.08);
  --pd-line-2: rgb(255 255 255 / 0.14);
  --pd-hair: rgb(255 255 255 / 0.06);
  --pd-ink: #F4F3F1;
  --pd-text: #DBD9D5;
  --pd-body: rgb(250 250 250 / 0.85);
  --pd-text-2: #A6A39E;
  --pd-text-3: #8B8783;
  --pd-accent: #FF7A3D;
  --pd-accent-ink: #FF8A55;
  --pd-grid: rgb(255 255 255 / 0.05);
  --pd-wire: rgb(244 243 241 / 0.4);
  --pd-wire-tip: rgb(244 243 241 / 0.62);
  --pd-well: rgb(255 255 255 / 0.05);
  --pd-well-2: rgb(255 255 255 / 0.03);
  --pd-chip: rgb(250 250 250 / 0.14);
  --pd-pill-bg: #1A1D21;
  --pd-pill-line: rgb(255 255 255 / 0.1);
  --pd-pill-ink: rgb(250 250 250 / 0.8);
  --pd-img-line: rgb(255 255 255 / 0.1);
  --pd-img-bg: #1A1D21;
  --pd-task-line: rgb(255 255 255 / 0.1);
  --pd-shadow: 0 1em 1.5em -0.4em rgb(0 0 0 / 0.3);
  --pd-shadow-soft: 0 0.1em 0.2em rgb(0 0 0 / 0.4), 0 0.7em 2.2em rgb(0 0 0 / 0.25);
  --pd-focus: rgb(255 255 255 / 0.72);
  --pd-green-ink: #34D399;
  --pd-amber-ink: #FBBF24;
  --pd-done-ink: rgb(74 222 128 / 0.75);
  --pd-tint: 8%;
  --note-bg: #1F1E1D;
  --note-edge: rgb(255 255 255 / 0.09);
  --note-rule: rgb(255 255 255 / 0.17);
  --note-ink: #EDEBE7;
  --note-text: #CFCCC7;
  --note-muted: #8E8B86;
  --note-shadow: 0 1px 0 rgb(255 255 255 / 0.03) inset, 0 2px 6px rgb(0 0 0 / 0.35), 0 14px 28px -16px rgb(0 0 0 / 0.6);
  --mark-insight: #7DA98A;
  --mark-verify: #CFA35C;
  --mark-caveat: #D8776B;
}
/* ⚠ Mirror of the block above. KEEP IN SYNC. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .demo {
    --pd-page: #101214;
    --pd-frame: rgb(255 255 255 / 0.1);
    --pd-surface: #16181B;
    --pd-line: rgb(255 255 255 / 0.08);
    --pd-line-2: rgb(255 255 255 / 0.14);
    --pd-hair: rgb(255 255 255 / 0.06);
    --pd-ink: #F4F3F1;
    --pd-text: #DBD9D5;
    --pd-body: rgb(250 250 250 / 0.85);
    --pd-text-2: #A6A39E;
    --pd-text-3: #8B8783;
    --pd-accent: #FF7A3D;
    --pd-accent-ink: #FF8A55;
    --pd-grid: rgb(255 255 255 / 0.05);
    --pd-wire: rgb(244 243 241 / 0.4);
    --pd-wire-tip: rgb(244 243 241 / 0.62);
    --pd-well: rgb(255 255 255 / 0.05);
    --pd-well-2: rgb(255 255 255 / 0.03);
    --pd-chip: rgb(250 250 250 / 0.14);
    --pd-pill-bg: #1A1D21;
    --pd-pill-line: rgb(255 255 255 / 0.1);
    --pd-pill-ink: rgb(250 250 250 / 0.8);
    --pd-img-line: rgb(255 255 255 / 0.1);
    --pd-img-bg: #1A1D21;
    --pd-task-line: rgb(255 255 255 / 0.1);
    --pd-shadow: 0 1em 1.5em -0.4em rgb(0 0 0 / 0.3);
    --pd-shadow-soft: 0 0.1em 0.2em rgb(0 0 0 / 0.4), 0 0.7em 2.2em rgb(0 0 0 / 0.25);
    --pd-focus: rgb(255 255 255 / 0.72);
    --pd-green-ink: #34D399;
    --pd-amber-ink: #FBBF24;
    --pd-done-ink: rgb(74 222 128 / 0.75);
    --pd-tint: 8%;
    --note-bg: #1F1E1D;
    --note-edge: rgb(255 255 255 / 0.09);
    --note-rule: rgb(255 255 255 / 0.17);
    --note-ink: #EDEBE7;
    --note-text: #CFCCC7;
    --note-muted: #8E8B86;
    --note-shadow: 0 1px 0 rgb(255 255 255 / 0.03) inset, 0 2px 6px rgb(0 0 0 / 0.35), 0 14px 28px -16px rgb(0 0 0 / 0.6);
    --mark-insight: #7DA98A;
    --mark-verify: #CFA35C;
    --mark-caveat: #D8776B;
  }
}
/* The canvas — only the canvas. One field, its blocks, their connections and
   a single selection; no tools, no zoom, no prompt. Three boards of the same
   project sit in the panel and home.js shows the one that matches the tab.

   GEOMETRY. A board is drawn in em on a fixed sheet (124 × 49 wide, 78 × 70.5
   below 1240px) and the panel's font-size is a fraction of its own width, so
   a board scales as one piece and nothing reflows or collides. Every placed
   element keeps font-size: 1em (its em IS the board unit); type sizes live on
   the children. --x/--y/--w place it on the wide sheet, --tx/--ty/--tw on the
   narrow one. Below 700px the board becomes a plain stack.

   BLOCKS follow the platform's own components (src/styles/note-block.css,
   text-block.css, canvas.css; blocks/*.tsx): notes are warm paper ON the
   board with a margin rule and marks ( ? ! ~ △ ); text and answers are cool
   flat panels IN it; link cards, image frames, video blocks and tasks keep
   their real anatomy. Connections are the platform's flow curves. */
.demo-body { container-type: inline-size; }
.canvas-area {
  --cv-mono: "Roboto Mono", var(--sw-mono);
  position: relative;
  height: 49em;
  overflow: hidden;
  outline: none;
  font-size: 10px;
  font-size: clamp(9.2px, calc(100cqw / 124), 11.8px);
  background-color: var(--pd-page);
  background-image: radial-gradient(circle at 1px 1px, var(--pd-grid) 1px, transparent 0);
  background-size: 20px 20px;
  background-position: 50% 0;
}
.canvas-area:focus-visible { outline: 2px solid var(--pd-focus); outline-offset: -2px; }

.cv-board { position: absolute; left: 50%; top: 0; width: 124em; height: 49em; margin-left: -62em; }
.cv-board[hidden] { display: none; }
/* 02 is three em taller on the wide sheet: its image engine node keeps a
   legible size beside the brief that directs it. */
.canvas-area--game, .canvas-area--game .cv-board { height: 52em; }

/* Which board shows (v9). The markup carries no `hidden`, so the page without
   scripting keeps all three boards; with scripting (html.js is set by the
   snippet in <head>, before the body is parsed) the panel's data-step picks
   one before home.js has run, and home.js keeps `hidden` in step. */
html.js .canvas-area[data-step="research"] .cv-board:not([data-board="research"]),
html.js .canvas-area[data-step="understand"] .cv-board:not([data-board="understand"]),
html.js .canvas-area[data-step="build"] .cv-board:not([data-board="build"]),
html.js .canvas-area[data-step="create"] .cv-board:not([data-board="create"]),
html.js .canvas-area[data-step="refine"] .cv-board:not([data-board="refine"]),
html.js .canvas-area[data-step="plan"] .cv-board:not([data-board="plan"]) { display: none; }

/* No scripting: the three boards stand in a column, each on its own sheet
   with a small index; the tabs, which could not switch anything, step aside. */
.cv-board-label { display: none; }
html:not(.js) .canvas-area { height: auto; }
html:not(.js) .cv-board + .cv-board { border-top: 1px solid var(--pd-line); }
html:not(.js) .sw-steps { display: none; }
html:not(.js) .sw .cv-board-label {
  display: flex; gap: 0.9em; margin: 0; max-width: none;
  font-family: var(--cv-mono); font-size: 1.05em; line-height: 1; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--pd-text-2);
}
.cv-board-label span { color: var(--pd-text-3); }
@media (min-width: 701px) {
  html:not(.js) .cv-board { position: relative; }
  html:not(.js) .sw .cv-board-label { position: absolute; left: 4em; top: 1.1em; }
}
@media (max-width: 1239px) and (min-width: 701px) {
  html:not(.js) .sw .cv-board-label { left: 3em; }
}

/* #workspace (the shared header's Workspace link) marks the top of this
   section; the margin keeps the section rule clear of the fixed header. */
.sw-alias { display: block; height: 0; scroll-margin-top: 96px; }
@media (max-width: 1000px) { .sw-alias { scroll-margin-top: 72px; } }
@media (max-width: 700px) { .sw-alias { scroll-margin-top: 64px; } }

.cv {
  position: absolute;
  left: calc(var(--x) * 1em);
  top: calc(var(--y) * 1em);
  width: calc(var(--w) * 1em);
  margin: 0;
  font-family: Inter, var(--sw-sans);
  font-size: 1em;
  letter-spacing: 0;
  color: var(--pd-text);
  text-wrap: pretty;
}

/* connections — flow curves under the blocks, a small head at the target */
.cv-wires { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; fill: none; stroke: var(--pd-wire); stroke-width: 1.5; stroke-linecap: round; }
.cv-wires path { vector-effect: non-scaling-stroke; }
.cv-wires .cv-tip { fill: var(--pd-wire-tip); stroke: none; }
.cv-wires--mid { display: none; }

/* heading block — the platform sets these in Roboto Mono */
.cv-heading { width: auto; white-space: nowrap; }
.sw .cv-heading span { display: block; font-family: var(--cv-mono); font-size: 2.3em; font-weight: 500; line-height: 1.15; letter-spacing: -0.025em; color: var(--pd-ink); }
.sw .cv-heading--lane span { font-size: 1.5em; letter-spacing: 0; }
.cv-heading--lane i { margin-right: 0.75em; font-style: normal; font-weight: 400; color: var(--pd-text-3); }

/* note — paper on the board */
.cv-note {
  padding: 1.25em 1.5em 1.3em 2.2em;
  border: 1px solid var(--note-edge);
  border-radius: 0.8em;
  background: var(--note-bg);
  box-shadow: var(--note-shadow);
}
.cv-note::before { content: ''; position: absolute; top: 1.1em; bottom: 1.1em; left: 1.1em; width: 1px; border-radius: 1px; background: var(--note-rule); }
.sw .cv-note p { margin: 0; max-width: none; font-size: 1.3em; line-height: 1.5; color: var(--note-text); }
.sw .cv-note p + p { margin-top: 0.3em; }
.sw .cv-note p:first-of-type::first-line { font-weight: 500; color: var(--note-ink); }
.sw .cv-note .cv-src { margin-top: 0.75em; font-family: var(--cv-mono); font-size: 0.98em; line-height: 1.45; letter-spacing: 0.01em; color: var(--note-muted); }
.cv-note[data-mark]::before { width: 1.5px; background: var(--mark); }
.cv-note[data-mark]::after {
  content: var(--glyph);
  position: absolute; top: 0.6em; left: 0.5em;
  width: 1.4em; height: 1.4em;
  border-radius: 0.3em;
  background: var(--note-bg);
  font-size: 0.95em; font-weight: 600; line-height: 1.4em; text-align: center;
  color: var(--mark);
}
.cv-note[data-mark='question'] { --mark: var(--pd-accent); --glyph: '?'; }
.cv-note[data-mark='insight'] { --mark: var(--mark-insight); --glyph: '!'; }
.cv-note[data-mark='verify'] { --mark: var(--mark-verify); --glyph: '~'; }
.cv-note[data-mark='caveat'] { --mark: var(--mark-caveat); --glyph: '△'; }
.cv-note[data-mark='caveat']::after { font-size: 0.8em; }

/* the selection — the platform's accent border, plus the viewfinder corners */
.cv-sel {
  position: absolute; z-index: 2; inset: -3px;
  border: 1.5px solid var(--pd-accent);
  border-radius: calc(0.8em + 3px);
  box-shadow: 0 0 0 1px var(--pd-page), 0 0 14px rgb(255 122 61 / 0.16);
  pointer-events: none;
}
.cv-answer > .cv-sel, .cv-diagram > .cv-sel { border-radius: calc(1.1em + 3px); }
.cv-sel::after {
  content: '';
  position: absolute; inset: -7px;
  --c: var(--pd-ink);
  background:
    linear-gradient(var(--c), var(--c)) top left / 7px 1.5px no-repeat,
    linear-gradient(var(--c), var(--c)) top left / 1.5px 7px no-repeat,
    linear-gradient(var(--c), var(--c)) top right / 7px 1.5px no-repeat,
    linear-gradient(var(--c), var(--c)) top right / 1.5px 7px no-repeat,
    linear-gradient(var(--c), var(--c)) bottom left / 7px 1.5px no-repeat,
    linear-gradient(var(--c), var(--c)) bottom left / 1.5px 7px no-repeat,
    linear-gradient(var(--c), var(--c)) bottom right / 7px 1.5px no-repeat,
    linear-gradient(var(--c), var(--c)) bottom right / 1.5px 7px no-repeat;
}

/* search answer — query, sourced body, follow-ups */
.cv-answer { border: 1px solid var(--pd-line); border-radius: 1.1em; background: var(--pd-surface); }
.cv-answer header { display: flex; align-items: center; gap: 0.8em; padding: 1.1em 1.5em 0.9em; border-bottom: 1px solid var(--pd-hair); color: var(--pd-text-3); }
.cv-answer header svg { flex: none; width: 1.35em; height: 1.35em; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.cv-answer header span { overflow: hidden; font-size: 1.1em; font-weight: 500; white-space: nowrap; text-overflow: ellipsis; }
.cv-answer__body { padding: 1.2em 1.5em 1.1em; }
.sw .cv-answer__body p { margin: 0; max-width: none; font-size: 1.3em; line-height: 1.58; color: var(--pd-body); }
.sw .cv-answer__body p + p { margin-top: 0.55em; }
.cv-answer strong { font-weight: 600; color: var(--pd-ink); }
.cv-answer sup { display: inline-grid; place-items: center; width: 1.55em; height: 1.55em; margin-left: 0.2em; border-radius: 50%; background: var(--pd-chip); font-size: 0.66em; font-weight: 500; line-height: 1; color: var(--pd-ink); vertical-align: 0.5em; }
.sw .cv-answer__body .cv-sources { display: flex; flex-wrap: wrap; gap: 0.2em 1.4em; margin-top: 0.9em; font-family: var(--cv-mono); font-size: 1em; color: var(--pd-text-3); }
.cv-sources b { margin-right: 0.5em; font-weight: 500; color: var(--pd-text-2); }
.cv-answer footer { display: flex; flex-wrap: wrap; gap: 0.6em; padding: 0.2em 1.5em 1.3em; }
.cv-answer footer span { display: inline-flex; align-items: center; gap: 0.5em; padding: 0.5em 1em; border: 1px solid var(--pd-pill-line); border-radius: 99em; background: var(--pd-pill-bg); font-size: 1.08em; font-weight: 500; white-space: nowrap; color: var(--pd-pill-ink); }
.cv-answer footer svg { width: 1.1em; height: 1.1em; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; opacity: 0.5; }

/* text — a flat panel in the board */
.cv-text { padding: 1.7em 1.9em 1.8em; border: 1px solid var(--pd-line); border-radius: 0.8em; background: var(--pd-surface); }
.sw .cv-text h4 { margin: 0 0 0.7em; font-family: inherit; font-size: 1.45em; font-weight: 600; line-height: 1.35; letter-spacing: -0.01em; text-wrap: wrap; color: var(--pd-ink); }
.cv-text ol { display: grid; gap: 0.7em; margin: 0; padding: 0; list-style: none; counter-reset: cv; }
.cv-text li { position: relative; padding-left: 1.9em; font-size: 1.27em; line-height: 1.5; color: var(--pd-body); counter-increment: cv; }
.cv-text li::before { content: counter(cv); position: absolute; left: 0; top: 0.12em; font-family: var(--cv-mono); font-size: 0.85em; color: var(--pd-text-3); }

/* link card */
.cv-link { display: flex; align-items: center; gap: 1.1em; padding: 1.3em 0.9em 1.3em 1.3em; border: 1px solid var(--pd-line); border-radius: 1.1em; background: var(--pd-surface); }
.cv-link__icon { flex: none; display: grid; place-items: center; width: 3.4em; height: 3.4em; border-radius: 0.8em; background: var(--pd-well); color: var(--pd-text-3); }
.cv-link__icon svg { width: 1.6em; height: 1.6em; fill: none; stroke: currentColor; stroke-width: 1.6; }
.cv-link__text { flex: 1; min-width: 0; display: grid; gap: 0.2em; }
.cv-link__text b { display: -webkit-box; overflow: hidden; -webkit-line-clamp: 2; -webkit-box-orient: vertical; font-size: 1.22em; font-weight: 600; line-height: 1.35; color: var(--pd-ink); }
.cv-link__text small { font-size: 1.05em; color: var(--pd-text-3); }
.cv-link__open { flex: none; width: 1.6em; height: 1.6em; margin: 0 0.5em; fill: none; stroke: var(--pd-text-3); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

/* image frame */
.cv-image { overflow: hidden; aspect-ratio: var(--ar, 3 / 2); border: 1.5px solid var(--pd-img-line); border-radius: 1em; background: var(--pd-img-bg); }
.cv-image img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* video block — grip, thumbnail, title and channel */
.cv-video { display: flex; flex-direction: column; overflow: hidden; border: 1px solid var(--pd-line); border-radius: 1.1em; background: var(--pd-surface); }
.cv-video__grip { display: grid; place-items: center; height: 2.2em; background: var(--pd-well-2); color: var(--pd-text-3); }
.cv-video__grip svg { width: 1.6em; height: 1.6em; fill: currentColor; opacity: 0.55; }
.cv-video__thumb { position: relative; display: block; aspect-ratio: 16 / 9; }
.cv-video__thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.cv-video__thumb::after { content: ''; position: absolute; inset: 0; background: rgb(0 0 0 / 0.2); }
.cv-video__play { position: absolute; z-index: 1; left: 50%; top: 50%; width: 5em; height: 3.6em; margin: -1.8em 0 0 -2.5em; border-radius: 0.8em; background: #D33A2C; box-shadow: 0 0.4em 1.2em rgb(0 0 0 / 0.35); }
.cv-video__play::after { content: ''; position: absolute; left: 50%; top: 50%; margin: -0.8em 0 0 -0.5em; border-left: 1.4em solid #fff; border-top: 0.8em solid transparent; border-bottom: 0.8em solid transparent; }
.cv-video__info { display: grid; gap: 0.15em; padding: 0.9em 1.3em 1.1em; }
.cv-video__info b { overflow: hidden; font-size: 1.25em; font-weight: 500; line-height: 1.3; white-space: nowrap; text-overflow: ellipsis; color: var(--pd-ink); }
.cv-video__info small { font-size: 1.05em; color: var(--pd-text-3); }

/* task */
.cv-task { display: flex; align-items: flex-start; gap: 1em; padding: 1.4em 1.5em; border: 1px solid var(--pd-task-line); border-radius: 1.1em; background: var(--pd-surface); box-shadow: var(--pd-shadow); }
.cv-task > svg { flex: none; width: 2em; height: 2em; margin-top: 0.05em; fill: none; stroke: var(--pd-text-3); stroke-width: 1.5; }
.cv-task[data-status='progress'] { border-color: rgb(245 158 11 / 0.3); background: color-mix(in srgb, #F59E0B var(--pd-tint), var(--pd-surface)); }
.cv-task[data-status='progress'] > svg circle { stroke: rgb(245 158 11 / 0.3); }
.cv-task[data-status='progress'] > svg path { stroke: #F59E0B; stroke-width: 2; stroke-linecap: round; }
.cv-task b { display: block; font-size: 1.25em; font-weight: 500; line-height: 1.35; color: var(--pd-ink); }
.cv-task small { display: inline-block; margin-top: 0.6em; padding: 0.2em 0.8em; border-radius: 99em; background: rgb(245 158 11 / 0.1); font-size: 0.98em; font-weight: 500; color: var(--pd-amber-ink); }

/* the made diagram — a light sheet, like the platform's generated infographics */
.cv-diagram { border: 1.5px solid var(--pd-img-line); border-radius: 1em; background: #F3EEE2; color: #14110D; }
.cv-diagram figcaption { display: flex; align-items: center; justify-content: space-between; gap: 1em; padding: 1.3em 1.6em 1em; }
.cv-diagram figcaption b { font-size: 1.45em; font-weight: 600; letter-spacing: -0.01em; }
.cv-diagram figcaption span { padding: 0.3em 0.65em; border: 1px solid rgb(20 17 13 / 0.28); border-radius: 0.35em; font-family: var(--cv-mono); font-size: 0.92em; letter-spacing: 0.08em; text-transform: uppercase; color: #5F584D; }
.cv-diagram > svg, .cv-diagram > img { display: block; width: 100%; height: auto; }
.cv-diagram__marks circle { fill: #FFFFFF; stroke: #14110D; stroke-width: 1; }
.cv-diagram__nums text { font-family: var(--cv-mono); font-size: 9px; font-weight: 500; text-anchor: middle; fill: #14110D; }
.cv-diagram__key { display: grid; grid-auto-flow: column; grid-template-rows: repeat(3, auto); grid-auto-columns: 1fr; gap: 0.55em 1.8em; margin: 0; padding: 1.2em 1.6em 0.5em; list-style: none; counter-reset: key; }
.cv-diagram__key li { position: relative; padding-left: 2.1em; font-size: 1.2em; line-height: 1.4; color: #2A251E; counter-increment: key; }
.cv-diagram__key li::before { content: counter(key); position: absolute; left: 0; top: 0; display: grid; place-items: center; width: 1.6em; height: 1.6em; border: 1px solid #14110D; border-radius: 50%; background: #FFFFFF; font-family: var(--cv-mono); font-size: 0.76em; font-weight: 500; }
.sw .cv-diagram__foot { margin: 0; max-width: none; padding: 0.5em 1.6em 1.3em; font-family: var(--cv-mono); font-size: 0.95em; line-height: 1.4; letter-spacing: 0.01em; color: #5F584D; }

/* ── 02's blocks (v11): the same grammar, plus the app's image engine,
   Markdown block, link card favicon and the three task states. ───────── */

/* a transparent image: the app draws only its frame and leaves the alpha
   alone (canvas.css .canvas-image-frame, .image-transparent-bg), so the
   field and its dots show through the art */
.cv-image--clear { background: transparent; }
.cv-image--clear img { object-fit: contain; }

/* a selected image: the frame stops clipping so the selection can sit
   outside it, and the picture keeps the frame's corners itself */
.cv-image.is-selected { overflow: visible; }
.cv-image.is-selected img { border-radius: calc(1em - 1.5px); }
.cv-image > .cv-sel { border-radius: calc(1em + 3px); }

/* the selection follows each block's own corner radius */
.cv-link > .cv-sel, .cv-task > .cv-sel { border-radius: calc(1.1em + 3px); }

/* link card to a repository — a real link, as in the app (Open link) */
.cv-link--repo { color: inherit; transition: border-color 160ms var(--sw-ease); }
.cv-link--repo:hover { border-color: var(--pd-line-2); }
.cv-link--repo .cv-link__text b { overflow-wrap: anywhere; }
.cv-link__icon .cv-link__favicon { width: 1.75em; height: 1.75em; fill: var(--pd-ink); stroke: none; }

/* image engine node (ImageEngineBlock.tsx), in direction mode and done:
   status, the connected note as its direction, the action prompt, and what
   the run produced. Roboto Mono throughout, like the node. */
.cv-engine { overflow: hidden; border: 1px solid var(--pd-line-2); border-radius: 1em; background: var(--pd-surface); box-shadow: var(--pd-shadow-soft); font-family: var(--cv-mono); color: var(--pd-ink); }
.sw .cv-engine p { margin: 0; max-width: none; font-size: 1em; line-height: 1.4; }
.cv-engine header { padding: 1.25em 1.35em 1em; border-bottom: 1px solid var(--pd-hair); }
.sw .cv-engine__title { display: flex; align-items: center; justify-content: space-between; gap: 0.8em; }
.cv-engine__title b { display: flex; align-items: center; gap: 0.65em; font-size: 1.32em; font-weight: 600; letter-spacing: 0.01em; }
.cv-engine__title b::before { content: ''; flex: none; width: 0.5em; height: 0.5em; border-radius: 50%; background: #4ADE80; }
.cv-engine__title span { font-size: 0.94em; font-weight: 500; letter-spacing: 0.14em; text-transform: uppercase; color: var(--pd-done-ink); }
.sw .cv-engine__sub { margin-top: 0.4em; font-size: 0.94em; letter-spacing: 0.16em; text-transform: uppercase; color: var(--pd-text-3); }
.cv-engine__sec { padding: 1em 1.35em 1.05em; border-bottom: 1px solid var(--pd-hair); }
.cv-engine__sec--prompt { background: rgb(255 107 44 / 0.022); }
.sw .cv-engine__label { display: flex; align-items: center; justify-content: space-between; gap: 0.8em; margin-bottom: 0.7em; }
.cv-engine__label span { display: flex; align-items: center; gap: 0.65em; font-size: 0.98em; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--pd-text-3); }
.cv-engine__label span::before { content: ''; width: 3px; height: 1.1em; border-radius: 1.5px; background: #FF6B2C; }
.cv-engine__label em { font-size: 0.94em; font-style: normal; font-weight: 500; color: var(--pd-accent-ink); }
.sw .cv-engine__chip { display: inline-flex; align-items: center; gap: 0.65em; max-width: 100%; padding: 0.45em 0.85em; border: 1px solid var(--pd-line-2); border-radius: 0.55em; background: var(--pd-well); font-size: 1.05em; }
.cv-engine__chip i { padding: 0.1em 0.45em; border-radius: 0.3em; background: rgb(255 107 44 / 0.1); font-size: 0.86em; font-style: normal; font-weight: 600; letter-spacing: 0.04em; color: var(--pd-accent-ink); }
.cv-engine__chip b { font-weight: 400; }
.cv-engine__chip small { font-size: 0.9em; color: var(--pd-text-2); }
.sw .cv-engine__prompt { padding: 0.95em 1.1em; border: 1px solid var(--pd-line-2); border-radius: 0.75em; background: var(--pd-surface); font-size: 1.14em; line-height: 1.6; }
.sw .cv-engine__foot { padding: 0.9em 1.35em 1.05em; font-size: 0.94em; letter-spacing: 0.02em; text-align: center; color: var(--pd-text-3); }
.cv-engine__foot b { font-weight: 400; color: var(--pd-accent-ink); }

/* Markdown block (MarkdownBlock.tsx): a file-name bar over the raw text,
   in mono — the app shows Markdown as written, not rendered */
.cv-md { overflow: hidden; border: 1px solid var(--pd-line); border-radius: 1.1em; background: var(--pd-surface); box-shadow: var(--pd-shadow-soft); }
.cv-md header { display: flex; align-items: center; gap: 0.75em; padding: 0.85em 1.3em; border-bottom: 1px solid var(--pd-hair); background: var(--pd-well); }
.cv-md header svg { flex: none; width: 1.35em; height: 1.35em; fill: none; stroke: var(--pd-text-3); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.cv-md header span { font-size: 1.12em; font-weight: 500; color: var(--pd-text); }
.cv-md pre { margin: 0; padding: 1.2em 1.4em 1.35em; overflow: hidden; font-family: var(--cv-mono); font-size: 1.1em; line-height: 1.62; white-space: pre-wrap; color: var(--pd-text); }

/* task states (TaskBlockContent.tsx): done, in progress, to do. The status
   ring, the title, the in-progress toggle (clock) and the status pill. */
.cv-task > span { flex: 1; min-width: 0; }
.cv-task small svg { width: 1.1em; height: 1.1em; margin-right: 0.45em; vertical-align: -0.17em; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.cv-task__clock { flex: none; display: grid; place-items: center; width: 2.3em; height: 2.3em; margin: -0.15em -0.45em 0 0; border-radius: 0.45em; color: var(--pd-text-3); opacity: 0.55; }
.cv-task__clock svg { width: 1.4em; height: 1.4em; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.cv-task[data-status='progress'] .cv-task__clock { opacity: 1; background: rgb(245 158 11 / 0.2); color: #F59E0B; }
.cv-task[data-status='todo'] > svg { opacity: 0.6; }
.cv-task[data-status='done'] { border-color: rgb(16 185 129 / 0.3); background: color-mix(in srgb, #10B981 var(--pd-tint), var(--pd-surface)); }
.cv-task[data-status='done'] > svg { stroke: #10B981; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.cv-task[data-status='done'] b { color: var(--pd-text-2); text-decoration: line-through; text-decoration-thickness: 1px; }
.cv-task[data-status='done'] small { background: rgb(16 185 129 / 0.1); color: var(--pd-green-ink); }

/* the three steps under the demo — real tabs */
.sw-steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.sw-steps button {
  position: relative;
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr) 24px;
  align-items: center;
  min-width: 0;
  padding: 24px 24px 24px 0;
  border: 0;
  border-top: 3px solid transparent;
  border-bottom: 1px solid var(--sw-line);
  border-radius: 0;
  background: transparent;
  text-align: left;
  color: inherit;
  font: inherit;
  cursor: pointer;
  transition: background-color 160ms var(--sw-ease);
}
.sw-steps button + button { padding-left: 24px; border-left: 1px solid var(--sw-line); }
.sw-steps button[aria-selected="true"] { border-top-color: var(--sw-accent); }
.sw-steps button > span:nth-child(2) { font-size: 25px; letter-spacing: -0.04em; overflow-wrap: anywhere; }
.sw-steps button > .eyebrow { color: var(--sw-muted); }
.sw-steps .step-arrow { font-family: var(--sw-mono); font-size: 22px; line-height: 1; }
.sw-steps button[aria-selected="true"] .step-arrow { color: var(--sw-accent); }
.sw-steps small { grid-column: 2; display: block; margin-top: 8px; font-size: 12px; color: var(--sw-muted); }
.sw-steps button:hover { background: rgb(255 122 47 / 0.1); }

/* One indicator travels between the steps instead of three borders
   switching, so the move from Research to Understand to Build reads as
   progress along one project. Browsers without :has() keep the borders. */
@supports selector(:has(*)) {
  .sw-steps { position: relative; }
  .sw-steps::before {
    content: '';
    position: absolute; z-index: 1; left: 0; top: 0;
    width: calc(100% / 3); height: 3px;
    background: var(--sw-accent);
    transition: transform 560ms var(--sw-ease);
    pointer-events: none;
  }
  .sw-steps:has(> :nth-child(2)[aria-selected="true"])::before { transform: translateX(100%); }
  .sw-steps:has(> :nth-child(3)[aria-selected="true"])::before { transform: translateX(200%); }
  .sw-steps button[aria-selected="true"] { border-top-color: transparent; }
}

/* ---------- 6. A chat is a line -------------------------------------------- */
.approach {
  background: var(--sw-accent);
  color: var(--sw-on-accent);
  --sw-ink: #17140F;
  --sw-line: rgb(23 20 15 / 0.3);
  --sw-muted: rgb(23 20 15 / 0.72);
  overflow: clip;
}
/* The heading takes its own width; the live laptop (laptop-3d.css) the rest. */
.approach-grid { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 32px; align-items: center; margin: 56px 0 0; }
.approach h2 { font-size: clamp(48px, 6.8vw, 104px); line-height: 1.06; }
.approach-device { justify-self: end; width: 100%; max-width: 560px; --l3d-tag-bg: var(--sw-accent); --l3d-ring: var(--sw-ink); }
.sw-line-art { height: 240px; color: var(--sw-on-accent); transform: rotate(-25deg); will-change: transform; }
.sw-line-art .pfs { width: 100%; height: 100%; color: inherit; }
/* ---------- 7. The project folder ---------------------------------------------- */
/* Section 04: folder.css. */

/* ---------- 8. On your desktop (coming soon) -------------------------------- */
/* Deliberately the quietest and shortest section on the page: the page's own
   paper, a heading and two hairline rows — no supporting copy. The slots are
   inert (aria-disabled, cursor default), so they read as a list of builds,
   not as live buttons. */
.desktop { padding-block: 56px; }
.desktop-grid { display: grid; grid-template-columns: 5fr 7fr; gap: clamp(32px, 6vw, 96px); align-items: center; margin-top: 32px; }
.desktop-copy h2 { font-size: clamp(26px, 2.4vw, 36px); line-height: 1.1; }

.desktop-list { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--sw-line); }
.desktop-list li { border-bottom: 1px solid var(--sw-line); }
.desktop-slot {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr) auto;
  align-items: center;
  gap: 16px;
  width: 100%;
  min-height: 44px;
  padding: 16px 2px;
  border: 0;
  border-radius: 0;
  background: transparent;
  text-align: left;
  color: var(--sw-muted);
  font: inherit;
  cursor: default;
}
.desktop-glyph { display: block; color: var(--sw-ink); opacity: 0.55; }
.desktop-glyph svg { display: block; width: 18px; height: 18px; }
.desktop-text { min-width: 0; }
.desktop-name { display: block; font-size: 18px; letter-spacing: -0.035em; color: var(--sw-ink); }
.desktop-slot small { display: block; margin-top: 4px; font-size: 11px; color: var(--sw-muted); }
.desktop-status {
  align-self: center;
  padding: 4px 8px;
  border: 1px solid var(--sw-line);
  color: var(--sw-muted);
}

/* ---------- 9. Closing ---------------------------------------------------------- */
.closing {
  /* --plane is the dark plane in light and the page colour in dark
     (styles.css §1 / §1b), so the section never reads as a different black. */
  background: var(--plane, #17140F);
  color: #F4F3F0;
  --sw-ink: #F4F3F0;
  --sw-line: rgb(244 243 240 / 0.2);
  --sw-muted: rgb(244 243 240 / 0.7);
  box-shadow: inset 0 1px var(--plane-sheen, rgb(255 255 255 / 0.06));
}
.closing h2 { margin-top: 56px; font-size: clamp(64px, 10.5vw, 160px); line-height: 0.96; }
.closing-bottom { display: flex; justify-content: space-between; align-items: end; gap: 32px; margin-top: 40px; }
.closing p { font-size: 16px; color: var(--sw-muted); }
/* `.sw a { color: inherit }` outranks `.button`, which left cream type on the
   orange (about 2.3 : 1). The button keeps the accent's own ink (about 7 : 1). */
.closing .button { color: var(--sw-on-accent); }
/* ---------- 10. Motion ----------------------------------------------------------- */
@keyframes sw-enter { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes sw-rise  { from { transform: translateY(16px); } to { transform: none; } }

/* Hidden only while scripting runs and the faces are still loading; the
   snippet in <head> flips html.fonts-ready (or gives up after 1.8s). */
html.js:not(.fonts-ready) .sw-enter { opacity: 0; }
html.js:not(.fonts-ready) .sw-enter-move { transform: translateY(16px); }
html.js.fonts-ready .sw-enter { animation: sw-enter 850ms var(--sw-ease) both; }
html.js.fonts-ready .sw-enter-move { animation: sw-rise 850ms var(--sw-ease) both; }
html.js.fonts-ready .thought-art.sw-enter { animation-delay: 120ms; }
html.js.fonts-ready .pff.sw-enter { animation-delay: 120ms; }
html.js.fonts-ready .sw-enter-move { animation-delay: 80ms; }

html.js-reveal [data-reveal] { opacity: 0; transform: translateY(18px); transition: opacity 700ms var(--sw-ease), transform 700ms var(--sw-ease); }
html.js-reveal [data-reveal].is-in { opacity: 1; transform: none; }

/* A board change (v9): the blocks land first, then each connection draws
   from its source to its target, its head arrives, and the selection
   settles last on the block the step is about. The same draw runs once
   when the demo first comes into view. Dash lengths are screen pixels
   (non-scaling strokes); 640 covers the longest connection. */
.panel-change .cv { animation: sw-enter 380ms var(--sw-ease) both; animation-delay: calc(var(--i, 0) * 40ms); }
.panel-change .cv-wires path:not(.cv-tip) { stroke-dasharray: 640; animation: cv-draw 680ms 300ms var(--sw-ease) both; }
.panel-change .cv-wires .cv-tip { animation: cv-wires 240ms 760ms ease-out both; }
.panel-change .cv-sel { animation: cv-sel 560ms 420ms var(--sw-ease) both; }
@keyframes cv-wires { from { opacity: 0; } to { opacity: 1; } }
@keyframes cv-draw { from { stroke-dashoffset: 640; } to { stroke-dashoffset: 0; } }
@keyframes cv-sel { from { opacity: 0; transform: scale(1.025); } to { opacity: 1; transform: none; } }

html.js-reveal .demo .cv-wires path:not(.cv-tip) { stroke-dasharray: 640; }
html.js-reveal .demo:not(.is-in) .cv-wires path:not(.cv-tip) { stroke-dashoffset: 640; }
html.js-reveal .demo:not(.is-in) .cv-wires .cv-tip { opacity: 0; }
html.js-reveal .demo.is-in .cv-wires path:not(.cv-tip) { transition: stroke-dashoffset 900ms 520ms var(--sw-ease); }
html.js-reveal .demo.is-in .cv-wires .cv-tip { transition: opacity 280ms 1180ms ease-out; }

@media (prefers-reduced-motion: reduce) {
  html.js:not(.fonts-ready) .sw-enter { opacity: 1; }
  html.js:not(.fonts-ready) .sw-enter-move { transform: none; }
  html.js.fonts-ready .sw-enter, html.js.fonts-ready .sw-enter-move, .panel-change .cv, .panel-change .cv-wires,
  .panel-change .cv-wires path, .panel-change .cv-wires .cv-tip, .panel-change .cv-sel { animation: none; }
  html.js-reveal [data-reveal] { opacity: 1; transform: none; transition: none; }
  html.js-reveal .demo .cv-wires path:not(.cv-tip) { stroke-dasharray: none; stroke-dashoffset: 0; transition: none; }
  html.js-reveal .demo .cv-wires .cv-tip { opacity: 1; transition: none; }
  .sw-line-art { transform: rotate(-25deg) !important; }
  .sw-steps button, .sw-steps::before { transition: none; }
}

/* ---------- 11. Responsive --------------------------------------------------- */
/* The canvas changes sheet, not scale: below 1240px the boards use their
   narrow placement (78 × 70.5) so type stays readable on a tablet. */
@media (max-width: 1239px) {
  .plani-sticker { position: relative; top: auto !important; bottom: auto !important; left: auto !important; right: auto !important; }
  #game .plani-sticker--chess { width: min(48vw, 390px); margin: 0 5% 20px auto; }
  #anywhere .plani-sticker--teaching { width: min(62vw, 448px); margin: 0 3% 24px auto; }
  .canvas-area { height: 70.5em; font-size: 10px; font-size: clamp(8.8px, calc(100cqw / 78), 11px); }
  .cv-board { width: 78em; height: 70.5em; margin-left: -39em; }
  .canvas-area--game, .canvas-area--game .cv-board { height: 75em; }
  .cv { left: calc(var(--tx, var(--x)) * 1em); top: calc(var(--ty, var(--y)) * 1em); width: calc(var(--tw, var(--w)) * 1em); }
  .cv.t-hide, .cv-wires--wide { display: none; }
  .cv-wires--mid { display: block; }
  .sw .cv-note .cv-src, .sw .cv-answer__body .cv-sources { font-size: 1.08em; }
}

/* Below 1100px the film goes under the copy at full width, so the chat in it
   stays legible; its frame then takes its shape from an aspect ratio. */
@media (max-width: 1100px) {
  .hero-grid { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .hero-grid > .pff .pff-frame { flex: none; min-height: 0; aspect-ratio: 16 / 10.5; }
}
@media (min-width: 701px) and (max-width: 1100px) {
  .hero-composer { margin-top: 92px; }
}
@media (max-width: 560px) {
  .hero-grid > .pff .pff-frame { aspect-ratio: 5 / 4; }
}

@media (max-width: 1000px) {
  .hero-grid { gap: 24px; }
  .sw h1 { font-size: 7vw; }
  .thought-art { min-height: 340px; padding: 16px; }
  .sw-steps button > span:nth-child(2) { font-size: 22px; }
  .approach h2 { font-size: 6.7vw; }
  .desktop-grid { grid-template-columns: 1fr; gap: 24px; }
}

@media (max-width: 700px) {
  #game .plani-sticker--chess { width: min(66vw, 270px); margin: 0 2% 16px auto; }
  #anywhere .plani-sticker--teaching { width: min(88vw, 350px); margin: 0 auto 24px; }
  .hero-grid { grid-template-columns: 1fr; gap: 32px; }
  .sw h1 { font-size: clamp(46px, 10.8vw, 76px); }
  .hero-composer { margin-top: 76px; }
  .sw-hero { padding-bottom: 24px; }
  .thought-art { min-height: 0; height: 320px; }
  .thought-art .pfs { position: absolute; width: 270px; height: 270px; max-height: none; left: 50%; top: 26px; transform: translateX(-50%); --pfs-labels: 0; }
  .art-coordinate, .art-bottom { position: relative; z-index: 1; }
  .art-bottom { margin-top: auto; font-size: 9px; }
  /* the canvas becomes a stack: the key blocks of each board, in reading order */
  .canvas-area { height: auto; padding: 22px 16px 26px; font-size: 10.4px; }
  /* minmax(0, 1fr): the search answer's one-line query would otherwise
     widen the stack past a 320px canvas; it ellipsizes as in the app */
  .cv-board { position: static; display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; width: auto; height: auto; margin: 0; }
  .canvas-area--game, .canvas-area--game .cv-board { height: auto; }
  .cv { position: relative; left: auto; top: auto; width: auto; }
  .cv-heading { white-space: normal; }
  .cv.m-hide, .cv-wires, .cv-wires--mid { display: none; }
  /* 02 on phones: its own reading order (--mo), the home screen concept and
     the icon side by side, and the icon (set aside on tablets) back */
  .canvas-area--game .cv-board { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
  .canvas-area--game .cv { grid-column: 1 / -1; order: var(--mo, 0); }
  .canvas-area--game .cv--half { grid-column: auto; }
  .canvas-area--game .cv.t-hide:not(.m-hide) { display: block; }
  [data-board='plan'] .cv-image--icon { justify-self: start; width: 9em; }
  /* 02's supporting line flows on phones instead of keeping its desktop break */
  .sw-game .section-heading p br { display: none; }
  html:not(.js) .cv-board + .cv-board { margin-top: 24px; padding-top: 24px; }
  .cv-diagram__key { grid-auto-flow: row; grid-template-rows: none; grid-template-columns: 1fr; }
  [data-board='build'] .cv-diagram { order: 1; }
  [data-board='build'] .cv-text { order: 2; }
  [data-board='build'] .cv-note { order: 3; }
  .sw-steps button, .sw-steps button + button { display: flex; flex-wrap: wrap; align-content: start; align-items: center; gap: 8px; padding: 16px 8px; }
  .sw-steps button > span:nth-child(2) { order: 2; width: 100%; font-size: 17px; letter-spacing: -0.035em; }
  .sw-steps .step-arrow { margin-left: auto; font-size: 16px; }
  .sw-steps small { order: 3; margin: 0; font-size: 10px; line-height: 1.5; }
  .approach-grid { grid-template-columns: 1fr; gap: 24px; margin: 40px 0 0; }
  .approach-device { justify-self: center; }
  .approach h2 { font-size: clamp(39px, 8.8vw, 62px); }
  .sw-line-art { height: 180px; width: 100%; max-width: 240px; justify-self: center; }
  .desktop { padding-block: 44px; }
  .desktop-grid { margin-top: 24px; gap: 20px; }
  .desktop-copy h2 { font-size: clamp(26px, 6.4vw, 34px); }
  .desktop-slot { grid-template-columns: 16px minmax(0, 1fr) auto; gap: 12px; padding: 14px 2px; }
  .desktop-glyph svg { width: 16px; height: 16px; }
  .desktop-name { font-size: 16px; }
  .desktop-slot small { margin-top: 4px; font-size: 10px; line-height: 1.5; }
  .closing h2 { margin-top: 40px; font-size: clamp(55px, 12vw, 84px); }
  .closing-bottom { display: block; margin-top: 32px; }
  .closing .button { margin-top: 32px; }
}
