/* ProjectStore — site stylesheet
   smartandpoint.com's look without its gradients: white by default, with midnight and graphite as dark tones; one
   indigo accent; pill buttons and rounded cards; mono for what a terminal would show. Every colour is a token on
   :root; the print rules at the end are the one place that sets its own. Static, no build step. */

/* ---------- fonts ----------
   Served from assets/fonts/, so the site makes no third-party request; provenance and
   licences in README.md and fonts/OFL-Onest.txt, fonts/LICENSE-IBMPlexMono.txt.
   Onest: Google Fonts' woff2 subsets, variable; font-weight and unicode-range from Google's CSS.
   IBM Plex Mono: IBM's own split files (@ibm/plex-mono 2.5.0) with IBM's unicode-range;
   a subset made by anyone else could not carry the reserved name "Plex".
   Chinese uses the platform's fonts (the zh-CN stacks below). */

/* Onest, cyrillic */
@font-face {
  font-family: "Onest";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/onest-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* Onest, symbols */
@font-face {
  font-family: "Onest";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/onest-symbols.woff2") format("woff2");
  unicode-range: U+0001-000C, U+000E-001F, U+007F-009F, U+20DD-20E0, U+20E2-20E4, U+2150-218F, U+2190, U+2192, U+2194-2199, U+21AF, U+21E6-21F0, U+21F3, U+2218-2219, U+2299, U+22C4-22C6, U+2300-243F, U+2440-244A, U+2460-24FF, U+25A0-27BF, U+2800-28FF, U+2921-2922, U+2981, U+29BF, U+29EB, U+2B00-2BFF, U+4DC0-4DFF, U+FFF9-FFFB, U+10140-1018E, U+10190-1019C, U+101A0, U+101D0-101FD, U+102E0-102FB, U+10E60-10E7E, U+1D2C0-1D2D3, U+1D2E0-1D37F, U+1F000-1F0FF, U+1F100-1F1AE, U+1F1E6-1F1FF, U+1F30D-1F30F, U+1F315, U+1F31C, U+1F31E, U+1F320-1F32C, U+1F336, U+1F378, U+1F37D, U+1F382, U+1F393-1F39F, U+1F3A7-1F3A8, U+1F3AC-1F3AF, U+1F3C2, U+1F3C4-1F3C6, U+1F3CA-1F3CE, U+1F3D4-1F3E0, U+1F3ED, U+1F3F1-1F3F3, U+1F3F5-1F3F7, U+1F408, U+1F415, U+1F41F, U+1F426, U+1F43F, U+1F441-1F442, U+1F444, U+1F446-1F449, U+1F44C-1F44E, U+1F453, U+1F46A, U+1F47D, U+1F4A3, U+1F4B0, U+1F4B3, U+1F4B9, U+1F4BB, U+1F4BF, U+1F4C8-1F4CB, U+1F4D6, U+1F4DA, U+1F4DF, U+1F4E3-1F4E6, U+1F4EA-1F4ED, U+1F4F7, U+1F4F9-1F4FB, U+1F4FD-1F4FE, U+1F503, U+1F507-1F50B, U+1F50D, U+1F512-1F513, U+1F53E-1F54A, U+1F54F-1F5FA, U+1F610, U+1F650-1F67F, U+1F687, U+1F68D, U+1F691, U+1F694, U+1F698, U+1F6AD, U+1F6B2, U+1F6B9-1F6BA, U+1F6BC, U+1F6C6-1F6CF, U+1F6D3-1F6D7, U+1F6E0-1F6EA, U+1F6F0-1F6F3, U+1F6F7-1F6FC, U+1F700-1F80B, U+1F810-1F847, U+1F850-1F859, U+1F860-1F887, U+1F890-1F8AD, U+1F8B0-1F8BB, U+1F8C0-1F8C1, U+1F8D0-1F8D8, U+1F900-1F90B, U+1F93B, U+1F946, U+1F984, U+1F996, U+1F9E9, U+1FA00-1FA6F, U+1FA70-1FA7C, U+1FA80-1FAC6, U+1FAC8, U+1FACC-1FADD, U+1FADF-1FAEB, U+1FAEF-1FAFA, U+1FB00-1FBFF;
}
/* Onest, latin */
@font-face {
  font-family: "Onest";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/onest-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* IBM Plex Mono, regular, cyrillic */
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local("IBM Plex Mono"), local("IBMPlexMono"), url("fonts/IBMPlexMono-Regular-Cyrillic.woff2") format("woff2");
  unicode-range: U+0400-045F, U+0462-0463, U+046A-046B, U+0472-0475, U+0490-04C2, U+04CF-04D9, U+04DC-04E9, U+04EE-04F9, U+0524-0525;
}
/* IBM Plex Mono, regular, latin-1 */
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local("IBM Plex Mono"), local("IBMPlexMono"), url("fonts/IBMPlexMono-Regular-Latin1.woff2") format("woff2");
  unicode-range: U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}
/* IBM Plex Mono, medium, cyrillic */
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: local("IBM Plex Mono Medm"), local("IBMPlexMono-Medm"), url("fonts/IBMPlexMono-Medium-Cyrillic.woff2") format("woff2");
  unicode-range: U+0400-045F, U+0462-0463, U+046A-046B, U+0472-0475, U+0490-04C2, U+04CF-04D9, U+04DC-04E9, U+04EE-04F9, U+0524-0525;
}
/* IBM Plex Mono, medium, latin-1 */
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: local("IBM Plex Mono Medm"), local("IBMPlexMono-Medm"), url("fonts/IBMPlexMono-Medium-Latin1.woff2") format("woff2");
  unicode-range: U+0020-007E, U+00A0-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, U+2030, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+FB01-FB02;
}

/* ---------- tokens ----------
   The film's colour semantics, with an indigo accent: the accent for what lands on disk and for
   you, red for an independent check, blue for the planner and for participants, green for done.
   Three tones: midnight's values below are the palette every tone draws from; graphite, a second
   set of the same surface values that [data-tone="graphite"] points at; and light, smartandpoint.com's
   white, whose --light-* set [data-tone="light"] points at (both rules after the motion rules).
   Every page ships in light (<html data-tone="light">); the early script sets a stored dark tone.
   A dark tone changes surfaces only: text, accent and roles stay midnight's. Light also changes
   the inks, the accent family, the roles and the menu shadow, and is color-scheme: light.
   - --bg is the opaque base: the canvas, and theme-color.
   - --bg-1 to --bg-4 are translucent panels, so the faint graph behind the page shows through.
   - --bg-0 is a well inside a panel; --bg-pop is opaque, for menus that cover the page.
   - --accent-bg, --check-bg, --plan-bg, --done-bg are a role's tint laid on a panel, so a
     coloured node or step is as dense as a plain one. */

