/* ============================================================
   AI++ — ai-plusplus.com
   Single stylesheet · All colors in :root · Mobile-first
   Breakpoints: <600px (mobile), 600–960px (tablet portrait), 961px+ (desktop)

   Palette derived from the logo mark:
     light logo  #556AAE (indigo) on warm paper
     dark  logo  #eae7df / #9a9690 on warm near-black
   Type: IBM Plex Sans (body) + JetBrains Mono (labels, data, diagnostics)
   ============================================================ */

/* ── Custom properties · light (default) ───────────────────── */
:root {
  --paper:        #f7f6f2;
  --surface:      #fffefb;
  --sunken:       #efede6;
  --ink:          #1b1a17;
  --ink-2:        #3f3d38;
  --muted:        #6b675f;
  --faint:        #96918a;
  --line:         #ddd9cf;
  --line-soft:    #e8e5dc;

  --accent:       #556aae;
  --accent-deep:  #3f5290;
  --accent-wash:  #eceff8;

  /* Call-to-action, deliberately deeper than --accent: the accent is tuned for
     text and rules on paper, where it only needs to read AGAINST the page. A
     filled button has to carry white text ON it, which is a different job.
     #556aae/white is 5.17:1 — legal, but thin at button sizes. */
  --cta:          #3f5290;   /* 7.44:1 on white — AAA */
  --cta-hover:    #334372;   /* 9.60:1 */
  --cta-ink:      #ffffff;

  --pass:         #2f6d4f;
  --fail:         #a4442e;
  --wait:         #8a6d1f;

  --shadow-sm:    0 1px 2px rgba(27,26,23,.05);
  --shadow:       0 1px 2px rgba(27,26,23,.05), 0 12px 32px -20px rgba(27,26,23,.28);

  --wide:         1080px;
  --read:         42rem;

  --font-body:    'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --logo-light:   block;
  --logo-dark:    none;
}

/* ── Custom properties · dark ──────────────────────────────── */
@media (prefers-color-scheme: dark) {
  :root {
    --paper:       #151412;
    --surface:     #1d1c19;
    --sunken:      #232120;
    --ink:         #eae7df;
    --ink-2:       #c4bfb4;
    --muted:       #9a9690;
    --faint:       #7c786f;
    --line:        #34312c;
    --line-soft:   #292724;

    --accent:      #8fa2dc;
    --accent-deep: #a9b8e6;
    --accent-wash: #21242f;

    /* Dark mode inverts the problem. The accent is LIGHT here, so white-on-it
       was 2.51:1 — below every threshold, including large text. A deep button
       is not the answer either: #3f5290 against this page is 2.39:1, so the
       button would vanish. The light button keeps dark ink. */
    --cta:         #8fa2dc;   /* 6.94:1 with the ink below */
    --cta-hover:   #a9b8e6;   /* 8.86:1 */
    --cta-ink:     #171a21;

    --pass:        #63b083;
    --fail:        #d9836b;
    --wait:        #cbab52;

    --shadow-sm:   0 1px 2px rgba(0,0,0,.4);
    --shadow:      0 1px 2px rgba(0,0,0,.4), 0 12px 32px -20px rgba(0,0,0,.8);

    --logo-light:  none;
    --logo-dark:   block;
  }
}

/* ── Reset & base ──────────────────────────────────────────── */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scrollbar-gutter: stable;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink-2);
  background: var(--paper);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

img, svg { max-width: 100%; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }
a:focus-visible, button:focus-visible, summary:focus-visible, input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

strong { color: var(--ink); font-weight: 600; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--accent); color: #fff; padding: .6rem 1rem;
  font-family: var(--font-mono); font-size: .8rem;
}
.skip-link:focus { left: 0; }

/* ── Layout shells ─────────────────────────────────────────── */
.wide  { width: 100%; max-width: var(--wide); margin: 0 auto; padding: 0 1.25rem; }
.read  { width: 100%; max-width: var(--read);  margin: 0 auto; padding: 0 1.25rem; }

@media (min-width: 600px) { .wide, .read { padding: 0 2rem; } }
@media (min-width: 961px) { .wide, .read { padding: 0 2.5rem; } }

main { flex: 1 0 auto; }

.band { padding: 3rem 0; }
.band + .band { border-top: 1px solid var(--line-soft); }
.band-sunken { background: var(--sunken); }
@media (min-width: 600px) { .band { padding: 4rem 0; } }
@media (min-width: 961px) { .band { padding: 5.5rem 0; } }