:root {
  --bg: #080d19;
  --bg-0: #04070fb3;
  --bg-1: #0f172ab8;
  --bg-2: #111a2fc4;
  --bg-3: #142036cc;
  --bg-4: #17233ad9;
  --bg-pop: #141f35;
  --dot: #1b2742;
  --line-1: #19233a;
  --graph: #1f2940;
  --line-2: #222e4a;
  --line-3: #34425f;
  --line-4: #46546f;
  --line-5: #5b6884;
  --swatch-midnight: #2b4aa8;
  --swatch-graphite: #5d6470;
  --swatch-light: #ffffff;
  --graphite-bg: #111316;
  --graphite-bg-0: #0a0b0db3;
  --graphite-bg-1: #191c21b8;
  --graphite-bg-2: #1b1f24c4;
  --graphite-bg-3: #1c2025cc;
  --graphite-bg-4: #212529d9;
  --graphite-bg-pop: #1e2228;
  --graphite-dot: #262a31;
  --graphite-line-1: #22262c;
  --graphite-graph: #252930;
  --graphite-line-2: #2b3037;
  --graphite-line-3: #3d434c;
  --graphite-line-4: #4f5660;
  --graphite-line-5: #646b76;
  --graphite-head-bg: #111316d1;
  --graphite-accent-bg: #23243adb;
  --graphite-check-bg: #282024db;
  --graphite-plan-bg: #1d242bdb;
  --graphite-done-bg: #1c2524db;
  --light-bg: #ffffff;
  --light-bg-0: #f5f5f5b3;
  --light-bg-1: #ffffffd9;
  --light-bg-2: #ffffffe0;
  --light-bg-3: #ffffffeb;
  --light-bg-4: #f5f5f5e6;
  --light-bg-pop: #ffffff;
  --light-dot: #e5e5e5;
  --light-line-1: #efefef;
  --light-graph: #e8e8e8;
  --light-line-2: #e5e5e5;
  --light-line-3: #d4d4d4;
  --light-line-4: #a3a3a3;
  --light-line-5: #8f8f8f;
  --light-head-bg: #ffffffd9;
  --light-ink: #262626;
  --light-ink-hi: #171717;
  --light-ink-2: #404040;
  --light-ink-3: #525252;
  --light-ink-4: #5c5c5c;
  --light-ink-5: #666666;
  --light-on-accent: #ffffff;
  --light-accent: #4f46e5;
  --light-accent-soft: #4f46e52b;
  --light-accent-glow: #4f46e53d;
  --light-accent-bg: #eef2ffe6;
  --light-accent-row: #4f46e50c;
  --light-brand: #4f46e5;
  --light-check: #b91c1c;
  --light-check-bg: #fef2f2e6;
  --light-check-glow: #b91c1c33;
  --light-plan: #0369a1;
  --light-plan-bg: #f0f9ffe6;
  --light-plan-line: #38a3d6;
  --light-plan-glow: #0369a133;
  --light-done: #065f46;
  --light-done-bg: #ecfdf5e6;
  --light-done-line: #5fc79a;
  --light-done-glow: #04785733;
  --light-exp: #7a5000;
  --light-exp-line: #d6bf8c;
  --light-epic: #7a5000;
  --light-shade: #17171726;
  --ink: #e6e3d8;
  --ink-hi: #ffffff;
  --ink-2: #c9c6bb;
  --ink-3: #a3a89a;
  --ink-4: #8d9285;
  --ink-5: #7f8578;
  --on-accent: #0b0c0a;
  --accent: #818cf8;
  --accent-soft: #818cf838;
  --accent-glow: #818cf866;
  --accent-bg: #1b2040db;
  --accent-row: #818cf80f;
  --brand: #818cf8;
  --brand-2: #a5b4fc;
  --brand-3: #6366f1;
  --mark-bar: #3d434d;
  --mark-bar-2: #2c3139;
  --check: #ff7a7a;
  --check-bg: #202031db;
  --check-glow: #ff7a7a66;
  --plan: #7cc4ff;
  --plan-bg: #152439db;
  --plan-line: #4f7fa6;
  --plan-glow: #7cc4ff66;
  --done: #7bd88f;
  --done-bg: #152531db;
  --done-line: #2f5a38;
  --done-glow: #7bd88f66;
  --exp: #e9b86a;
  --exp-line: #5c4a2a;
  --epic: #e9c46a;
  --shade: #00000099;
  --player-bg: #080d19;
  --player-bar: #080d19d9;
  --player-fg: #ffffff;
  --player-hover: #ffffff26;
  --head-bg: #080d19d1;
  --font-sans: "Onest", "Inter", system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
  --font-mono: "IBM Plex Mono", "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --gutter: clamp(16px, 4vw, 48px);
  color-scheme: dark;
}

/* ---------- base ---------- */

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 84px; -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--bg); color: var(--ink); font-family: var(--font-sans); font-size: 17px; line-height: 1.6; -webkit-font-smoothing: antialiased; }
a { color: var(--ink); text-decoration-color: var(--line-4); text-underline-offset: 3px; }
a:hover { color: var(--ink-hi); text-decoration-color: var(--accent); }
button { font-family: inherit; cursor: pointer; color: inherit; }
a:focus-visible, button:focus-visible, [tabindex]:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
::selection { background: var(--accent); color: var(--on-accent); }
h1, h2, h3, h4, p, figure, pre, blockquote { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
svg { flex-shrink: 0; }
code { font-family: var(--font-mono); font-size: 0.86em; color: var(--ink-2); background: var(--bg-4); border: 1px solid var(--line-2); border-radius: 3px; padding: 0.05em 0.35em; }
pre { font-family: var(--font-mono); }
table { border-collapse: collapse; width: 100%; }
[hidden] { display: none !important; }
b, strong { font-weight: 600; color: var(--ink-hi); }

.wrap { max-width: 1200px; margin-inline: auto; padding-inline: var(--gutter); }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip-link { position: fixed; top: 10px; left: 10px; z-index: 100; padding: 10px 16px; background: var(--accent); color: var(--on-accent); transform: translateY(-180%); }
.skip-link:focus { transform: translateY(0); }
.icon { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.icon.sm { width: 14px; height: 14px; }
.acc { color: var(--accent); }
.dim { color: var(--ink-4); }
.ok { color: var(--done); }

/* ---------- header ---------- */

.site-header { position: sticky; top: 0; z-index: 30; background: var(--head-bg); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); border-bottom: 1px solid var(--line-2); }
.head-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 64px; }
.brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; color: var(--ink-hi); }
.brand:hover { color: var(--ink-hi); }
.brand .mark { width: 30px; height: 30px; }
.wordmark { font-weight: 650; font-size: 19px; letter-spacing: -0.02em; }
/* the wordmark's dot: a round dot in the brand colour, larger than a full stop, with room after it, and a
   slow ring pulsing out of it. overflow: hidden puts its baseline at its bottom edge, so it sits where a
   full stop would; the "." stays in the text for copying. Reduced motion stops the ring. */
.wordmark .dot { display: inline-block; width: 0.32em; height: 0.32em; margin-right: 0.16em; overflow: hidden; border-radius: 50%; background: var(--brand); color: transparent; vertical-align: baseline; animation: dot-ping 2.4s ease-out infinite; }
@keyframes dot-ping { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--brand) 60%, transparent); } 70%, 100% { box-shadow: 0 0 0 6px transparent; } }
.head-nav { display: flex; align-items: center; gap: 8px; font-family: var(--font-mono); font-size: 14px; }
.head-nav > a { padding: 6px 10px; border-radius: 8px; color: var(--ink-3); text-decoration: none; white-space: nowrap; }
.head-nav > a:hover { background: var(--bg-4); }
.head-nav > a:hover, .head-nav > a[aria-current="page"] { color: var(--ink-hi); }
.head-nav > a[aria-current="page"] { box-shadow: inset 0 -2px 0 var(--accent); }
/* the source: GitHub's mark, then its name, a link like the others in the row; at 760 px and narrower the mark alone */
.gh { display: inline-flex; align-items: center; gap: 8px; min-height: 40px; }
.gh svg { width: 16px; height: 16px; flex: none; }

.lang-switch { position: relative; }
.lang { display: inline-flex; align-items: center; gap: 6px; min-height: 40px; background: transparent; font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.06em; border: 1px solid var(--line-3); border-radius: 999px; padding: 0 10px; color: var(--ink-3); }
.lang:hover, .lang[aria-expanded="true"] { border-color: var(--line-5); color: var(--ink-hi); }
.lang .icon { width: 13px; height: 13px; }
.lang-chev { transition: transform 0.15s; }
.lang[aria-expanded="true"] .lang-chev { transform: rotate(180deg); }
.lang-menu { position: absolute; right: 0; top: calc(100% + 8px); z-index: 40; min-width: 190px; padding: 6px; background: var(--bg-pop); border: 1px solid var(--line-3); border-radius: 12px; box-shadow: 0 24px 48px -16px var(--shade); }
.lang-menu a { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 9px 12px; border-radius: 8px; font-size: 15px; color: var(--ink); text-decoration: none; }
.lang-menu a::after { content: attr(data-lang); font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-5); }
.lang-menu a:hover, .lang-menu a:focus-visible { background: var(--bg-4); outline: none; }
.lang-menu a[aria-current] { color: var(--accent); }

/* the tone switch: three swatches, midnight, graphite and light. It needs the script, and the
   early script in <head> sets data-tones before the first paint, so it never appears late; a page
   ships with data-tone="light" in its markup, so data-tone alone cannot be the gate. */
.tone-switch { display: none; align-items: center; gap: 2px; padding: 3px; min-height: 40px; border: 1px solid var(--line-3); border-radius: 20px; }
:root[data-tones] .tone-switch { display: inline-flex; }
.tone-opt { position: relative; display: grid; place-items: center; width: 30px; height: 30px; padding: 0; border: 0; border-radius: 50%; background: transparent; }
.tone-opt .sw { width: 16px; height: 16px; border-radius: 50%; border: 1px solid var(--line-5); }
.tone-opt .sw-midnight { background: var(--swatch-midnight); }
.tone-opt .sw-graphite { background: var(--swatch-graphite); }
.tone-opt .sw-light { background: var(--swatch-light); }
.tone-opt[aria-pressed="true"] { box-shadow: inset 0 0 0 1.5px var(--accent); }
.tone-opt:hover .sw { border-color: var(--ink-3); }
/* the tone's name: on keyboard focus, and on hover where there is one (a tap would leave it stuck) */
.tone-opt:focus-visible::after { content: attr(aria-label); }
@media (hover: hover) { .tone-opt:hover::after { content: attr(aria-label); } }
.tone-opt::after { position: absolute; top: calc(100% + 8px); left: 50%; transform: translateX(-50%); z-index: 40; padding: 4px 8px; border: 1px solid var(--line-3); border-radius: 8px; background: var(--bg-pop); color: var(--ink); font-size: 12px; white-space: nowrap; pointer-events: none; }

/* ---------- sections ---------- */

.sec { padding: 72px 0; border-top: 1px solid var(--line-1); display: flex; flex-direction: column; gap: 24px; }
/* a wide diagram scrolls inside its own box; it never widens the page */
.sec > *, .hero > *, .mode-box > *, .cols > *, .settings > *, .files > *, .page > * { min-width: 0; }
.section-label { font-family: var(--font-mono); font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--accent); }
h1 { font-size: clamp(38px, 5vw, 64px); line-height: 1.04; font-weight: 600; letter-spacing: -0.03em; text-wrap: balance; color: var(--ink-hi); }
h2 { font-size: clamp(30px, 3.6vw, 46px); line-height: 1.1; font-weight: 600; letter-spacing: -0.02em; text-wrap: balance; color: var(--ink-hi); }
h3 { font-size: clamp(22px, 2.4vw, 28px); line-height: 1.15; font-weight: 600; letter-spacing: -0.01em; color: var(--ink-hi); }
.lede { max-width: 60ch; color: var(--ink-3); }
.more { align-self: flex-start; font-family: var(--font-mono); font-size: 14px; color: var(--ink-3); }
.cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr)); gap: 24px 48px; align-items: center; }

/* ---------- hero ---------- */

.hero { padding: clamp(20px, 3.4vw, 44px) 0 64px; display: grid; grid-template-columns: minmax(0, 1fr); gap: 40px; align-items: start; }

.term { border: 1px solid var(--line-3); background: var(--bg-3); border-radius: 16px; box-shadow: 0 8px 32px -8px var(--accent-soft); }
.cmdline { display: flex; align-items: center; gap: 12px; padding: 14px 14px; }
.cmdline .ps1 { font-family: var(--font-mono); font-size: 0.7em; color: var(--ink-4); white-space: nowrap; }
.cmdtext { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 0.6em; font-size: clamp(17px, 2.2vw, 24px); min-width: 0; flex: 1 1 auto; }
.cmdtext pre { font-weight: 500; color: var(--ink-hi); white-space: pre-wrap; word-break: break-word; }
.copy { width: 44px; height: 44px; flex: none; display: inline-flex; align-items: center; justify-content: center; padding: 0; background: var(--bg-4); border: 1px solid var(--line-3); border-radius: 10px; color: var(--ink-3); transition: border-color 0.15s, color 0.15s; }
.copy:hover { border-color: var(--line-5); color: var(--ink-hi); }
.copy .done-icon { display: none; }
.copy.ok { border-color: var(--done-line); color: var(--done); }
.copy.ok .copy-icon { display: none; }
.copy.ok .done-icon { display: block; }
.ask { display: flex; flex-direction: column; gap: 8px; font-size: 15px; }
.ask-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; font-family: var(--font-mono); font-size: 13px; color: var(--ink-4); }
.ask-head b { font-weight: 500; }
.quote-row { display: flex; align-items: flex-start; gap: 12px; }
.quote-row blockquote { flex: 1 1 auto; min-width: 0; border-left: 2px solid var(--accent); padding: 4px 0 4px 14px; color: var(--ink-2); overflow-wrap: anywhere; }
.note { font-size: 13px; color: var(--ink-5); }

/* ---------- diagrams ---------- */