/* ── Header / nav ──────────────────────────────────────────── */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: saturate(180%) blur(8px);
  border-bottom: 1px solid var(--line-soft);
}
.header-inner {
  max-width: var(--wide); margin: 0 auto; padding: .7rem 1.25rem;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
@media (min-width: 600px) { .header-inner { padding: .8rem 2rem; } }
@media (min-width: 961px) { .header-inner { padding: .9rem 2.5rem; } }

.site-logo { display: block; line-height: 0; }
.site-logo img { height: 26px; width: auto; }
.logo-light { display: var(--logo-light); }
.logo-dark  { display: var(--logo-dark); }
@media (min-width: 600px) { .site-logo img { height: 30px; } }


.main-nav { display: none; gap: 1.6rem; align-items: center; }
@media (min-width: 961px) { .main-nav { display: flex; } }
.nav-link {
  font-family: var(--font-mono); font-size: .78rem; letter-spacing: .02em;
  color: var(--muted); text-decoration: none; padding: .3rem 0;
  border-bottom: 1px solid transparent;
}
.nav-link:hover { color: var(--ink); text-decoration: none; border-bottom-color: var(--line); }
.nav-link.active { color: var(--accent); border-bottom-color: var(--accent); }
.nav-cta {
  font-family: var(--font-mono); font-size: .78rem;
  background: var(--cta); color: var(--cta-ink); padding: .45rem .9rem;
  border-radius: 3px; text-decoration: none;
}
.nav-cta:hover { background: var(--cta-hover); color: var(--cta-ink); text-decoration: none; }

/* ── Nav dropdown (horizontal layout only) ──────────────────
   The hamburger layout keeps its flat list: a drop-down inside a full-screen
   panel is a second tap for nothing. These only exist above the 961px breakpoint
   where .main-nav is displayed at all. */
.nav-group { position: relative; }
.nav-group-btn {
  font-family: var(--font-mono); font-size: .78rem; letter-spacing: .02em;
  color: var(--muted); background: none; border: 0; cursor: pointer;
  padding: .3rem 0; border-bottom: 1px solid transparent;
  display: inline-flex; align-items: center; gap: .35rem;
}
.nav-group-btn:hover,
.nav-group[data-open="true"] .nav-group-btn { color: var(--ink); border-bottom-color: var(--line); }
.nav-group-btn.active { color: var(--accent); border-bottom-color: var(--accent); }
.nav-caret {
  width: 8px; height: 5px; flex: none; fill: none;
  stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
  transition: transform .16s ease;
}
.nav-group[data-open="true"] .nav-caret { transform: rotate(180deg); }

.nav-menu {
  position: absolute; top: calc(100% + .55rem); left: 50%; transform: translateX(-50%) translateY(-4px);
  min-width: 11rem; padding: .35rem; z-index: 70;
  background: var(--surface); border: 1px solid var(--line); border-radius: 4px;
  box-shadow: var(--shadow);
  display: flex; flex-direction: column;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .16s ease, transform .16s ease, visibility .16s;
}
.nav-group[data-open="true"] .nav-menu {
  opacity: 1; visibility: visible; pointer-events: auto; transform: translateX(-50%) translateY(0);
}
/* A hover bridge across the gap, so the pointer can travel button -> menu. */
.nav-menu::before { content: ""; position: absolute; top: -.6rem; left: 0; right: 0; height: .6rem; }
.nav-menu a {
  font-family: var(--font-mono); font-size: .78rem; letter-spacing: .02em;
  color: var(--muted); text-decoration: none; white-space: nowrap;
  padding: .5rem .7rem; border-radius: 3px;
}
.nav-menu a:hover { color: var(--ink); background: var(--sunken); text-decoration: none; }
.nav-menu a.active { color: var(--accent); }

.hamburger {
  display: flex; flex-direction: column; gap: 4px; background: none;
  border: 0; cursor: pointer; padding: .4rem;
}
@media (min-width: 961px) { .hamburger { display: none; } }
.hamburger span { display: block; width: 20px; height: 2px; background: var(--ink); }

.mobile-nav {
  position: fixed; inset: 0; z-index: 60; background: var(--paper);
  display: none; flex-direction: column; align-items: flex-start;
  justify-content: center; gap: .4rem; padding: 2rem;
}
.mobile-nav.open { display: flex; }
.mobile-nav a {
  font-family: var(--font-mono); font-size: 1.05rem; color: var(--ink);
  padding: .6rem 0; text-decoration: none;
}
.mobile-nav a.active { color: var(--accent); }
/* The one action in the sheet reads as an action. Specificity beats `.mobile-nav a`
   above, which sets its own colour and padding. */
.mobile-nav a.mobile-nav-cta {
  background: var(--cta); color: var(--cta-ink); font-size: .95rem;
  padding: .75rem 1.3rem; border-radius: 3px; margin-top: 1.1rem;
}
.mobile-nav a.mobile-nav-cta-active { color: var(--cta-ink); }
.mobile-nav-close {
  position: absolute; top: 1.2rem; right: 1.4rem; background: none; border: 0;
  font-size: 2rem; line-height: 1; color: var(--muted); cursor: pointer;
}

/* ── Type scale ────────────────────────────────────────────── */
.eyebrow {
  font-family: var(--font-mono); font-size: .7rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--accent); font-weight: 600;
  margin-bottom: .9rem;
}
.eyebrow-muted { color: var(--muted); }

h1 {
  font-size: clamp(1.9rem, 6.2vw, 3.1rem); line-height: 1.08; letter-spacing: -.025em;
  color: var(--ink); font-weight: 700; text-wrap: balance; margin-bottom: 1rem;
}
h2 {
  font-size: clamp(1.35rem, 4.2vw, 1.95rem); line-height: 1.18; letter-spacing: -.018em;
  color: var(--ink); font-weight: 700; text-wrap: balance; margin-bottom: .85rem;
}
h3 {
  font-size: clamp(1.02rem, 2.6vw, 1.18rem); line-height: 1.3; letter-spacing: -.008em;
  color: var(--ink); font-weight: 600; margin-bottom: .45rem;
}
h4 {
  font-family: var(--font-mono); font-size: .74rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted); font-weight: 600; margin-bottom: .5rem;
}

p { margin-bottom: 1rem; }
p:last-child { margin-bottom: 0; }

.lead { font-size: clamp(1.02rem, 2.8vw, 1.18rem); color: var(--ink-2); }
.small { font-size: .87rem; }
.tiny  { font-size: .78rem; color: var(--muted); }
.tabular { font-variant-numeric: tabular-nums; }

ul.plain, ol.plain { list-style: none; }
ul.bul { padding-left: 1.15rem; margin-bottom: 1rem; }
ul.bul li { margin-bottom: .4rem; }
ul.bul li::marker { color: var(--faint); }

/* ── Buttons ───────────────────────────────────────────────── */
.btn {
  display: inline-block; font-family: var(--font-mono); font-size: .82rem;
  padding: .7rem 1.25rem; border-radius: 3px; border: 1px solid transparent;
  cursor: pointer; text-decoration: none; transition: background .15s, color .15s;
}
.btn:hover { text-decoration: none; }
.btn-primary { background: var(--cta); color: var(--cta-ink); }
.btn-primary:hover { background: var(--cta-hover); color: var(--cta-ink); }
.btn-ghost { background: transparent; color: var(--accent); border-color: var(--line); }
.btn-ghost:hover { border-color: var(--accent); background: var(--accent-wash); }
.btn-row { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: 1.4rem; }

/* ── Hero ──────────────────────────────────────────────────── */
.hero { padding: 2.5rem 0 3rem; }
@media (min-width: 600px) { .hero { padding: 3.5rem 0 4rem; } }
@media (min-width: 961px) { .hero { padding: 4.5rem 0 5rem; } }

.hero-claim { max-width: 34rem; }
/* With the artifacts moved out to the example section, the hero is text only.
   At desktop it splits so the scope note sits beside the claim as a peer
   rather than leaving half the page empty. */
.hero-split { display: grid; gap: 1.6rem; }
@media (min-width: 961px) {
  .hero-split { grid-template-columns: 1.1fr .9fr; gap: 3.4rem; align-items: start; }
  .hero-split .hero-claim { max-width: none; }
  /* The right column starts below the H1's cap height so the two columns read
     as one argument, left first. */
  .hero-split .hero-rest { margin-top: 4.6rem; }
}
.hero-sub { font-size: clamp(1rem, 2.8vw, 1.16rem); color: var(--ink-2); margin-top: .2rem; }

.artifact-grid { display: grid; gap: 1rem; margin-top: 2.2rem; }
@media (min-width: 961px) { .artifact-grid { grid-template-columns: 1.35fr 1fr; align-items: start; } }

.artifact {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 6px; overflow: hidden; box-shadow: var(--shadow);
}
.artifact-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: .75rem;
  padding: .6rem .9rem; border-bottom: 1px solid var(--line-soft);
  background: var(--sunken);
}
.artifact-title {
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); font-weight: 600;
}
.artifact-meta { font-family: var(--font-mono); font-size: .68rem; color: var(--faint); }
.artifact-body { padding: .9rem; }
.artifact-body.tight { padding: .5rem; }

/* ── Plan diagram ──────────────────────────────────────────── */
.plan-svg { width: 100%; height: auto; display: block; }

.plan-svg .pn-box       { fill: var(--surface); stroke: var(--line); stroke-width: 1; }
/* Shaded: this step waits on a person — the legend under the diagram says so. */
.plan-svg .pn-box-human { fill: var(--accent-wash); stroke: var(--accent); stroke-width: 1; }
.plan-svg .pn-decision  { fill: var(--sunken); stroke: var(--line); stroke-width: 1.5; }
/* Dark mode: --line is tuned for hairlines on panels and reads too dim as a
   shape outline; the flowchart borders get their own brighter strokes. */