.diagram { border: 1px solid var(--line-2); border-radius: 16px; background-color: var(--bg-1); background-image: radial-gradient(var(--dot) 1px, transparent 1px); background-size: 18px 18px; padding: clamp(16px, 3vw, 32px); overflow-x: auto; }
.diagram > svg { display: block; margin: 0 auto; height: auto; }
.diagram figcaption { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-4); margin-bottom: 16px; }
.diagram .cap-after { text-transform: none; letter-spacing: 0; margin: 16px 0 0; font-size: 13px; }
svg.dg { font-family: var(--font-mono); font-size: 13px; }
.dg .edge { fill: none; stroke: var(--ink-5); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.dg .edge.chk { stroke: var(--check); stroke-dasharray: 6 6; }
.dg .edge.chk-solid { stroke: var(--check); }
.dg .edge.ok { stroke: var(--done); }
.dg .edge.pln { stroke: var(--plan-line); }
.dg .edge.ret { stroke: var(--ink-4); stroke-dasharray: 6 6; animation: march 1.2s linear infinite; }
@keyframes march { to { stroke-dashoffset: -24; } }
.dg .head { fill: var(--ink-5); }
.dg .head.chk { fill: var(--check); }
.dg .head.ok { fill: var(--done); }
.dg .head.pln { fill: var(--plan-line); }
.dg .head.ret { fill: var(--ink-4); }
.dg .nb { fill: var(--bg-3); stroke: var(--line-4); stroke-width: 1; }
.dg .nb.acc { fill: var(--accent-bg); stroke: var(--accent); }
.dg .nb.chk { fill: var(--check-bg); stroke: var(--check); }
.dg .nb.pln { fill: var(--plan-bg); stroke: var(--plan); }
.dg .nb.ok { fill: var(--done-bg); stroke: var(--done); }
.dg .nb.dash { stroke: var(--line-5); stroke-dasharray: 5 4; }
.dg .t { fill: var(--ink-hi); font-family: var(--font-sans); font-weight: 600; font-size: 15px; }
.dg .t.acc { fill: var(--accent); }
.dg .t.chk { fill: var(--check); }
.dg .t.pln { fill: var(--plan); }
.dg .t.ok { fill: var(--done); }
.dg .s { fill: var(--ink-4); }
.dg .tag { fill: var(--check); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; }
.dg .lbl { fill: var(--ink-4); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; }
.dg .elbl { fill: var(--ink-3); font-size: 13px; }
.dg .elbl.chk { fill: var(--check); }
.dg .elbl.ok { fill: var(--done); }
.dg .elbl.pln { fill: var(--plan); }
.dg .elbl.dim { fill: var(--ink-4); }
.dg .node { cursor: pointer; }
.dg .node:focus-visible { outline: none; }
.dg .node:focus-visible .nb, .dg .node.active .nb { stroke-width: 2.5; }
.dg .node .nb { transition: filter 0.2s; }
.dg .node.pressed .nb { animation: node-press 0.9s ease-out; }
@keyframes node-press { 0% { filter: none; } 30% { filter: drop-shadow(0 0 6px var(--accent-glow)) drop-shadow(0 0 2px var(--accent-glow)); } 100% { filter: none; } }
.dg .node.pressed .nb.chk { animation-name: node-press-chk; }
@keyframes node-press-chk { 30% { filter: drop-shadow(0 0 6px var(--check-glow)); } }
.dg .node.pressed .nb.pln { animation-name: node-press-pln; }
@keyframes node-press-pln { 30% { filter: drop-shadow(0 0 6px var(--plan-glow)); } }
.dg .node.pressed .nb.ok { animation-name: node-press-ok; }
@keyframes node-press-ok { 30% { filter: drop-shadow(0 0 6px var(--done-glow)); } }
.dg .pulse .nb { animation: pulse 5s ease-in-out infinite; }
@keyframes pulse { 0%, 15%, 100% { filter: none; } 5%, 10% { filter: drop-shadow(0 0 5px var(--accent-glow)); } }

.tty { border: 1px solid var(--line-2); border-radius: 12px; background: var(--bg-1); overflow: hidden; font-family: var(--font-mono); min-width: 0; }
.tty figcaption { display: flex; justify-content: space-between; gap: 8px; padding: 8px 14px; border-bottom: 1px solid var(--line-2); font-size: 12px; color: var(--ink-5); }
.tty-body { padding: 14px 16px; font-size: 13px; line-height: 1.8; display: flex; flex-direction: column; color: var(--ink-2); overflow-x: auto; }
.tty-body .you { color: var(--ink-hi); }
.tty-body .ind { padding-left: 18px; }
.tty-body .sub { color: var(--ink); }
.c-acc { color: var(--accent); }
.c-chk { color: var(--check); }
.c-pln { color: var(--plan); }
.c-ok { color: var(--done); }
.c-dim { color: var(--ink-5); }
.c-epic { color: var(--epic); }
.c-hi { color: var(--ink-hi); }

.runs { font-family: var(--font-mono); font-size: 12px; color: var(--ink-4); overflow-wrap: anywhere; }
.band { border: 1px solid var(--line-2); border-radius: 12px; background: var(--bg-0); padding: 14px 16px; font-family: var(--font-mono); font-size: 12px; line-height: 1.75; white-space: pre; overflow-x: auto; color: var(--ink-5); }
.band b { font-weight: 500; }
.band .prompt-box { display: block; margin-top: 8px; border: 1px solid var(--line-3); border-radius: 8px; padding: 4px 10px; color: var(--ink); white-space: pre; }
.later { font-family: var(--font-mono); font-size: 12px; color: var(--ink-5); }
.later code { font-size: 1em; color: var(--ink-3); }

/* ---------- tables, files ---------- */

.table-wrap { overflow-x: auto; border: 1px solid var(--line-2); border-radius: 12px; }
.grid-table { min-width: 720px; font-size: 15px; }
.grid-table th { padding: 12px 16px; border-bottom: 1px solid var(--line-2); font-family: var(--font-mono); font-size: 12px; font-weight: 400; color: var(--ink-4); text-align: left; }
.grid-table td { padding: 14px 16px; border-bottom: 1px solid var(--line-1); color: var(--ink-3); vertical-align: top; }
.grid-table td:first-child { color: var(--ink); font-weight: 500; }
.grid-table td.ex { color: var(--ink-4); }
.grid-table tr:last-child td { border-bottom: 0; }
.grid-table tr.us { background: var(--accent-row); }
.grid-table tr.us td { color: var(--ink-hi); }
.grid-table tr.us td:first-child { color: var(--accent); font-weight: 700; }
.grid-table tr.us td.ex { color: var(--ink-2); }
.files { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr)); gap: 16px; }
.file { border: 1px solid var(--line-2); background: var(--bg-2); border-radius: 12px; min-width: 0; }
.file figcaption { padding: 10px 14px; border-bottom: 1px solid var(--line-2); font-family: var(--font-mono); font-size: 12px; color: var(--ink-4); overflow-wrap: anywhere; }
.file pre { padding: 16px 14px; font-size: 13px; line-height: 1.7; white-space: pre-wrap; color: var(--ink-2); overflow-x: auto; }
.file .fm { color: var(--ink-5); }
.file .k { color: var(--ink-4); }
.file .h { color: var(--accent); }

/* ---------- modes (solo or a team) ---------- */