@media (prefers-color-scheme: dark) {
  .plan-svg .pn-box      { stroke: #5a564e; }
  .plan-svg .pn-decision { stroke: #5a564e; }
  .plan-svg .pn-box-human { stroke: #8fa2dc; }
}
.plan-svg .pn-legend    { font-family: var(--font-mono); font-size: 10.5px; fill: var(--muted); }
.plan-svg .pn-flow      { stroke: var(--line); stroke-width: 1.5; fill: none; }

.plan-svg .pn-desc      { font-family: var(--font-body); font-size: 13.5px; fill: var(--ink); }
.plan-svg .pn-desc-sm   { font-family: var(--font-body); font-size: 12.5px; fill: var(--ink); }
.plan-svg .pn-note      { font-family: var(--font-mono); font-size: 9.5px; fill: var(--faint); }
.plan-svg .pn-edge      { font-family: var(--font-mono); font-size: 9.5px; fill: var(--muted); }
.plan-svg .pn-foot      { font-family: var(--font-mono); font-size: 10.5px; fill: var(--pass); }
.plan-svg .pn-foot2     { font-family: var(--font-mono); font-size: 9.5px; fill: var(--faint); }

.plan-node { opacity: .28; }
.plan-node.verified { opacity: 1; transition: opacity .32s ease; }

/* ── Record excerpt ────────────────────────────────────────── */
.record {
  font-family: var(--font-mono); font-size: .72rem; line-height: 1.62;
  color: var(--ink-2); overflow-x: auto; white-space: pre; margin: 0;
}
.record .k   { color: var(--accent); }
.record .s   { color: var(--pass); }
.record .n   { color: var(--wait); }
.record .c   { color: var(--faint); }

.record-lines { display: grid; gap: .55rem; }
.rec-line { display: grid; grid-template-columns: 4.9rem 1fr; gap: .6rem; align-items: baseline; font-size: .78rem; }
.rec-tag {
  font-family: var(--font-mono); font-size: .62rem; letter-spacing: .07em;
  padding: .12rem .38rem; border-radius: 2px; border: 1px solid currentColor;
  white-space: nowrap; text-align: center; justify-self: stretch;
}
.rec-tag.pass { color: var(--pass); }
.rec-tag.wait { color: var(--wait); }
.rec-tag.act  { color: var(--accent); }
.rec-body { color: var(--ink-2); }
.rec-body em { color: var(--muted); font-style: italic; }

/* ── Cost line ─────────────────────────────────────────────── */
.cost {
  display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
  font-family: var(--font-mono);
}
.cost-value { font-size: clamp(1.6rem, 5vw, 2.2rem); color: var(--ink); font-weight: 600; letter-spacing: -.02em; }
.cost-label { font-size: .74rem; color: var(--muted); letter-spacing: .06em; text-transform: uppercase; }


/* ── Cards / grids ─────────────────────────────────────────── */
.grid-3 { display: grid; gap: 1.1rem; }
@media (min-width: 600px) { .grid-3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 961px) { .grid-3 { grid-template-columns: repeat(3, 1fr); } }

.grid-2 { display: grid; gap: 1.1rem; }
@media (min-width: 600px) { .grid-2 { grid-template-columns: repeat(2, 1fr); } }

.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: 6px;
  padding: 1.25rem; box-shadow: var(--shadow-sm);
}
.card-num {
  font-family: var(--font-mono); font-size: .7rem; color: var(--accent);
  letter-spacing: .1em; margin-bottom: .55rem;
}
/* Names the blocker this card answers, so the 1:1 with the section above is
   visible rather than merely intended. */
.card-tag {
  font-family: var(--font-mono); font-size: .66rem; letter-spacing: .06em;
  color: var(--muted); margin: .9rem 0 0; padding-top: .6rem;
  border-top: 1px solid var(--line-soft);
}

/* ── Stat strip ────────────────────────────────────────────── */
.stats { display: grid; gap: 1.4rem; }
@media (min-width: 600px) { .stats { grid-template-columns: repeat(3, 1fr); } }
.stat-value {
  font-family: var(--font-mono); font-size: clamp(1.7rem, 5.5vw, 2.4rem);
  color: var(--ink); font-weight: 600; letter-spacing: -.02em; line-height: 1;
}
.stat-label { font-size: .87rem; color: var(--muted); margin-top: .45rem; }
.stat-src { font-family: var(--font-mono); font-size: .64rem; color: var(--faint); margin-top: .3rem; }

/* ── Doors ─────────────────────────────────────────────────── */
.door {
  background: var(--surface); border: 1px solid var(--line); border-radius: 6px;
  padding: 1.4rem; display: flex; flex-direction: column;
}
.door-kicker {
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent); margin-bottom: .6rem;
}
.door h3 { margin-bottom: .5rem; }
.door p { font-size: .92rem; }
.door-who {
  font-family: var(--font-mono); font-size: .7rem; color: var(--muted);
  margin-top: auto; padding-top: .9rem; border-top: 1px solid var(--line-soft);
}

/* ── Method / notes cards ──────────────────────────────────── */
.note-card { padding: 1.6rem 0; border-bottom: 1px solid var(--line-soft); }
.note-card:last-child { border-bottom: 0; }
.note-date {
  display: inline-block; font-family: var(--font-mono); font-size: .68rem;
  letter-spacing: .08em; color: var(--muted); background: var(--sunken);
  padding: .2rem .55rem; border-radius: 3px; margin-bottom: .7rem;
}
.note-title { font-size: clamp(1.05rem, 3vw, 1.28rem); line-height: 1.28; margin-bottom: .55rem; }
.note-title a.out {
  display: inline-block; font-family: var(--font-mono); font-size: .72rem;
  color: var(--accent); font-weight: 500; margin-top: .3rem;
}
.note-summary { font-size: .93rem; color: var(--ink-2); margin-bottom: .8rem; }
.note-topics { list-style: none; display: flex; flex-wrap: wrap; gap: .35rem; }
.note-topics li {
  font-family: var(--font-mono); font-size: .68rem; color: var(--muted);
  background: var(--sunken); border: 1px solid var(--line-soft);
  padding: .18rem .5rem; border-radius: 3px;
}

/* ── Book ──────────────────────────────────────────────────── */
.book { display: grid; gap: 1.3rem; }
@media (min-width: 600px) { .book { grid-template-columns: 150px 1fr; align-items: start; } }
.book-cover {
  display: block; width: 100%; height: auto;
}
.book-accolade { margin-bottom: .8rem; }
/* Deliberately NOT --pass. Green is this site's verification colour — the PASS
   stamps, the "verified before it ran" footer, the VERIFIED diagnostic — so an
   Amazon sales ranking wearing it reads as a system verdict rather than an
   accolade, on the one page arguing nothing runs unproven. The words carry it. */
.book-badge {
  display: inline-block; font-family: var(--font-mono); font-size: .66rem;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink);
  font-weight: 600; border: 1px solid var(--line); background: var(--surface);
  padding: .22rem .55rem; border-radius: 3px;
}
.book-source {
  display: block; margin-top: .4rem;
  font-family: var(--font-mono); font-size: .66rem;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}

/* ── Steps (how-it-works) ──────────────────────────────────── */
.steps { display: grid; gap: 0; counter-reset: step; }
/* A second list that carries on the first one's numbering rather than restarting.
   The count follows the markup, so adding a step above renumbers below for free. */
.steps.steps-continue { counter-reset: none; }
.step {
  display: grid; gap: .3rem .9rem; padding: 1.5rem 0;
  border-bottom: 1px solid var(--line-soft); counter-increment: step;
}
.step:last-child { border-bottom: 0; }
@media (min-width: 600px) { .step { grid-template-columns: 3.2rem 1fr; } }
.step-n {
  font-family: var(--font-mono); font-size: .8rem; color: var(--accent);
  font-weight: 600; padding-top: .15rem;
}
.step-n::before { content: counter(step, decimal-leading-zero); }

/* ── Definition rows ───────────────────────────────────────── */
.rows { border-top: 1px solid var(--line); margin: 1.2rem 0; }
.row { display: grid; gap: .3rem .9rem; padding: 1rem 0; border-bottom: 1px solid var(--line-soft); }
@media (min-width: 600px) { .row { grid-template-columns: 12rem 1fr; } }
.row .k { color: var(--ink); font-weight: 600; font-size: .95rem; }
.row .k .sub { display: block; font-weight: 400; color: var(--faint); font-size: .78rem; margin-top: .1rem; }
.row .v { font-size: .93rem; }

/* ── Callout ───────────────────────────────────────────────── */
.callout {
  background: var(--surface); border: 1px solid var(--line);
  border-left: 3px solid var(--accent); border-radius: 0 5px 5px 0;
  padding: 1.1rem 1.2rem; margin: 1.4rem 0; box-shadow: var(--shadow-sm);
}
.callout h4 { color: var(--accent); }

/* ── Reveal animation (FOUC-safe) ──────────────────────────── */
.reveal-init { opacity: 0; transform: translateY(10px); }
.reveal-on {
  opacity: 1; transform: none;
  transition: opacity .55s ease, transform .55s ease;
}

/* ── Footer ────────────────────────────────────────────────── */
.site-footer {
  flex-shrink: 0; border-top: 1px solid var(--line);
  padding: 2.2rem 0 2.6rem; margin-top: 1rem;
}
.footer-inner {
  max-width: var(--wide); margin: 0 auto; padding: 0 1.25rem;
}
@media (min-width: 600px) {
  .footer-inner { padding: 0 2rem; }
}
@media (min-width: 961px) { .footer-inner { padding: 0 2.5rem; } }
.footer-note { font-family: var(--font-mono); font-size: .7rem; color: var(--faint); margin-bottom: 0; }

/* ── 404 ───────────────────────────────────────────────────── */
.e404 { text-align: center; padding: 5rem 0; }
.e404-code {
  font-family: var(--font-mono); font-size: clamp(3rem, 14vw, 5.5rem);
  color: var(--accent); font-weight: 600; line-height: 1; letter-spacing: -.03em;
}

/* ── Print ─────────────────────────────────────────────────── */
@media print {
  .site-header, .mobile-nav, .hamburger, .btn-row, .breaker { display: none; }
  body { background: #fff; color: #000; }
}

/* ── Industry / process list ───────────────────────────────── */
.work { border-top: 1px solid var(--line); margin: 1.4rem 0 0; }
.work-row {
  display: grid; gap: .35rem .9rem; padding: 1.05rem 0;
  border-bottom: 1px solid var(--line-soft);
}
@media (min-width: 600px) { .work-row { grid-template-columns: 13.5rem 1fr; } }
.work-row .who { color: var(--ink); font-weight: 600; font-size: .97rem; }
.work-row .who .dur {
  display: block; font-family: var(--font-mono); font-size: .7rem; letter-spacing: .05em;
  color: var(--faint); text-transform: uppercase; margin-top: .2rem; font-weight: 400;
}
.work-row .what { font-size: .93rem; line-height: 1.55; }

/* ── The authoring chat ────────────────────────────────────── */
/* The interview rendered as the chat it is: the manager's initial request
   first, then the questions that close its gaps. Animated on scroll (JS adds
   data-animate, so with no JS every message is simply visible). */
.chat { display: flex; flex-direction: column; gap: .6rem; }
.msg {
  max-width: 88%; padding: .6rem .85rem; border-radius: 10px;
  font-size: .93rem; line-height: 1.55; color: var(--ink-2);
}
.msg .who {
  display: block; font-family: var(--font-mono); font-size: .62rem; letter-spacing: .09em;
  text-transform: uppercase; color: var(--faint); margin-bottom: .3rem;
}
.msg.ai  { align-self: flex-start; background: var(--surface); border: 1px solid var(--line);
           border-bottom-left-radius: 3px; }
.msg.you { align-self: flex-end; background: var(--accent-wash); border: 1px solid var(--line);
           border-bottom-right-radius: 3px; color: var(--ink); }
/* The skipped-ahead marker: a visible CUT in the conversation, not a line of
   dialogue. Dashed rules flank the label and flex to any width. */
.chat .gap {
  align-self: stretch; display: flex; align-items: center; gap: .8rem;
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .06em;
  color: var(--faint); text-transform: uppercase; padding: .45rem 0;
  text-align: center;
}
.chat .gap::before, .chat .gap::after {
  content: ''; flex: 1 1 0; min-width: 1.5rem;
  border-top: 1px dashed var(--faint);
}
.chat[data-animate] .msg, .chat[data-animate] .gap {
  opacity: 0; transform: translateY(8px);
  transition: opacity .38s ease, transform .38s ease;
}
.chat[data-animate] .msg.in, .chat[data-animate] .gap.in { opacity: 1; transform: none; }

/* ── Four-across property grid + its row labels ────────────── */
.grid-4 { display: grid; gap: 1rem; }
@media (min-width: 600px) { .grid-4 { grid-template-columns: 1fr 1fr; } }
@media (min-width: 961px) { .grid-4 { grid-template-columns: repeat(4, 1fr); } }
.row-label {
  font-family: var(--font-mono); font-size: .7rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--faint); margin: 1.7rem 0 .8rem;
}

/* ── Run-through animation (plan + trail in parallel) ──────── */
/* The verifier sweep settles the plan once at load; this is the second act:
   the run replays step by step, the current plan node and its trail line
   sharing one subtle background lift. Driven by JS on scroll into view; with
   no JS, bots, or reduced motion, nothing here applies and both artifacts are
   simply still. The untaken branch ("proceed on the standing limit") is never
   lit — this run went over the limit, and the trail says so. */
.plan-svg .pn-box, .plan-svg .pn-box-human, .plan-svg .pn-decision {
  transition: fill .5s ease;
}
.plan-node.run-live .pn-box,
.plan-node.run-live .pn-decision {
  fill: color-mix(in srgb, var(--accent) 14%, var(--surface));
}
.plan-node.run-live .pn-box-human {
  fill: color-mix(in srgb, var(--accent) 24%, var(--surface));
}
.rec-line {
  border-radius: 4px; padding: .18rem .45rem; margin: -.18rem -.45rem;
  transition: background .5s ease;
}
.rec-line.run-live { background: var(--accent-wash); }