.tabs { display: flex; flex-wrap: wrap; gap: 8px; font-family: var(--font-mono); }
.tab { font-family: var(--font-mono); font-size: 14px; padding: 10px 16px; min-height: 44px; border-radius: 999px; border: 1px solid var(--line-3); background: transparent; color: var(--ink-2); }
.tab:hover { border-color: var(--line-5); color: var(--ink-hi); }
.tab[aria-selected="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.mode-box { border: 1px solid var(--line-2); border-radius: 16px; background-color: var(--bg-1); background-image: radial-gradient(var(--dot) 1px, transparent 1px); background-size: 18px 18px; padding: clamp(16px, 2.6vw, 32px); display: grid; grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr)); gap: 32px; align-items: center; }
.mode-panel { display: none; flex-direction: column; gap: 10px; }
.mode-panel.active { display: flex; }
.mode-panel h3 { font-size: 24px; }
.mode-panel p { color: var(--ink-3); }
.mode-fig { overflow-x: auto; }
.mode-fig svg { display: block; margin: 0 auto; }
.mode-fig [data-mode] { display: none; }
.modes[data-mode="solo"] .mode-fig [data-mode="solo"],
.modes[data-mode="team"] .mode-fig [data-mode="team"],
.modes[data-mode="teams"] .mode-fig [data-mode="teams"],
.modes[data-mode="agents"] .mode-fig [data-mode="agents"] { display: inline; }
.dg .who { fill: var(--plan-bg); stroke: var(--plan); }
.dg .who-t { fill: var(--plan); font-size: 12px; }

/* ---------- method, proof, questions ---------- */

.outline-btn { align-self: flex-start; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 18px; border: 1px solid var(--line-3); border-radius: 999px; background: var(--bg-pop); color: var(--ink-hi); font-family: var(--font-mono); text-decoration: none; }
.outline-btn:hover { color: var(--ink-hi); border-color: var(--line-5); }
.src { font-family: var(--font-mono); font-size: 12px; color: var(--ink-5); }
.src a { color: var(--ink-4); }

/* ---------- method pages ---------- */

.page-hero { padding: clamp(40px, 6vw, 72px) 0 48px; display: flex; flex-direction: column; gap: 18px; }
.crumb { font-family: var(--font-mono); font-size: 13px; color: var(--ink-4); }
.crumb a { color: var(--ink-3); }
.page-hero .lead { max-width: 62ch; font-size: clamp(17px, 1.6vw, 19px); color: var(--ink-2); }
.prose { max-width: 68ch; display: flex; flex-direction: column; gap: 14px; color: var(--ink-2); }
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr)); gap: 0 32px; counter-reset: step; }
.steps li { padding: 14px 0; border-top: 1px solid var(--line-2); display: grid; grid-template-columns: 36px 1fr; gap: 4px 12px; color: var(--ink-3); font-size: 15px; }
.steps li::before { counter-increment: step; content: counter(step, decimal-leading-zero); font-family: var(--font-mono); font-size: 13px; color: var(--accent); padding-top: 3px; grid-row: span 2; }
.steps li b { font-weight: 600; }
.agents { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 16px; }
.agent { border: 1px solid var(--line-2); background: var(--bg-2); border-radius: 12px; padding: 16px; display: flex; flex-direction: column; gap: 6px; font-size: 15px; color: var(--ink-3); }
.agent .role { font-family: var(--font-mono); font-size: 14px; font-weight: 500; }
.agent .role.chk { color: var(--check); }
.agent .role.pln { color: var(--plan); }
.agent .role.acc { color: var(--accent); }
.agent .role.ok { color: var(--done); }
.agent .rw { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-5); }
.mechs { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr)); gap: 16px; }
.mech { border-left: 2px solid var(--accent); padding: 4px 0 4px 16px; display: flex; flex-direction: column; gap: 6px; color: var(--ink-3); font-size: 15px; }
.mech h3 { font-size: 18px; letter-spacing: 0; }
.fine { display: flex; flex-direction: column; gap: 8px; font-size: 14px; color: var(--ink-4); max-width: 76ch; }
.fine li::before { content: "— "; color: var(--ink-5); }
.timeline { position: relative; display: flex; flex-direction: column; gap: 0; padding-left: 28px; }
.timeline::before { content: ""; position: absolute; left: 7px; top: 8px; bottom: 8px; border-left: 2px dashed var(--line-3); }
.timeline li { position: relative; padding: 10px 0 16px; display: grid; grid-template-columns: 72px 1fr; gap: 4px 16px; color: var(--ink-3); font-size: 15px; }
.timeline li::before { content: ""; position: absolute; left: -27px; top: 15px; width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--accent); background: var(--bg); }
.timeline .yr { font-family: var(--font-mono); font-size: 14px; color: var(--accent); }
.timeline li.now::before { background: var(--done); border-color: var(--done); box-shadow: 0 0 0 6px var(--done-line); animation: ping 2.4s ease-out infinite; }
.timeline li.now .yr { color: var(--done); }
@keyframes ping { 0% { box-shadow: 0 0 0 0 var(--done-glow); } 70%, 100% { box-shadow: 0 0 0 12px transparent; } }
.equation { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; font-family: var(--font-mono); font-size: clamp(16px, 2vw, 20px); color: var(--ink-3); }
.equation .term-pill { border: 1px solid var(--line-3); border-radius: 999px; padding: 6px 14px; color: var(--ink); }
.equation .term-pill.acc { border-color: var(--accent); color: var(--accent); }
.transcript { border: 1px solid var(--line-2); border-radius: 12px; background: var(--bg-0); padding: 14px 16px; font-size: 12.5px; line-height: 1.7; white-space: pre-wrap; color: var(--ink-3); overflow-x: auto; }
.setup { position: relative; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); gap: 16px; }
.setup li { border: 1px solid var(--line-2); background: var(--bg-2); border-radius: 10px; padding: 16px; display: flex; flex-direction: column; gap: 6px; color: var(--ink-3); font-size: 15px; }
.setup .n { font-family: var(--font-mono); font-size: 12px; color: var(--accent); }
.setup h3, .setup h4 { color: var(--ink-hi); font-size: 17px; font-weight: 600; letter-spacing: 0; }
.next-pages { display: flex; flex-wrap: wrap; gap: 12px 28px; font-family: var(--font-mono); font-size: 14px; }

/* ---------- the loop and its lines ---------- */

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.mk path { fill: var(--ink-5); }
.mk.chk path { fill: var(--check); }
.mk.ok path { fill: var(--done); }
.mk.pln path { fill: var(--plan-line); }
.mk.ret path { fill: var(--ink-4); }
.diagram > svg { width: 100%; min-width: 860px; }
.mode-fig svg { width: 100%; min-width: 400px; max-width: 480px; height: auto; }
.step-lines { margin-top: 14px; display: flex; flex-direction: column; gap: 6px; font-size: 15px; color: var(--ink-3); }
.step-lines li { display: grid; grid-template-columns: 34px 1fr; }
.step-lines b { font-family: var(--font-mono); font-size: 13px; font-weight: 500; color: var(--accent); padding-top: 2px; }
.loop.js .step-lines { min-height: 3.4em; }
/* where the cartoon runs, the line under the diagram has one fixed height, so nothing below it moves */
@media (min-width: 900px) { .loop.js .step-lines { height: 3.4em; min-height: 0; overflow: hidden; } }

/* ---------- small pieces ---------- */

.tty-body > span { display: block; }
.file-note { padding: 10px 14px; border-top: 1px solid var(--line-2); font-size: 13px; color: var(--ink-5); }
pre.later, pre.runs { white-space: pre-wrap; overflow-wrap: anywhere; color: var(--ink-3); }
.later-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; font-family: var(--font-mono); font-size: 13px; color: var(--ink-5); }
.later-row pre { color: var(--ink-2); }
.wordmark-sm { color: var(--ink-3); font-weight: 600; }
.wordmark-sm .dot { color: var(--brand); }
.foot-links { display: flex; flex-wrap: wrap; gap: 14px; }
body[data-page="how-it-works"] [data-nav="how-it-works"],
body[data-page="why-it-works"] [data-nav="why-it-works"],
body[data-page="one-vault"] [data-nav="one-vault"],
body[data-page="main"] .mobile-nav [data-nav="main"] { color: var(--ink-hi); box-shadow: inset 0 -2px 0 var(--accent); }

/* ---------- the quiet close: the prompt to paste into Claude Code ---------- */

.ask-end { margin-top: 8px; padding-top: 24px; border-top: 1px solid var(--line-2); max-width: 760px; }
.ask-end .ask-head { font-size: 14px; color: var(--ink-3); }
.ask-end blockquote { font-size: 17px; }

/* ---------- the main page: what it is, how to start, and the method pages' own blocks ----------
   PS-HARNESS "The front page says what ProjectStore is …": the top says what it is and how it helps, then
   installation for a beginner, then How it works whole and digests of One vault and Why it works, in those
   pages' own markup. Colour stays in the diagrams and the loop picture; the rest is ink on the tone. */