/* ── The authoring loop (DSL replay) ───────────────────────── */
/* Rest state (and the no-JS state) is the converged draft with its seal.
   JS replaces the static block with a live replay: draft → diagnostics →
   fixes → verified, looping with a long hold on the seal. */
.dsl {
  font-family: var(--font-mono); font-size: .72rem; line-height: 1.6;
  /* overflow-y hidden, not auto: the sweep bar is absolutely positioned and
     travels to the container's full height, which in a scroll container
     extends the scrollable area and flashes a vertical scrollbar mid-pass */
  overflow-x: auto; overflow-y: hidden; padding: .2rem .1rem;
}
.dsl-line { white-space: pre; }
.dsl-line .k { color: var(--accent-deep); font-weight: 600; }   /* keywords */
.dsl-line .g { color: var(--faint); }                            /* gutter char */
.dsl-line .t { color: var(--ink-2); }                            /* gutter prose */
.dsl-line .r { color: var(--accent); }                           /* $() reads */
.dsl-line .w { color: var(--ink); font-weight: 600; }            /* → writes */
.dsl-line .m { color: var(--faint); }                            /* @modifiers */
.dsl-line .c { color: var(--faint); font-style: italic; }        /* # docs */
.dsl-line .e { color: var(--wait); }                             /* 'enum' values */

/* a line being rewritten by the AI */
.dsl-line { border-radius: 3px; transition: background .45s ease; }
.dsl-line.fixing { background: var(--accent-wash); }
.dsl-cursor {
  display: inline-block; width: .55em; height: 1em; background: var(--accent);
  vertical-align: -.15em; animation: dsl-blink 1s steps(1) infinite;
}
@keyframes dsl-blink { 50% { opacity: 0; } }

/* a diagnostic unfolding under its line */
.dsl-diag {
  overflow: hidden; max-height: 0; opacity: 0; margin: 0;
  transition: max-height .5s ease, opacity .5s ease, margin .5s ease;
  border-left: 2px solid var(--fail); color: var(--fail);
  font-size: .68rem; line-height: 1.5; white-space: normal;
  padding: 0 .6rem; border-radius: 0 3px 3px 0;
  background: color-mix(in srgb, var(--fail) 6%, var(--surface));
}
.dsl-diag.open { max-height: 5.5rem; opacity: 1; margin: .3rem 0 .45rem; padding: .35rem .6rem; }
.dsl-diag b { font-weight: 600; }

/* the verifier pass sweeping down the code */
.dsl { position: relative; }
.dsl-sweep {
  position: absolute; left: 0; right: 0; top: 0; height: 1.6rem; pointer-events: none;
  background: linear-gradient(to bottom, transparent,
              color-mix(in srgb, var(--accent) 12%, transparent), transparent);
  opacity: 0; transform: translateY(-2rem);
}
.dsl-sweep.on { opacity: 1; transition: transform 1.1s linear; }

/* the converged seal */
.dsl-seal {
  display: inline-block; margin-top: .8rem; padding: .3rem .7rem;
  border: 1px solid var(--pass); color: var(--pass); border-radius: 3px;
  font-size: .68rem; letter-spacing: .08em; text-transform: uppercase;
  opacity: 1; transition: opacity .6s ease;
}
.dsl-seal.off { opacity: 0; }

/* ── The ask form (/start) ─────────────────────────────────── */
/* No backend by design: submit composes a mail in the visitor's own client
   with everything in the subject and body. */
.ask { margin-top: 1.6rem; max-width: 34rem; display: grid; gap: 1rem; }
.ask[hidden] { display: none; }
/* .btn sets display, which outranks the UA [hidden] rule — restate it. */
.reveal-form-btn[hidden] { display: none; }   /* display:grid would defeat the hidden attribute */
.reveal-form { margin-top: 1.2rem; }
.field { display: grid; gap: .35rem; }
.field label {
  font-family: var(--font-mono); font-size: .7rem; letter-spacing: .09em;
  text-transform: uppercase; color: var(--muted);
}
.field label .opt { color: var(--faint); text-transform: none; letter-spacing: 0; }
.field input, .field textarea {
  font-family: var(--font-body); font-size: .95rem; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: 4px;
  padding: .55rem .7rem; width: 100%;
}
.field textarea { resize: vertical; line-height: 1.55; }
.field input:focus-visible, .field textarea:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent);
}
.field .invalid { border-color: var(--fail); }

/* ── Ask AI++ (/ask) ───────────────────────────────────────── */
/* The assistant page: the conversation rendered in the same bubble language
   as the example page's interview (.msg reused). The container is
   deliberately NOT .chat — scripts.js animates .chat messages on first view,
   which would hide dynamically appended ones. */
.ask-band { padding: 2.2rem 0 2.6rem; }
.ask-h1 { font-size: clamp(1.5rem, 4.5vw, 2.05rem); margin-bottom: .7rem; }
.ask-artifact { margin-top: 1.3rem; }
/* No inner scrollbars anywhere on /ask: the chat area and the input both
   grow with their content, and the OUTER PAGE scrolls (anatoly, 2026-07-30). */
.ask-chat { display: flex; flex-direction: column; gap: .6rem; }
/* scroll-margin clears the sticky header when a send anchors the question */
.ask-chat .msg { flex: 0 0 auto; scroll-margin-top: 4.5rem; }
/* Only the visitor's input reads as a bubble; the assistant's replies are
   plain text on the artifact surface — no border, full width (anatoly,
   2026-07-30). Scoped to /ask: the example page's interview keeps its
   two-sided bubbles. */
.ask-chat .msg.ai {
  background: transparent; border: 0; border-radius: 0;
  max-width: 100%; padding: .1rem 0;
}

/* Markdown inside the bubbles */
.ask-chat .msg-body p { margin-bottom: .55rem; }
.ask-chat .msg-body p:last-child { margin-bottom: 0; }
.ask-chat .msg-body ul, .ask-chat .msg-body ol { padding-left: 1.15rem; margin: .3rem 0 .55rem; }
.ask-chat .msg-body li { margin-bottom: .25rem; }
.ask-chat .msg-body code {
  font-family: var(--font-mono); font-size: .82em;
  background: var(--sunken); border: 1px solid var(--line-soft);
  border-radius: 3px; padding: .05em .3em;
}
.ask-chat .msg-body pre {
  font-family: var(--font-mono); font-size: .78rem; line-height: 1.55;
  background: var(--sunken); border: 1px solid var(--line-soft); border-radius: 4px;
  padding: .6rem .75rem; overflow-x: auto; margin: .3rem 0 .55rem;
  /* A long code line scrolls horizontally; the browser-default scrollbar is
     theme-blind (a light bar on the dark surface — anatoly, 2026-07-30), so
     paint it with the site's tokens. Chromium/Firefox take scrollbar-color;
     Safari takes the -webkit pseudos below. */
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
.ask-chat .msg-body pre::-webkit-scrollbar { height: 8px; }
.ask-chat .msg-body pre::-webkit-scrollbar-track { background: transparent; }
.ask-chat .msg-body pre::-webkit-scrollbar-thumb {
  background: var(--line); border-radius: 4px;
}
.ask-chat .msg-body pre::-webkit-scrollbar-thumb:hover { background: var(--faint); }
.ask-chat .msg-body pre code { background: none; border: 0; padding: 0; font-size: inherit; }
.ask-chat .msg-body blockquote {
  border-left: 3px solid var(--accent); background: var(--accent-wash);
  border-radius: 0 4px 4px 0; padding: .5rem .7rem; margin: .3rem 0 .55rem;
}
.ask-chat .msg-body blockquote p:last-child { margin-bottom: 0; }
.ask-chat .msg-body h1, .ask-chat .msg-body h2, .ask-chat .msg-body h3,
.ask-chat .msg-body h4, .ask-chat .msg-body h5, .ask-chat .msg-body h6 {
  font-family: var(--font-body); font-size: 1rem; letter-spacing: 0;
  text-transform: none; color: var(--ink); margin: .5rem 0 .3rem;
}
.ask-chat .msg-body table { border-collapse: collapse; font-size: .85rem; margin: .3rem 0 .55rem; }
.ask-chat .msg-body th, .ask-chat .msg-body td { border: 1px solid var(--line); padding: .3rem .5rem; }
.ask-cursor {
  display: inline-block; width: .5em; height: 1em; background: var(--accent);
  vertical-align: -.12em; margin-left: .1em;
  animation: dsl-blink 1s steps(1) infinite;
}

/* The input bar */
.ask-inputbar {
  display: flex; align-items: flex-end; gap: .6rem;
  border-top: 1px solid var(--line-soft); background: var(--sunken);
  padding: .6rem .9rem;
}
.ask-inputbar textarea {
  flex: 1 1 auto; font-family: var(--font-body); font-size: .95rem; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: 4px;
  padding: .5rem .65rem; resize: none; line-height: 1.5; overflow-y: hidden;
}
.ask-inputbar textarea:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent);
}
/* The send button is the bare arrow glyph — transparent background, stroked
   in the CTA color per theme via currentColor (anatoly, 2026-07-30). */
.ask-send {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 2.4rem; height: 2.4rem; padding: 0;
  background: transparent; border: 0; border-radius: 4px;
  color: var(--cta); cursor: pointer;
}
.ask-send:hover { color: var(--cta-hover); }
.ask-send:disabled { opacity: .45; cursor: default; }
.ask-send svg { display: block; }
.ask-note { margin-top: .8rem; }

/* An entry point: the small circled question mark. Quiet by design —
   it must not compete with the artifact it sits on. */
.ask-q {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.15rem; height: 1.15rem; border-radius: 50%; flex: 0 0 auto;
  border: 1px solid var(--line); color: var(--faint);
  font-family: var(--font-mono); font-size: .66rem; font-weight: 600; line-height: 1;
  text-decoration: none; vertical-align: .12em; margin-left: .5rem;
}
.ask-q:hover {
  color: var(--accent); border-color: var(--accent);
  background: var(--accent-wash); text-decoration: none;
}
.artifact-head .ask-q { align-self: center; margin-left: 0; }
/* In a row label the icon takes its own line, always — inline it wrapped
   unpredictably with the label text (long labels pushed it down, short ones
   kept it beside), so uniformity comes from never sharing the line. */
.k .ask-q { display: flex; margin: 0.45rem 0 0; }


/* ── Video player (HLS) ─────────────────────────────────────
   VIDEO COLOUR MODEL — note this is a property of the FOOTAGE, not of the
   site. The page theme comes from prefers-color-scheme and is a separate axis
   entirely: a light video on a dark page is an ordinary combination, and the
   controls have to stay legible in it.

   A translucent white bar is the standard because most footage is dark. Over
   predominantly WHITE footage — a screen recording of a document, a light UI —
   it disappears: white glass on white pixels. So the bar's colours come from
   tokens, and the model swaps the token set:

     (default)                     dark footage  — light glass, white icons
     data-video-color-model="light"  light footage — dark scrim, white icons

   Both models keep white icons. Over light footage the contrast has to come
   from the scrim rather than the glyphs; dark-on-light was the alternative and
   loses against the bright, busy frames these recordings actually contain.

   Adding a third model is a token block — no new rule needs writing below. */