/* what it is: the heading across the page, the text and the pain rows side by side, the comparison under both */
.hero.what { grid-template-columns: repeat(auto-fit, minmax(min(440px, 100%), 1fr)); gap: 24px clamp(28px, 4vw, 56px); padding-bottom: 56px; }
.hero.what > .section-label, .hero.what > h1, .cmp-box { grid-column: 1 / -1; }
.what-text, .what-side, .cmp-box { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.what-side { gap: 12px; }
.what-text .lead { max-width: 62ch; font-size: clamp(17px, 1.6vw, 19px); color: var(--ink-2); }

/* the comparison: three approaches feed ProjectStore. The drawing lives in the first cell's left padding, drawn by
   pseudo-elements, so the table keeps five columns and a screen reader meets no extra cell */
.cmp-box { gap: 14px; margin-top: 16px; padding-top: 32px; border-top: 1px solid var(--line-2); }
.cmp { min-width: 920px; }
.cmp td:first-child { position: relative; width: 15%; padding-left: 44px; }
.cmp td:first-child small { display: block; font-family: var(--font-mono); font-size: 12px; font-weight: 400; color: var(--ink-4); }
.cmp tr.from td:first-child::before { content: ""; position: absolute; left: 18px; top: 0; bottom: -1px; width: 2px; background: var(--line-5); }
.cmp tr.from:first-child td:first-child::before { top: 25px; }
.cmp tr.from td:first-child::after { content: ""; position: absolute; left: 18px; top: 25px; width: 20px; height: 2px; background: var(--line-5); }
.cmp tr.us td:first-child::before { content: ""; position: absolute; box-sizing: border-box; left: 18px; top: 0; width: 16px; height: 27px; border-left: 2px solid var(--accent); border-bottom: 2px solid var(--accent); border-bottom-left-radius: 8px; }
.cmp tr.us td:first-child::after { content: ""; position: absolute; left: 32px; top: 20px; border-style: solid; border-width: 6px 0 6px 8px; border-color: transparent transparent transparent var(--accent); }
.cmp-sum { max-width: 70ch; color: var(--ink-3); }

/* a chapter head: a method page's own heading and lead, set as an h2 at the h1's size so the page keeps one h1 */
.sec.chapter { gap: 18px; padding-bottom: 48px; }
.chapter h2 { font-size: clamp(38px, 5vw, 64px); line-height: 1.04; letter-spacing: -0.03em; }
.chapter .lead { max-width: 62ch; font-size: clamp(17px, 1.6vw, 19px); color: var(--ink-2); }
/* the loop diagram belongs to its chapter head: no rule and no gap above it */
.sec.joined { border-top: 0; padding-top: 0; }

/* the loop player's play and pause icon */
.pause-bars { width: 10px; height: 11px; border-left: 3px solid currentColor; border-right: 3px solid currentColor; }
[aria-pressed="true"] > .pause-bars { width: 0; height: 0; border-style: solid; border-width: 6px 0 6px 10px; border-color: transparent transparent transparent currentColor; margin-left: 2px; }

/* install: "Ask your agent" is drawn as a chat box in a desktop app, "Terminal" as a terminal */
.install { border: 1px solid var(--line-3); border-radius: 16px; background: var(--bg-3); overflow: hidden; box-shadow: 0 8px 32px -8px var(--accent-soft); }
.install-bar { display: flex; align-items: flex-end; gap: 14px; padding: 0 12px; border-bottom: 1px solid var(--line-2); }
.install-dots { display: inline-flex; gap: 6px; align-self: center; }
.install-dots i { width: 10px; height: 10px; border-radius: 50%; background: var(--line-3); }
.install-tabs { display: flex; gap: 2px; }
.install-tab { font-family: var(--font-mono); font-size: 13px; color: var(--ink-4); background: transparent; border: 0; border-bottom: 2px solid transparent; padding: 11px 10px 9px; }
.install-tab:hover { color: var(--ink-hi); }
.install-tab[aria-selected="true"] { color: var(--ink-hi); border-bottom-color: var(--accent); }
/* without script both ways show; with it, the tab chosen */
.install[data-mode] .install-panel:not(.active) { display: none; }
.chatbox { margin: 12px; padding: 14px 14px 10px 16px; border: 1px solid var(--line-3); border-radius: 16px; background: var(--bg-4); display: flex; flex-direction: column; gap: 10px; }
.chatbox blockquote { font-size: 16px; line-height: 1.55; color: var(--ink); overflow-wrap: anywhere; }
.chatbox-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.chatbox-note { font-size: 13px; color: var(--ink-4); }
.termbox { background: var(--bg-0); border-top: 1px solid var(--line-2); }
.install[data-mode] .termbox { border-top: 0; }
.termbox .cmdtext { font-size: 17px; }
.termbox .ps1 { font-size: 0.78em; }
.agents-line { font-size: 15px; color: var(--ink-3); }
.agents-line b { font-weight: 500; color: var(--ink-2); }
.actions { display: flex; flex-wrap: wrap; gap: 12px; }
.btn { display: inline-flex; align-items: center; min-height: 44px; padding: 0 22px; border-radius: 999px; border: 1px solid var(--line-3); background: var(--bg-pop); color: var(--ink-hi); font-weight: 600; font-size: 15px; text-decoration: none; }
.btn:hover { color: var(--ink-hi); border-color: var(--line-5); }
/* the main button: filled with the strongest ink and lettered in the page's base, as smartandpoint.com's is */
.btn.primary { background: var(--ink-hi); border-color: var(--ink-hi); color: var(--bg); }
.btn.primary:hover { color: var(--bg); box-shadow: 0 0 0 4px var(--accent-soft); }

/* sound familiar? a pain, then what ProjectStore does about it */
.pain-list { border-top: 1px solid var(--line-2); }
.pain { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 24px; padding: 16px 0; border-bottom: 1px solid var(--line-2); }
.pain .was { font-size: 17px; font-weight: 500; color: var(--ink-hi); }
.pain .now { font-size: 16px; color: var(--ink-2); }
.pain .arr { color: var(--done); font-weight: 600; }
.pain:last-child { border-bottom: 0; }

/* the loop: the marketing loop's dark terminal dashboard in a player (site.js), the same in every tone; the
   caption follows the tone. The loop's own page plays in a frame over its still, and a bar of controls runs
   along its bottom; the picture is always dark, so the player's colours are its own tokens. The bar shows
   while paused, on hover, on focus, and for a moment after a tap or a move. In full screen, or filling the
   window where an element cannot go full screen, the picture keeps 16:9 on black. */
.loopfig { display: flex; flex-direction: column; gap: 12px; }
.loopfig figcaption { font-family: var(--font-mono); font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--accent); }
.player { position: relative; border: 1px solid var(--line-3); border-radius: 16px; overflow: hidden; background: var(--player-bg); touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.player-poster { display: block; width: 100%; height: auto; }
.player-frame { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; pointer-events: none; opacity: 0; transition: opacity 0.3s; }
.player.ready { cursor: pointer; }
.player.ready .player-frame { opacity: 1; }
.player-bar { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; gap: 10px; padding: 6px 10px; background: var(--player-bar); color: var(--player-fg); font-family: var(--font-mono); font-size: 12px; opacity: 0; pointer-events: none; transition: opacity 0.2s; }
/* a hidden bar takes no taps, so a tap anywhere on the playing picture pauses it */
.player.paused .player-bar, .player.show .player-bar, .player:focus-within .player-bar { opacity: 1; pointer-events: auto; }
@media (hover: hover) { .player:hover .player-bar { opacity: 1; pointer-events: auto; } }
.player-bar button { width: 36px; height: 36px; flex: none; display: inline-grid; place-items: center; padding: 0; border: 0; border-radius: 50%; background: transparent; color: inherit; }
.player-bar button:hover { background: var(--player-hover); }
.player-seek { flex: 1 1 auto; min-width: 0; margin: 0; accent-color: var(--accent); cursor: pointer; }
.player-time { flex: none; font-variant-numeric: tabular-nums; }
.player-full .icon { width: 18px; height: 18px; }
.player-full[aria-pressed="true"] .on-off, .player-full[aria-pressed="false"] .on-on { display: none; }
.player.full { border: 0; border-radius: 0; }
.player.full .player-poster, .player.full .player-frame { position: absolute; inset: 0; margin: auto; width: min(100%, 177.78vh); width: min(100%, 177.78dvh); height: auto; aspect-ratio: 16 / 9; }
.player.filled { position: fixed; inset: 0; z-index: 100; }
:root.player-open { overflow: hidden; }

/* what you can do: a verb, what you say, what happens */
.tasks { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.task { border: 1px solid var(--line-2); border-radius: 16px; background: var(--bg-2); padding: 20px 22px; display: flex; flex-direction: column; gap: 12px; }
.task h3 { font-size: 19px; line-height: 1.3; letter-spacing: 0; }
.task p { font-size: 15px; color: var(--ink-3); }
.say { font-family: var(--font-mono); font-size: 14px; line-height: 1.5; color: var(--ink-hi) !important; background: var(--bg-0); border: 1px solid var(--line-2); border-radius: 10px; padding: 10px 14px; }
.say::before { content: "› "; color: var(--accent); }
.trust { display: flex; flex-wrap: wrap; gap: 10px 28px; }
.trust li { display: inline-flex; align-items: center; gap: 8px; font-size: 15px; color: var(--ink-2); }
.trust .icon { color: var(--done); }
.trust .agents-line { font-size: 15px; }
.proof { border-left: 3px solid var(--accent); padding: 4px 0 4px 16px; display: flex; flex-direction: column; gap: 4px; }
.proof b { font-size: 15px; }
.proof p { font-size: 15px; color: var(--ink-3); }

/* quick start: four numbered steps, the third a real exchange */
.qs { counter-reset: qs; display: flex; flex-direction: column; gap: 26px; max-width: 840px; }
.qs > li { counter-increment: qs; display: grid; grid-template-columns: 34px minmax(0, 1fr); gap: 8px 16px; }
.qs > li::before { content: counter(qs); grid-row: span 6; width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--accent); background: var(--accent-bg); color: var(--accent); display: grid; place-items: center; font-family: var(--font-mono); font-size: 13px; font-weight: 500; }
.qs h3 { font-size: 18px; line-height: 1.65; letter-spacing: 0; }
.qs p { color: var(--ink-3); }
.tr { font-size: 14px; color: var(--ink-4) !important; }
.tr:empty { display: none; }
.chat { border: 1px solid var(--line-2); border-radius: 12px; background: var(--bg-1); padding: 16px 18px; display: flex; flex-direction: column; gap: 10px; }
.chat-agent { font-family: var(--font-mono); font-size: 14px; line-height: 1.6; color: var(--ink) !important; }
.chat-agent::before { content: "⏺ "; color: var(--ink-4); }
.choice { border-left: 2px solid var(--accent); padding-left: 14px; display: flex; flex-direction: column; gap: 6px; }
.choice-q { font-weight: 500; color: var(--ink-hi) !important; }
.choice ol { list-style: decimal; padding-left: 22px; display: flex; flex-direction: column; gap: 4px; font-family: var(--font-mono); font-size: 14px; color: var(--ink-2); }
.choice li:first-child { color: var(--accent); }
.choice li span { color: var(--ink-4); }

/* free and open source */
.closing { border: 1px solid var(--line-2); border-radius: 16px; background: var(--bg-2); padding: 28px; display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
.closing p { color: var(--ink-3); }

@media (max-width: 760px) {
  .pain { grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .tasks { grid-template-columns: minmax(0, 1fr); }
  .closing { padding: 20px; }
}

/* ---------- method pages: pieces ---------- */

.page { padding-bottom: 24px; }
.page .sec { padding: 56px 0; }
.plain-code { padding: 16px 14px; font-size: 13px; line-height: 1.7; white-space: pre-wrap; overflow-wrap: anywhere; color: var(--ink-2); }
.tools { display: flex; flex-wrap: wrap; gap: 8px; font-family: var(--font-mono); font-size: 13px; }
.tools li { border: 1px solid var(--line-3); border-radius: 8px; padding: 3px 9px; color: var(--ink-2); }
.agent p { color: var(--ink-3); }
.agent p.c-hi { color: var(--ink); }
.rules-list { display: flex; flex-direction: column; gap: 10px; }
.rules-list li { border-left: 2px solid var(--plan-line); padding-left: 14px; color: var(--ink-3); }
.rules-list strong { color: var(--ink-hi); }
.wide-panel { margin-top: 8px; }
.wide-panel .tty { align-self: start; }
.stages td small { display: block; font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-5); font-weight: 400; }
.stages td.ps { color: var(--ink); }
.stages td b { color: var(--ink-hi); }
.chain { display: flex; flex-direction: column; max-width: 720px; }
.chain li { display: grid; grid-template-columns: 76px 1fr; gap: 0 16px; }
.chain .ch-k { grid-row: span 2; font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent); padding-top: 14px; text-align: right; }
.chain .ch-c { border: 1px solid var(--line-3); background: var(--bg-2); border-radius: 10px; padding: 10px 14px; display: flex; flex-wrap: wrap; gap: 4px 12px; align-items: baseline; color: var(--ink-3); font-size: 15px; }
.chain .ch-c b { color: var(--ink-hi); }
.chain .ch-f { position: relative; margin-left: 24px; padding: 8px 0 8px 20px; border-left: 2px dashed var(--line-4); font-family: var(--font-mono); font-size: 12px; color: var(--ink-4); }
.chain li.ok .ch-c { border-color: var(--done); background: var(--done-bg); }
.chain li.ok .ch-c b, .chain li.ok .ch-k { color: var(--done); }
.dg .d { fill: var(--ink-hi); font-weight: 500; }

/* ---------- footer ---------- */

.site-footer { border-top: 1px solid var(--line-2); }
.foot-row { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px; padding-block: 20px; font-family: var(--font-mono); font-size: 13px; color: var(--ink-5); }
.foot-row a { color: var(--ink-4); }

/* ---------- Chinese ---------- */

html:lang(zh-CN) {
  --font-sans: "Onest", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", "Source Han Sans SC", system-ui, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, "PingFang SC", "Microsoft YaHei", "Noto Sans SC", monospace;
}
html:lang(zh-CN) :is(h1, h2, h3, h4) { letter-spacing: 0; }
html:lang(zh-CN) h1 { line-height: 1.12; }
html:lang(zh-CN) :is(.section-label, .step-name, .lbl) { letter-spacing: 0.02em; }

/* ---------- small screens ---------- */

@media (max-width: 760px) {
  .head-nav { gap: 8px; }
  .tone-switch { gap: 0; padding: 2px; min-height: 36px; }
  .lang-chev { display: none; }
  .tone-opt { width: 26px; height: 26px; }
  .gh { min-width: 32px; justify-content: center; }
  .gh span { display: none; }
  .head-row { min-height: 56px; gap: 12px; }
  .sec { padding: 56px 0; }
  .hero { padding-top: 28px; gap: 32px; }
  .cmdline { padding: 14px 12px; gap: 8px; }
}
/* the smallest phones (360 to 400 px): the header row tightens so it still ends inside the gutter */
@media (max-width: 400px) {
  .head-row { gap: 8px; }
  .head-nav { gap: 6px; }
  .brand { gap: 8px; }
  .wordmark { font-size: 16px; }
  .tone-opt { width: 24px; height: 24px; }
}
/* below the page's full width the page links move to a second row: the longest languages (de, fr) need all of it,
   and the header row never wraps or overflows */
.mobile-nav { display: none; }
@media (max-width: 1199px) {
  html { scroll-padding-top: 116px; }
  .head-nav > a.page-link { display: none; }
  .mobile-nav { display: flex; gap: 18px; overflow-x: auto; padding: 8px var(--gutter); border-top: 1px solid var(--line-1); font-family: var(--font-mono); font-size: 13px; white-space: nowrap; }
  .mobile-nav a { color: var(--ink-3); text-decoration: none; }
  .mobile-nav a[aria-current="page"] { color: var(--ink-hi); }
}

/* ---------- motion ---------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .graph line { stroke-dashoffset: 0 !important; }
  .graph .node { opacity: 1 !important; transform: none !important; }
  .graph .beacon { opacity: 0 !important; }
  .graph-rings { display: none !important; }
}

/* the graph behind the page (site.js builds it): fixed and under the content, taking no
   pointer. The lines are one colour per tone, --graph, as light as the readability test allows: it counts
   them as a surface text may sit on. A line draws over its length (--len) as its progress (--p) grows, and
   pulses once (.fresh) when the scroll draws it.
   The nodes are lit beyond those floors, by the maintainer's decision, within bounds the test reads: a
   node (--node) with a soft halo; while a line heads for it, it shows at up to 2.2x and its beacon, a
   --line-5 disc at up to 0.55, at up to 4.5x, both shrinking to the point as the line arrives; a ring
   breathes out of each reached node (.graph-rings, HTML, so transform and opacity cost no layout per
   frame, as they would in SVG); a node pings once when the scroll reaches it. The graph is a slice of
   this project's own vault, each node labelled with its number and slug in small mono in its node's
   grey, shown as its node shows; site.js drops a label that would cover one shown before it or another
   node, and at 900 px and narrower none shows, since every label would lie under the text. Forced
   colours would turn it to full contrast behind the text. */
.graph { position: fixed; inset: 0; width: 100%; height: 100lvh; z-index: -1; pointer-events: none; color: var(--graph); --node: var(--line-4); }
/* the maintainer's call of 2026-10-22: the whole graph barely shows, so its nodes and lines never compete with
   the text, and it sinks almost out of sight while the page scrolls (site.js sets .scrolling) */
.graph, .graph-rings { opacity: 0.3; transition: opacity 0.6s ease; }
:root.scrolling .graph, :root.scrolling .graph-rings { opacity: 0.1; transition-duration: 0.2s; }
.graph line { stroke: currentColor; stroke-width: 1; stroke-dasharray: var(--len); stroke-dashoffset: calc(var(--len) * (1 - var(--p, 1))); }
.graph line.fresh { animation: graph-pulse 1.4s ease-out; }
.graph circle { transform-box: fill-box; transform-origin: center; }
.graph .node { fill: var(--node); stroke: var(--line-5); stroke-width: 3; stroke-opacity: 0.3; opacity: min(calc(var(--p, 1) * 1000), 1); transform: scale(calc(1 + (1 - var(--p, 1)) * 1.2)); }
.graph .node.ping { animation: graph-ping 1.6s ease-out; }
.graph .label { fill: var(--node); font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.06em; opacity: min(calc(var(--p, 1) * 1000), 1); }
.graph .label.off { display: none; } /* site.js: it would cover a label shown before it, or another node */
@media (max-width: 900px) { .graph .label { display: none; } } /* on a narrow screen every label lies under the text */
.graph .beacon { fill: var(--line-5); opacity: calc(min(var(--p, 0) * 1000, 1) * (1 - var(--p, 0)) * 0.55); transform: scale(calc(1 + (1 - var(--p, 0)) * 3.5)); }
.graph-rings { position: fixed; inset: 0; height: 100lvh; z-index: -1; pointer-events: none; }
.graph-rings .ring { display: none; position: absolute; left: var(--x); top: var(--y); width: 8px; height: 8px; margin: -4px 0 0 -4px; border: 1.5px solid var(--line-5); border-radius: 50%; opacity: 0; }
.graph-rings .ring.on { display: block; animation: graph-ring 4.2s ease-out infinite; }
.graph-rings .ring:nth-child(3n) { animation-delay: -1.4s; }
.graph-rings .ring:nth-child(3n + 1) { animation-delay: -2.8s; }
@keyframes graph-ring { 0% { transform: scale(1); opacity: 0.9; } 45%, 100% { transform: scale(4); opacity: 0; } }
@keyframes graph-ping { 0% { stroke-width: 3; stroke-opacity: 1; } 100% { stroke-width: 34; stroke-opacity: 0; } }
@keyframes graph-pulse { 0%, 30% { stroke: var(--line-5); stroke-width: 3; } 100% { stroke: currentColor; stroke-width: 1; } }
/* forced colours: no graph; the wordmark's dot is its "." again, which a forced background would hide */
@media (forced-colors: active) {
  .graph { display: none; }
  .graph-rings { display: none; }
  .wordmark .dot { width: auto; height: auto; overflow: visible; margin-right: 0; border-radius: 0; background: none; color: inherit; animation: none; }
}

/* ---------- the graphite and light tones ----------
   Screen only: in print the palette below is replaced. There is no glow behind the page (2026-10-22: no
   gradients); the tone rules point the surface tokens, and light the inks too, at their sets. */

@media screen {
  :root[data-tone="graphite"] {
    --bg: var(--graphite-bg); --bg-0: var(--graphite-bg-0); --bg-1: var(--graphite-bg-1); --bg-2: var(--graphite-bg-2);
    --bg-3: var(--graphite-bg-3); --bg-4: var(--graphite-bg-4); --bg-pop: var(--graphite-bg-pop); --dot: var(--graphite-dot);
    --graph: var(--graphite-graph);
    --line-1: var(--graphite-line-1); --line-2: var(--graphite-line-2); --line-3: var(--graphite-line-3);
    --line-4: var(--graphite-line-4); --line-5: var(--graphite-line-5);
    --head-bg: var(--graphite-head-bg);
    --accent-bg: var(--graphite-accent-bg); --check-bg: var(--graphite-check-bg); --plan-bg: var(--graphite-plan-bg); --done-bg: var(--graphite-done-bg);
  }
  :root[data-tone="light"] {
    color-scheme: light;
    --bg: var(--light-bg); --bg-0: var(--light-bg-0); --bg-1: var(--light-bg-1); --bg-2: var(--light-bg-2);
    --bg-3: var(--light-bg-3); --bg-4: var(--light-bg-4); --bg-pop: var(--light-bg-pop); --dot: var(--light-dot);
    --graph: var(--light-graph);
    --line-1: var(--light-line-1); --line-2: var(--light-line-2); --line-3: var(--light-line-3);
    --line-4: var(--light-line-4); --line-5: var(--light-line-5);
    --head-bg: var(--light-head-bg);
    --ink: var(--light-ink); --ink-hi: var(--light-ink-hi); --ink-2: var(--light-ink-2); --ink-3: var(--light-ink-3);
    --ink-4: var(--light-ink-4); --ink-5: var(--light-ink-5);
    --on-accent: var(--light-on-accent); --accent: var(--light-accent); --accent-soft: var(--light-accent-soft);
    --accent-glow: var(--light-accent-glow); --accent-bg: var(--light-accent-bg); --accent-row: var(--light-accent-row);
    --brand: var(--light-brand);
    --check: var(--light-check); --check-bg: var(--light-check-bg); --check-glow: var(--light-check-glow);
    --plan: var(--light-plan); --plan-bg: var(--light-plan-bg); --plan-line: var(--light-plan-line); --plan-glow: var(--light-plan-glow);
    --done: var(--light-done); --done-bg: var(--light-done-bg); --done-line: var(--light-done-line); --done-glow: var(--light-done-glow);
    --exp: var(--light-exp); --exp-line: var(--light-exp-line); --epic: var(--light-epic);
    --shade: var(--light-shade);
  }
}

/* ---------- print: dark text on white ---------- */

@media print {
  :root {
    --bg: #ffffff; --bg-0: #ffffff; --bg-pop: #ffffff; --bg-1: #ffffff; --bg-2: #ffffff; --bg-3: #ffffff; --bg-4: #ffffff; --dot: #ffffff;
    --line-1: #dddddd; --line-2: #cccccc; --line-3: #bbbbbb; --line-4: #999999; --line-5: #888888;
    --ink: #111111; --ink-hi: #000000; --ink-2: #222222; --ink-3: #333333; --ink-4: #555555; --ink-5: #666666;
    --accent: #4338ca; --accent-soft: #e0e7ff; --accent-bg: #ffffff; --accent-row: #f5f5f5; --brand: #4338ca;
    --check: #b42318; --check-bg: #ffffff; --plan: #175cd3; --plan-bg: #ffffff; --plan-line: #175cd3;
    --done: #067647; --done-bg: #ffffff; --done-line: #067647; --exp: #8a5a00; --exp-line: #8a5a00; --epic: #8a5a00;
    color-scheme: light;
  }
  .site-header, .mobile-nav, .copy, .lang-switch, .tone-switch, .tabs, .skip-link, .player-bar, .player-frame { display: none !important; }
  .mode-panel { display: flex !important; }
  .term { box-shadow: none; }
  .graph { display: none; }
  .graph-rings { display: none; }
  .sec, .file, .diagram, .tty, .task, .pain, .loopfig { break-inside: avoid; }
  a { text-decoration: underline; }
}