.hls-player {
  --vp-stage:        #0c0b0a;
  --vp-bar-bg:       rgba(255, 255, 255, .10);
  --vp-bar-border:   rgba(255, 255, 255, .12);
  --vp-btn-bg:       rgba(255, 255, 255, .15);
  --vp-btn-bg-hover: rgba(255, 255, 255, .25);
  --vp-icon:         #ffffff;
  --vp-track:        rgba(255, 255, 255, .15);
  --vp-buffer:       rgba(255, 255, 255, .20);
  --vp-fill:         rgba(255, 255, 255, .62);
  --vp-time:         rgba(255, 255, 255, .58);
  --vp-time-sep:     rgba(255, 255, 255, .30);

  position: relative;
  width: 100%;
  padding-bottom: var(--player-ratio, 56.25%);
  background: var(--vp-stage);
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 5px;
  box-shadow: var(--shadow);
  cursor: pointer;
  outline: none;
}

/* Light footage: the bar becomes the dark element on the frame. Opacity is
   carried higher than the dark model's because it is doing the whole job of
   separating the controls from the picture. */
.hls-player[data-video-color-model="light"] {
  --vp-stage:        #e9e6df;
  --vp-bar-bg:       rgba(20, 19, 17, .62);
  --vp-bar-border:   rgba(20, 19, 17, .30);
  --vp-btn-bg:       rgba(255, 255, 255, .18);
  --vp-btn-bg-hover: rgba(255, 255, 255, .30);
  --vp-icon:         #ffffff;
  --vp-track:        rgba(255, 255, 255, .25);
  --vp-buffer:       rgba(255, 255, 255, .35);
  --vp-fill:         rgba(255, 255, 255, .85);
  --vp-time:         rgba(255, 255, 255, .80);
  --vp-time-sep:     rgba(255, 255, 255, .45);
}

.hls-player:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.hls-player video {
  position: absolute; top: 0; left: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  background: var(--vp-stage);
  display: block;
}

/* Poster — the video's own first frame, extracted by build.sh step 0. */
.hls-player .player-poster {
  position: absolute; inset: 0; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  background: var(--vp-stage);
  transition: opacity .4s ease;
}
.hls-player .player-poster.hidden { opacity: 0; pointer-events: none; }
.hls-player .player-poster-img { width: 100%; height: 100%; object-fit: cover; }

/* Glass control bar */
.hls-player .player-controls {
  position: absolute; bottom: 14px; left: 50%;
  transform: translateX(-50%);
  width: 85%; padding: 10px 16px; z-index: 4;
  display: flex; align-items: center; gap: 12px;
  background: var(--vp-bar-bg);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-radius: 10px;
  border: 1px solid var(--vp-bar-border);
  opacity: 0; transition: opacity .3s ease; pointer-events: none;
}
.hls-player .player-controls.visible { opacity: 1; pointer-events: auto; }

.hls-player .player-play-btn {
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--vp-btn-bg);
  border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; transition: background .15s;
}
.hls-player .player-play-btn:hover { background: var(--vp-btn-bg-hover); }
.hls-player .player-play-btn svg { fill: var(--vp-icon); width: 13px; height: 13px; margin-left: 2px; }
.hls-player .player-pause-icon { margin-left: 0 !important; }

.hls-player .player-progress {
  flex: 1; height: 3px;
  background: var(--vp-track);
  border-radius: 2px; position: relative; cursor: pointer;
}
.hls-player .player-progress-buffer,
.hls-player .player-progress-fill {
  position: absolute; top: 0; left: 0; height: 100%;
  border-radius: 2px; width: 0;
}
.hls-player .player-progress-buffer { background: var(--vp-buffer); }
.hls-player .player-progress-fill   { background: var(--vp-fill); z-index: 1; }
.hls-player .player-progress::before {
  content: ''; position: absolute; top: -8px; bottom: -8px; left: 0; right: 0;
}

.hls-player .player-time-current,
.hls-player .player-time-duration {
  font-family: var(--font-mono); font-size: 11px;
  color: var(--vp-time);
  white-space: nowrap; flex-shrink: 0;
}
.hls-player .player-time-sep {
  font-size: 11px; color: var(--vp-time-sep);
  flex-shrink: 0; margin: 0 -4px;
}

.hls-player .player-volume-btn,
.hls-player .player-fullscreen-btn {
  background: none; border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  padding: 4px; flex-shrink: 0;
}
.hls-player .player-volume-btn svg,
.hls-player .player-fullscreen-btn svg { width: 16px; height: 16px; fill: var(--vp-icon); }
.hls-player .player-volume-btn.muted .vol-on { display: none; }
.hls-player .player-volume-btn.muted .vol-off { display: block !important; }

.hls-player:fullscreen { border-radius: 0; border: 0; }
.hls-player:fullscreen .player-controls { bottom: 24px; }

@media (max-width: 600px) {
  .hls-player .player-controls { bottom: 8px; width: 92%; padding: 8px 10px; gap: 8px; }
  .hls-player .player-time-sep,
  .hls-player .player-time-duration { display: none; }
}

/* ── Demo page layout ───────────────────────────────────────
   One <article class="demo-item"> per video, so adding the next one is markup
   only — no new CSS, no new script. */
.demo-item + .demo-item { margin-top: 4.5rem; padding-top: 4.5rem; border-top: 1px solid var(--line-soft); }
.demo-item-head { margin-bottom: 1.4rem; }
.demo-item-head h2 { margin: 0 0 .4rem; }
.demo-item-meta {
  font-family: var(--font-mono); font-size: .74rem; color: var(--faint);
  letter-spacing: .04em; text-transform: uppercase;
}
