/* reef demo — three pages: an overview, a comparison, and the details.
   Mobile first; the only breakpoints are where a two-column layout starts to fit. */
/* One palette: deep water. The page is carried by two dense panels of cited text and
   they read better on dark, and coral only means anything against water — so the
   neutrals carry a green-blue cast rather than being a neutral charcoal. A light
   alternative existed briefly and was dropped: warm paper cannot hold the metaphor,
   so it said less than this does. */
:root{
  /* Structural, not palette. These must sit outside both themes: an undefined var
     invalidates the whole declaration that uses it, so losing --gut here silently
     zeroed the padding on every section. */
  /* Manrope and JetBrains Mono, the pairing Talent Solutions uses. Neither carries
     Hangul, so the Korean stack follows immediately behind and takes over for it. */
  --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace;
  --sans:"Manrope","Pretendard","Apple SD Gothic Neo",-apple-system,
         BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --gut:clamp(18px,5vw,72px);
  --band:clamp(44px,7.5vh,92px);   /* vertical padding of every section, on every page */
  --page:1360px;
  --measure:66ch;

  /* The water was green-leaning, which at this lightness read as plain black. Same
     darkness, hue tilted from teal toward blue — deep rather than unlit. */
  --bg:#07151b; --bg-deep:#040f14; --bg-soft:#0c1e26; --panel:#0e212b; --line:#1c3542;
  --ink:#e8f1f4; --ink-dim:#95a9b2; --ink-faint:#61767f;
  /* The accent used to be one flat hue applied at full strength in forty-odd places,
     which is what made the largest surface — the button — look cheap. It is now a
     short range: amber at one end, rose at the other, coral in the middle. Both ends
     are neighbours of coral rather than a second meaningful colour, so the gradient
     reads as one accent with depth in it and not as two colours competing. */
  --accent:#ff8a6e; --accent-warm:#ffab6d; --accent-cool:#3a80a4;
  /* Two ranges, because they have different jobs. The warm one fills things that carry
     dark text and therefore need one legible field. The cool one runs coral into the
     water the page is already painted with, which is the only way to put a dark blue
     in an accent without it reading as a second, competing colour. */
  --grad-warm:linear-gradient(103deg, var(--accent-warm) 0%, var(--accent) 100%);
  --grad:linear-gradient(103deg, var(--accent) 0%, var(--accent-cool) 100%);
  --grad-v:linear-gradient(176deg, var(--accent) 0%, var(--accent-cool) 100%);
  --warn:#e3b341;
  --code-bg:#0a0d10; --code-ink:#93a3b1;
  --accent-wash:#221714; --dot:rgba(233,242,238,.05);
  --lift:none;
  --panel-shadow:0 18px 50px rgba(0,0,0,.55);
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0; color:var(--ink);
  /* A fine dot field over the whole page, which is what stops a flat dark background
     reading as an empty div. Sized so it is texture at reading distance, not pattern. */
  /* Both layers scroll with the document. A fixed background repaints the whole
     viewport on every scroll frame, which is what made scrolling feel like it was
     bobbing. The depth gradient spans the body, so it still reads as depth. */
  background:
    radial-gradient(circle at 1px 1px, var(--dot) 1px, transparent 0) 0 0 / 22px 22px,
    linear-gradient(180deg, var(--bg) 0%, var(--bg-deep) 100%);
  font-family:var(--sans); font-size:17px; line-height:1.65;
  -webkit-font-smoothing:antialiased;
  /* Two rules working together. keep-all stops Korean breaking mid-word — without it
     시스템 splits as 시스/템 — while overflow-wrap still lets a long unbroken Latin
     token, a Java package path or a file name, wrap rather than scroll the page. */
  word-break:keep-all;
  overflow-wrap:anywhere;
}
a{color:var(--accent)}
h1,h2{line-height:1.22}
h2{font-size:clamp(28px,4.2vw,54px); margin:0 0 20px; font-weight:600; letter-spacing:-.028em}

/* ---------- chrome ---------- */
/* The bar aligns to the same column the content uses, rather than hugging the window
   edges — on a wide screen the brand and the nav were sitting a metre apart from
   anything they belong to. */
.topbar{
  position:fixed; inset:0 0 auto 0; z-index:20; display:flex; align-items:center;
  gap:16px; flex-wrap:wrap; min-height:68px;
  padding:12px max(var(--gut), calc((100% - var(--page)) / 2));
  background:color-mix(in srgb,var(--bg) 84%,transparent);
  backdrop-filter:blur(10px); border-bottom:1px solid var(--line);
}
.brand{
  font-family:var(--mono); font-weight:600; font-size:17px; letter-spacing:.01em;
  text-decoration:none; color:var(--ink);
}
.brand span{color:var(--ink)}
.nav{display:flex; gap:4px; flex-wrap:wrap; min-width:0}
.nav{gap:2px}
.nav a{
  font-size:15px; text-decoration:none; color:var(--ink-dim);
  padding:9px 14px; border-radius:8px; white-space:nowrap;
}
.nav a:hover{color:var(--ink); background:var(--panel)}
/* The page you are on should be legible at a glance, not a slightly different grey. */
.nav a[aria-current="page"]{
  color:var(--accent); background:var(--accent-wash);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--accent) 30%, transparent);
}
.lang{display:flex; border:1px solid var(--line); border-radius:8px; overflow:hidden}
.lang button{
  font:inherit; font-size:13.5px; background:transparent; color:var(--ink-faint);
  border:0; padding:7px 11px; cursor:pointer;
}
.lang button[aria-pressed="true"]{background:var(--panel); color:var(--ink)}
/* --bar is measured by site.js; the fallback matches the unwrapped height. */
main{padding-top:var(--bar,68px)}
footer{
  padding:40px var(--gut) 56px; border-top:1px solid var(--line);
  text-align:center; font-size:14px; color:var(--ink-faint);
}
footer p{margin:0 0 8px; max-width:var(--measure); margin-inline:auto}

/* The three public repositories, at the foot of every page. A sitemap line: the same
   size and colour as the fine print beside it, carrying no emphasis of its own. They
   are somewhere to go afterwards, not something the page is asking for. */
.foot-repos{
  display:flex; flex-wrap:wrap; justify-content:center; align-items:baseline;
  gap:2px 8px; margin:0 auto 10px;
}
.foot-repos a{
  font-size:13px; color:var(--ink-faint);
  text-decoration:none; text-underline-offset:3px;
}
.foot-repos a:hover{color:var(--ink-dim); text-decoration:underline}
.foot-repos-sep{color:var(--ink-faint); opacity:.5; font-size:12px}

/* The way on, at the end of every page. Two cells so the ends of the sequence keep
   their side: the first page's Next stays right, the last page's Previous stays left. */
.pager{
  display:grid; grid-template-columns:1fr 1fr; gap:12px;
  max-width:var(--page); margin:0 auto 32px; text-align:left;
}
.pager-link{
  display:grid; gap:5px; align-content:center; min-height:72px;
  padding:16px 18px; text-decoration:none;
  background:var(--panel); border:1px solid var(--line); border-radius:12px;
  transition:border-color .15s ease, background .15s ease;
}
.pager-link:hover{
  border-color:color-mix(in srgb, var(--accent) 55%, transparent);
  background:color-mix(in srgb, var(--accent) 5%, var(--panel));
}
.pager-dir{
  font-family:var(--mono); font-size:11.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-faint);
}
.pager-link b{font-size:16px; font-weight:600; color:var(--ink); word-break:keep-all}
.pager-next{text-align:right}
@media(max-width:640px){
  /* One column, and the empty cell would otherwise be an empty row. */
  .pager{grid-template-columns:1fr}
  .pager-gap{display:none}
}

/* ---------- shared blocks ---------- */
.kicker{
  font-family:var(--mono); font-size:12px; letter-spacing:.16em; text-transform:uppercase;
  color:var(--ink-faint); margin:0 0 18px;
}
.hero .kicker{color:var(--accent)}
.body{color:var(--ink-dim); max-width:var(--measure); margin:0 0 14px}
.meta{font-family:var(--mono); font-size:13px; color:var(--ink-faint); max-width:var(--measure)}
.muted{color:var(--ink-faint)}
.preline{white-space:pre-line}
.panel{
  background:color-mix(in srgb, var(--panel) 88%, transparent);
  border:1px solid var(--line); border-radius:16px; padding:22px;
  box-shadow:var(--lift);
}
pre,code{font-family:var(--mono); font-size:13.5px}
code{color:var(--ink)}
pre{margin:0; overflow-x:auto; line-height:1.6}
.term{
  background:var(--code-bg); border:1px solid var(--line); border-radius:8px;
  padding:14px 16px; color:var(--code-ink); white-space:pre; overflow-x:auto;
}
.src{font-family:var(--mono); font-size:12px; color:var(--ink-faint)}
.tag{
  display:inline-block; font-family:var(--mono); font-size:11px; letter-spacing:.06em;
  text-transform:uppercase; padding:3px 8px; border-radius:999px;
  border:1px solid var(--line); color:var(--ink-faint);
}
.q-mark{color:var(--accent); font-family:var(--mono); margin-right:10px}
/* The reef column of any comparison, so the eye finds it without a legend. */
.is-reef{color:var(--ink); border-left:2px solid color-mix(in srgb, var(--accent) 62%, transparent) !important}

/* A class selector beats the UA rule for [hidden], so display:flex/grid on a
   component silently un-hides it. State this once, loudly. */
[hidden]{display:none !important}
[data-i18n]:empty::after,[data-md]:empty::after{content:"…"; color:var(--ink-faint)}

/* Light through water: a fixed layer of soft blooms that stays with the viewport as
   you scroll, so the whole page sits in one body of water rather than the hero alone
   being lit. No blur filter — wide, soft colour stops are cheaper and do not shimmer
   on a repaint. */
body::before{
  content:""; position:fixed; inset:0; z-index:-1; pointer-events:none;
  /* Promoted to its own compositing layer so it is composited on scroll rather than
     repainted. It is the one fixed thing left, and it is what keeps the light with
     the viewport. */
  transform:translateZ(0);
  background:
    radial-gradient(62% 48% at 78% 8%,  color-mix(in srgb, var(--accent-warm) 20%, transparent), transparent 68%),
    radial-gradient(70% 50% at 60% 96%, color-mix(in srgb, var(--accent-cool) 16%, transparent), transparent 72%);
}


/* ---------- 1. landing ---------- */
/* The hero holds the headline and the product. The product is deliberately taller
   than the room left for it, so the fold cuts it — which is what tells a visitor
   there is more without asking them to take that on trust. */
/* The hero holds three things and nothing else: the line, the descriptor, the button.
   Centred, because with the comparison moved out there is no second column for the
   type to sit against, and left-aligned copy in an empty band drifts to one side. */
.hero{
  padding:clamp(72px,14vh,150px) var(--gut) var(--band);
  display:flex; flex-direction:column; overflow:hidden; text-align:center;
}
/* The bar is translucent, so what sits behind it shows through. main's padding put
   the bar's height of bare page there while the hero's glow began underneath it —
   a tonal step along exactly the bar's bottom edge, visible the whole way down the
   scroll. The hero takes that strip back: it starts at the top of the document, and
   pads its own content clear of the bar instead. The glow cannot simply bleed up
   into it, because `overflow:hidden` clips the ::before at the hero's own edge. */
.hero{
  margin-top:calc(var(--bar, 68px) * -1);
  padding-top:calc(clamp(72px,14vh,150px) + var(--bar, 68px));
}
.hero-inner{max-width:var(--page); margin:0 auto; width:100%; flex:0 0 auto}
.hero .hero-desc{margin-left:auto; margin-right:auto}
.hero .cta-row{align-items:center}
.hero .kicker{align-self:center}
/* No rule under the hero. Its water and its glow both fade to nothing before the
   edge, so the next band begins on open background rather than on a line. */
/* The hero's bottom padding and this band's top padding used to add up to three
   hundred pixels of nothing on a tall screen. Half of each is enough. */
.hero + .band{border-top:0; position:relative; isolation:isolate}
/* The hero's cool glow does not stop at the hero. It carries on into the band below
   and fades out there, so the two read as one body of water with the comparison
   sitting in it. */
.hero + .band::before{
  content:""; position:absolute; inset:0 0 auto 0; height:min(70%, 720px);
  z-index:-1; pointer-events:none;
  /* Starts at exactly the strength the hero ends on, so there is no seam. */
  background:linear-gradient(to bottom, color-mix(in srgb, var(--accent-cool) 16%, transparent), transparent 100%);
  opacity:.85;
}
.hero + .band > *{position:relative}
/* The pair used to be capped and cropped by the fold, on the theory that a cut edge
   tells a visitor there is more. It does not — it tells them the answers are long. Two
   essays cannot be compared at a glance, so each arm is clamped to the same few lines
   and the reader opens them if the lead makes them want to. The clamp is in em, so both
   arms cut at the same line count whatever the window. */
.hero-demo{max-width:var(--page); width:100%; margin:28px auto 0}
.hero-demo[data-clamped] .arm-body{
  max-height:9.6em; overflow:hidden;
  -webkit-mask-image:linear-gradient(to bottom, #000 66%, transparent);
          mask-image:linear-gradient(to bottom, #000 66%, transparent);
}

/* Question chips. The fold held one recorded answer and no way to act on it, which is
   the difference between a screenshot and an application: here the reader picks. */
.pair-pick{margin:0 0 14px}
.pair-pick-label{
  margin:0 0 9px;
  font-family:var(--mono); font-size:11.5px; letter-spacing:.09em;
  text-transform:uppercase; color:var(--ink-faint);
}
.chips{display:flex; flex-wrap:wrap; gap:8px}
.chips button{
  font:inherit; font-size:13.5px; line-height:1.3; color:var(--ink-dim);
  background:transparent; border:1px solid var(--line); border-radius:999px;
  padding:7px 14px; cursor:pointer; word-break:keep-all; text-align:left;
}
.chips button:hover{color:var(--ink); border-color:var(--ink-faint)}
/* The selected chip is deliberately not coral. There is one coral pill in this screen
   and it is the call to action; a second one beside it turns a state indicator into a
   competing button. Selection reads as contrast instead. */
.chips button[aria-pressed="true"]{
  color:var(--ink); font-weight:600;
  border-color:color-mix(in srgb, var(--ink) 45%, transparent);
  background:color-mix(in srgb, var(--ink) 9%, transparent);
}
.pair-watch{
  margin:0 0 16px; font-size:14.5px; line-height:1.6; color:var(--ink-faint);
  max-width:var(--measure); word-break:keep-all;
}
.pair-more{
  font:inherit; font-size:14px; font-weight:600; color:var(--accent);
  background:transparent; border:0; padding:6px 0; margin:10px 0 0; cursor:pointer;
}
.pair-more:hover{text-decoration:underline}
.hero-demo .compare{margin:0}
.hero-demo .cmp-row{min-width:0}
.hero-h1{
  font-size:clamp(34px,6.6vw,78px); margin:0 0 26px;
  font-weight:600; letter-spacing:-.032em; line-height:1.12;
}
.hero-sub{font-size:clamp(17px,1.5vw,19px); color:var(--ink-dim); max-width:60ch; margin:0 0 36px}

.values{list-style:none; margin:0 0 40px; padding:0; display:grid; gap:18px}
@media(min-width:900px){ .values{grid-template-columns:repeat(3,1fr); gap:24px} }
.values li{border-top:2px solid transparent; border-image:var(--grad) 1; padding-top:14px}
.values b{display:block; margin-bottom:6px; font-size:16px}
.values span{color:var(--ink-dim); font-size:15px; line-height:1.6}

.cta-row{display:flex; flex-direction:column; gap:12px; align-items:flex-start}
.cta{
  display:inline-flex; align-items:center; gap:10px; text-decoration:none;
  font-size:clamp(15px,1.4vw,17px); font-weight:600; color:var(--bg);
  background:var(--grad-warm); border-radius:999px; padding:14px 24px;
}
.cta em{font-style:normal; font-family:var(--mono)}
.cta:hover{filter:brightness(1.08)}

/* The divider has to be visible against deep water, where --line is tuned for
   panel edges and disappears at full width. */
.band{
  padding:var(--band) var(--gut);
  border-top:1px solid color-mix(in srgb, var(--ink) 13%, transparent);
}
.band-tight{padding-bottom:clamp(20px,3vh,32px); border-top:0}
.band-inner{max-width:var(--page); margin:0 auto}
.band-disc .band-inner{max-width:var(--measure)}

table{width:100%; border-collapse:collapse; margin:0 0 18px; font-size:15px}
th,td{text-align:left; vertical-align:top; padding:12px 14px; border-top:1px solid var(--line)}
thead th{
  font-family:var(--mono); font-size:12px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink-faint); border-top:0; font-weight:500;
}
tbody th{color:var(--ink-dim); font-weight:500; width:8em}
td{color:var(--ink-dim)}
tfoot td{font-size:13px; color:var(--ink-faint); font-family:var(--mono)}
.diff td.is-reef{background:color-mix(in srgb,var(--accent) 6%,transparent)}

/* ---------- 2. comparison ---------- */
.brief{
  margin:0 0 22px; padding:0 0 0 18px; border-left:3px solid transparent; border-image:var(--grad-v) 1;
  font-size:clamp(20px,3vw,30px); font-weight:600; line-height:1.4;
}
/* The sources, browsable. Groups on the left as an accordion, the chosen file on the
   right, the way a repository host lays it out — because that is the shape a reader
   already knows how to use. */
/* The bar is fixed, so scrolling this into view puts its own top — and on a phone the
   back button with it — underneath the bar. --bar is measured by the shell and kept
   measured, because the bar wraps to two rows on a narrow screen. */
.src-browser{
  display:grid; gap:14px; margin-bottom:18px;
  scroll-margin-top:calc(var(--bar, 68px) + 12px);
}
@media(min-width:900px){ .src-browser{grid-template-columns:minmax(260px,34%) 1fr; align-items:start} }
.src-tree{display:grid; gap:8px}
.src-group{background:var(--panel); border:1px solid var(--line); border-radius:12px; overflow:hidden}
.src-group.is-docs{border-color:color-mix(in srgb, var(--accent) 55%, transparent)}
.src-group summary{
  display:flex; align-items:baseline; gap:10px; padding:12px 14px; cursor:pointer;
  font-family:var(--mono); font-size:13px; color:var(--ink); list-style:none;
}
.src-group summary::-webkit-details-marker{display:none}
.src-group summary::before{content:"▸"; color:var(--ink-faint); font-size:11px; flex:0 0 auto}
.src-group[open] summary::before{content:"▾"}
.src-group summary .src-kind{font-family:var(--sans); font-size:12.5px; color:var(--ink-faint); flex:1}
.src-group summary b{font-size:15px; font-family:var(--mono); color:var(--ink-dim)}
.src-group ul{margin:0; padding:4px 0 8px; list-style:none; max-height:300px; overflow-y:auto; border-top:1px solid var(--line)}
.src-group li button{
  display:block; width:100%; text-align:left; font:inherit; font-family:var(--mono); font-size:12px;
  color:var(--ink-dim); background:transparent; border:0; padding:6px 14px 6px 30px; cursor:pointer;
  overflow-wrap:anywhere;
}
.src-group li button:hover{color:var(--ink); background:color-mix(in srgb, var(--ink) 4%, transparent)}
.src-group li button[aria-current="true"]{color:var(--accent); background:color-mix(in srgb, var(--accent) 9%, transparent)}
.src-view{background:var(--code-bg); border:1px solid var(--line); border-radius:12px; overflow:hidden; min-width:0}
.src-view-bar{
  display:flex; align-items:center; gap:12px; padding:10px 14px; border-bottom:1px solid var(--line);
  font-family:var(--mono); font-size:12px; color:var(--ink-faint);
}
.src-view-path{flex:1; min-width:0; color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.src-view-meta{flex:0 0 auto; white-space:nowrap}
.src-view-link{flex:0 0 auto; color:var(--accent); text-decoration:none; white-space:nowrap}
.src-view-link:hover{text-decoration:underline}
.src-view-body{
  margin:0; padding:14px 16px; height:clamp(320px,56vh,560px); overflow:auto;
  font-family:var(--mono); font-size:12.5px; line-height:1.55; color:var(--code-ink);
  white-space:pre; tab-size:4;
}
.excluded{margin-top:10px}
summary{cursor:pointer; font-size:13px; color:var(--ink-faint); font-family:var(--mono)}
.excluded ul{margin:10px 0 0; padding-left:16px; max-height:220px; overflow-y:auto}
.excluded li{font-size:12px; color:var(--ink-faint); margin-bottom:4px}

.steps{margin:0 0 16px; padding-left:22px; max-width:var(--measure)}
.steps li{color:var(--ink-dim); margin-bottom:12px}
.steps code{color:var(--accent)}

.fair{
  margin:0 0 22px; padding:14px 16px; border:1px dashed var(--line); border-radius:8px;
  font-size:14px; color:var(--ink-dim); max-width:var(--measure);
}
.chat-chips{display:flex; flex-wrap:wrap; gap:8px; margin-bottom:14px}
.chip{
  font:inherit; font-size:14px; text-align:left; background:var(--panel);
  color:var(--ink-dim); border:1px solid var(--line); border-radius:999px;
  padding:7px 14px; cursor:pointer;
}
.chip:hover{color:var(--ink); border-color:var(--accent)}
.chat-form{display:flex; gap:8px; margin:0 0 10px; flex-wrap:wrap}
.chat-input{
  flex:1 1 240px; min-width:0; font:inherit; font-size:15px; background:var(--bg-soft);
  color:var(--ink); border:1px solid var(--line); border-radius:8px; padding:11px 14px;
}
.chat-input:focus{outline:none; border-color:var(--accent)}
.chat-form button{
  font:inherit; font-size:15px; background:var(--grad-warm); color:var(--bg);
  border:0; border-radius:8px; padding:11px 20px; cursor:pointer;
}
.chat-form[aria-busy="true"]{opacity:.55; pointer-events:none}
.chat-offline{font-size:14px; color:var(--ink-faint); margin:0 0 14px}

.compare{display:grid; gap:26px; margin:22px 0 14px}
.cmp-q{
  font-size:clamp(16px,1.8vw,19px); font-weight:600; margin:0 0 12px;
  padding-bottom:12px; border-bottom:1px solid var(--line);
}
.cmp-arms{display:grid; gap:14px}
@media(min-width:900px){ .cmp-arms{grid-template-columns:1fr 1fr; align-items:start} }
.arm{margin:0; padding:16px 18px; min-width:0}
.arm-reef{border-color:color-mix(in srgb, var(--accent) 48%, transparent)}
.arm-head{display:flex; justify-content:space-between; align-items:baseline; gap:10px; margin-bottom:12px}
.arm-head b{font-size:15px}
.arm-reef .arm-head b{color:var(--accent)}
.arm-body{font-size:15px; color:var(--ink-dim)}
.arm-body p{margin:0 0 10px} .arm-body p:last-child{margin:0}
.arm-body b{color:var(--ink); font-weight:600}
.arm-meta{font-family:var(--mono); font-size:11.5px; color:var(--ink-faint); margin:12px 0 0}
/* The waiting state. It used to be three static full stops, which on a live call is
   twenty-odd seconds of a page that looks broken. Now: dots that move, what it is
   waiting for in words, and the seconds counting up on the right. */
.thinking{
  display:flex; align-items:center; gap:10px;
  font-size:14px; color:var(--ink-faint);
}
.thinking-dots{display:inline-flex; gap:4px; flex:0 0 auto}
.thinking-dots i{
  width:5px; height:5px; border-radius:50%; background:currentColor; opacity:.25;
  animation:thinking 1.3s ease-in-out infinite;
}
.thinking-dots i:nth-child(2){animation-delay:.16s}
.thinking-dots i:nth-child(3){animation-delay:.32s}
@keyframes thinking{
  0%,70%,100%{opacity:.22; transform:translateY(0)}
  35%{opacity:1; transform:translateY(-3px)}
}
/* Pushed to the far edge so it reads as a clock rather than part of the sentence. */
.thinking-clock{margin-left:auto; font-family:var(--mono); font-size:11.5px; opacity:.7}

/* While one pair is in flight the controls are held, so they have to look held. */
.chat-chips button:disabled{opacity:.45; cursor:default}
.chat-form.is-busy{opacity:.6}
.chat-form input:disabled,.chat-form button:disabled{cursor:default}

.cite{
  font-family:var(--mono); font-size:11.5px; line-height:1.4; cursor:pointer;
  background:color-mix(in srgb,var(--accent) 9%,transparent); color:var(--accent);
  border:1px solid color-mix(in srgb,var(--accent) 34%,transparent);
  border-radius:5px; padding:1px 5px; text-decoration:none; display:inline-block;
}
.cite:hover{background:color-mix(in srgb,var(--accent) 18%,transparent)}
.cite-plain{font-family:var(--mono); font-size:11.5px; color:var(--ink-faint); padding:1px 5px}

.artifact-panel{
  margin-top:20px; background:var(--bg-soft); border:1px solid color-mix(in srgb, var(--accent) 55%, transparent);
  border-radius:10px; padding:16px 18px;
}
.artifact-head{display:flex; align-items:center; gap:10px; margin-bottom:10px}
.artifact-title{font-family:var(--mono); font-size:13px; margin:0; flex:1; color:var(--ink)}
.artifact-close{
  font:inherit; font-size:12px; background:transparent; color:var(--ink-faint);
  border:1px solid var(--line); border-radius:6px; padding:3px 9px; cursor:pointer;
}
.artifact-panel ul{margin:8px 0 14px; padding-left:18px}
.artifact-panel li{margin-bottom:8px; color:var(--ink-dim); font-size:14px}
.artifact-panel .src{display:block; margin-top:3px}

/* ---------- 3. details ---------- */
.repo-list{display:grid; gap:12px; margin-bottom:18px}
@media(min-width:840px){ .repo-list{grid-template-columns:repeat(3,1fr)} }
.repo{
  display:block; text-decoration:none; background:var(--panel);
  border:1px solid var(--line); border-radius:16px; padding:18px;
}
.repo:hover{border-color:var(--accent)}
.repo b{display:block; font-family:var(--mono); font-size:16px; color:var(--accent); margin-bottom:8px}
.repo span{display:block; color:var(--ink-dim); font-size:14px; line-height:1.55; margin-bottom:10px}
.repo em{font-style:normal; font-family:var(--mono); font-size:12px; color:var(--ink-faint)}

.figures{display:flex; flex-wrap:wrap; gap:20px 36px; margin:0 0 20px}
.fig b{display:block; font-family:var(--mono); font-size:clamp(26px,4vw,38px); color:var(--accent); line-height:1.1}
.fig span{font-size:13px; color:var(--ink-faint)}

.caution{border-left:2px solid var(--warn); padding-left:14px}
.paper{margin:0 0 18px}
.paper-title{margin:10px 0 2px; font-weight:600; color:var(--ink)}
.paper ul{margin:14px 0; padding-left:18px}
.paper li{color:var(--ink-dim); font-size:15px; margin-bottom:8px}
.answers,.limits{margin:0; padding-left:22px; max-width:var(--measure)}
.answers li,.limits li{color:var(--ink-dim); margin-bottom:14px}

/* ---------- the few blocks the modules build by hand ---------- */
/* The comparison section carries the page, so it gets the room. */
.band-ask{padding-bottom:clamp(56px,9vh,96px)}
.cmp-row{min-width:0}
/* Newest comparison first, so an answer never appears below the fold. */
.compare{grid-auto-flow:row}

.artifact-body{font-size:14px}
.artifact-link{display:inline-block; margin-top:4px}

/* Two comparison tables on the details page: the benchmark and the stack. */
.bench tbody th,.stack tbody th{width:14em}
.bench td.is-reef{background:color-mix(in srgb,var(--accent) 6%,transparent)}
.bench tfoot td{border-top:1px solid var(--line); line-height:1.5}
.stack td code{color:var(--ink-dim)}
@media(max-width:620px){
  .bench tbody th,.stack tbody th,tbody th{width:auto}
  th,td{padding:10px 8px}
  table{font-size:14px}
}

/* On a phone the three value blocks push the button three screens down, and the button
   is the point of the page. Below the breakpoint the button comes first and the values
   read as support underneath it. */
.hero-inner{display:flex; flex-direction:column}
.values{order:3}
.cta-row{order:2; margin-bottom:34px}
@media(min-width:760px){
  .values{order:2; margin-bottom:40px}
  .cta-row{order:3; margin-bottom:0}
}

/* The line under the call to action is an invitation, not metadata. */
.cta-note{margin:0; font-size:15px; line-height:1.65; color:var(--ink-dim); max-width:62ch; word-break:keep-all}

/* The one-line descriptor under the headline. It states what the thing is, so it sits
   close to the headline and reads as part of it rather than as body copy. */
.hero-desc{
  margin:-8px 0 36px; font-size:clamp(16px,1.6vw,19px); color:var(--ink-dim);
  max-width:60ch;
}

/* ---------- landing: the skill flow ---------- */
h3{font-size:clamp(18px,2.1vw,24px); margin:44px 0 14px; font-weight:600; color:var(--ink)}
.phase{
  font-family:var(--mono); font-size:12px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--accent); margin:28px 0 14px;
}
.flow{list-style:none; margin:0; padding:0; display:grid; gap:10px}
@media(min-width:900px){ .flow{grid-template-columns:repeat(4,1fr); gap:22px} }
.flow li{
  position:relative; background:var(--panel); border:1px solid var(--line);
  border-radius:16px; padding:18px 18px; min-width:0;
}
.flow code{display:block; color:var(--accent); font-size:13px; margin-bottom:2px}
.flow code + code{margin-top:0}
.flow span{display:block; margin-top:8px; font-size:14px; color:var(--ink-dim); line-height:1.55}
/* The step a person takes, not the tool. It is the one that makes the loop compound,
   so it does not look like the three commands beside it. */
.flow .is-human{background:transparent; border-style:dashed; border-color:var(--accent)}
.flow .who{
  display:inline-block; margin:0; font-family:var(--mono); font-size:13px;
  color:var(--accent);
}
/* Arrows between steps, on the axis the row currently runs along. */
@media(min-width:900px){
  .flow li:not(:first-child)::before{
    content:"→"; position:absolute; left:-17px; top:50%; transform:translateY(-50%);
    color:var(--accent); font-family:var(--mono); font-size:15px; line-height:1;
  }
}
/* A closed box. It used to hang off the bottom of the bordered cards the flow was
   built from, which is why it had no top edge and only bottom corners; the deck that
   replaced them is borderless rows, so the open top attached to nothing and read as
   a missing border. Same dashed treatment as .fair, which is the other aside here. */
.loop-back{
  display:flex; gap:10px; align-items:baseline; margin:12px 0 28px; padding:12px 16px;
  border:1px dashed var(--line); border-radius:10px;
  font-size:14px; color:var(--ink-dim);
}
.loop-mark{color:var(--accent); font-size:18px; line-height:1}
.cta-quiet{background:transparent; color:var(--accent); border:1px solid color-mix(in srgb, var(--accent) 55%, transparent)}
.cta-quiet:hover{background:color-mix(in srgb,var(--accent) 12%,transparent); filter:none}
.band .cta{margin-top:10px}

/* ---------- landing: the three questions, and where it fits ---------- */
.questions{list-style:none; margin:0 0 8px; padding:0; counter-reset:q; display:grid; gap:20px}
@media(min-width:900px){ .questions{grid-template-columns:repeat(3,1fr); gap:26px} }
.questions li{counter-increment:q; border-top:2px solid transparent; border-image:var(--grad) 1; padding-top:14px}
.questions b{display:block; margin-bottom:8px; font-size:16px}
.questions b::before{
  content:counter(q); font-family:var(--mono); color:var(--accent);
  margin-right:8px; font-weight:400;
}
.questions span{color:var(--ink-dim); font-size:15px; line-height:1.6}
/* Where it fits, and where it does not — the second half is the part that earns trust,
   so it is not styled as a warning. */
.fit{margin-bottom:8px}
.fit-yes{border-left:2px solid transparent; border-image:var(--grad-v) 1; padding-left:16px}
.fit-no{border-left:2px solid var(--line); padding-left:16px}
.fit .phase{margin-top:0}
.fit .body{max-width:none}

/* The AI-use list: a heading per item, then the explanation. Scoped to the direct
   child, because the explanations contain their own inline <b> emphasis. */
.answers li > b{display:block; margin-bottom:6px; color:var(--ink)}
.answers li > span{display:block; color:var(--ink-dim)}
.answers li > span b{color:var(--ink)}

/* ---------- screenshot mode (?shot=) ---------- */
/* The only section left visible sits at the top of the document, which is where a
   headless capture looks. No nav, no chrome, no interaction affordances. */
body[data-shot] .topbar{display:none}
body[data-shot] main{padding-top:0}
body[data-shot] .band,body[data-shot] .hero{
  border-top:0; opacity:1; padding-top:clamp(32px,6vh,56px);
}
body[data-shot] footer{display:none}
body[data-shot] .chat-chips{display:none}
body[data-shot] .chat-form{display:none !important}
body[data-shot] .chat-offline{display:none}
body[data-shot] .cta{display:none}
body[data-shot] details{display:none}
/* In the comparison shot the section heading and its intro cost 150px the answers
   need. The fairness note stays — it is the part of that section worth capturing. */
body[data-shot="ask"] h2,
body[data-shot="ask"] [data-i18n="T.askNote"]{display:none}
/* A short section left at the top of a 16:9 frame leaves the bottom half empty, so
   every shot but the comparison is centred. The comparison is taller than the frame
   and must stay top-aligned, or centring would cut its first lines. */
body[data-shot]:not([data-shot="ask"]):not([data-shot="1"]) main{
  min-height:100vh; display:flex; align-items:center;
}
body[data-shot]:not([data-shot="ask"]):not([data-shot="1"]) main > section{width:100%}
/* The cover is the hero exactly as a visitor meets it, crop included, so it is left
   alone apart from keeping the button that shot mode otherwise hides. */
body[data-shot="1"] .cta{display:inline-flex}

/* The hero pair is a still, not a conversation: tighter type, no interaction chrome. */
.hero-demo .arm{padding:14px 16px}
.hero-demo .arm-body{font-size:14px}
.hero-demo .cmp-q{font-size:clamp(15px,1.6vw,17px); padding-bottom:10px; margin-bottom:10px}
.hero-demo .arm-meta{display:none}

/* Evidence sits immediately under the fold, so it gets the emphasis a first section
   would otherwise spend on a heading. */
.band-strip{border-top:0}
.band-strip .figures{margin-top:4px}
.band-strip .cta{margin-top:18px}

/* The artifact panel is fixed on the landing page, because the citation that opened it
   may be anywhere in the fold. */
.hero ~ .artifact-panel,
main > .artifact-panel{
  position:fixed; inset:auto var(--gut) 20px var(--gut); z-index:30; margin:0;
  max-width:760px; margin-inline:auto; max-height:56vh; overflow-y:auto;
  box-shadow:var(--panel-shadow);
}

/* ---------- light-mode character ---------- */
/* One soft wash behind the hero. The gallery's rule is that a single gradient behind
   the hero is fine and a page that shimmers everywhere reads as a template. */
.hero{position:relative; isolation:isolate}
/* One bloom, behind everything, bleeding off the top. A single soft light source is
   the whole of "restraint with the glow" — the page does not shimmer anywhere else. */
.hero::before{
  content:""; position:absolute; inset:-25% -10% 0 -10%;
  z-index:-1; pointer-events:none;
  background:
    radial-gradient(56% 56% at 50% 26%, color-mix(in srgb, var(--accent-warm) 22%, transparent), transparent 72%),
    linear-gradient(to bottom, transparent 40%, color-mix(in srgb, var(--accent-cool) 16%, transparent) 100%);
  opacity:.85;
}

/* The two arms should not look interchangeable: the reef side is tinted, the side
   without one is left plain. */
.arm-reef{background:var(--panel)}


/* "Not determinable" is a defined term in the artifact contract and it is the whole
   difference between the two answers, so it is marked rather than left to be found. */
.arm-body mark{
  background:var(--accent-wash); color:inherit; padding:1px 3px; border-radius:3px;
  box-shadow:inset 0 -2px 0 var(--accent);
}

/* Figures carry the evidence; they were sized like captions. */
.fig b{font-size:clamp(34px,5.5vw,52px); letter-spacing:-.02em}
.fig span{font-size:14px}

/* Cards respond, which on a light page reads as "this is a thing you can use". */
.repo{transition:transform .15s ease, box-shadow .15s ease}
.repo:hover{transform:translateY(-2px); box-shadow:var(--panel-shadow)}
.cta{transition:transform .15s ease, filter .15s ease}
.cta:hover{transform:translateY(-1px)}


/* The two kinds of citation are not the same claim, so they are not the same colour.
   A coral chip is an artifact — something the reef wrote and stands behind. A sea-green
   one is a file in the repository, which nobody wrote a claim about. It also keeps the
   coral for the things that are actually reef's. */
a.cite{
  background:transparent;
  color:var(--ink-dim);
  border-color:var(--line);
}
a.cite:hover{color:var(--ink); border-color:var(--ink-faint)}

/* ---------- the bar's right-hand group, and its phone form ---------- */
.bar-end{display:flex; align-items:center; gap:16px; margin-left:auto}
.menu-toggle{
  display:none; align-items:center; justify-content:center;
  width:38px; height:38px; padding:0; cursor:pointer;
  background:transparent; color:var(--ink); border:1px solid var(--line); border-radius:8px;
}
.menu-toggle svg{width:20px; height:20px}
.menu-toggle .bar-a,.menu-toggle .bar-b,.menu-toggle .bar-c{
  transition:transform .18s ease, opacity .18s ease; transform-origin:center;
}
/* Rotate last, not first. The bars sit at y=7 and y=17 in a 24-unit box whose centre
   — and so the transform origin — is y=12, so each one has to travel to the middle
   before it turns. Written the other way round the rotation happens five units off
   centre and swings the stroke out with it: the two ends still cross, but at 14.1
   rather than 12, which is the X sitting visibly right of the button it is in. */
.menu-toggle[aria-expanded="true"] .bar-a{transform:rotate(45deg) translateY(5px)}
.menu-toggle[aria-expanded="true"] .bar-b{opacity:0}
.menu-toggle[aria-expanded="true"] .bar-c{transform:rotate(-45deg) translateY(-5px)}

@media(max-width:720px){
  /* On a phone the links and the language switch fold away, so the bar is one row:
     the brand, the theme, and the menu. */
  .menu-toggle{display:inline-flex; margin-left:auto}
  .bar-end{
    display:none; order:3; width:100%; margin:0;
    flex-direction:column; align-items:stretch; gap:10px;
    padding:14px 0 4px; border-top:1px solid var(--line);
  }
  .bar-end[data-open]{display:flex}
  .nav{flex-direction:column; gap:2px}
  .nav a{padding:11px 12px; font-size:16px}
  .lang{align-self:flex-start}
}


/* The section marker: what this part of the page is, in two words, before the
   heading says anything. Walkie's is the clearest example of why it works — it gives
   the eye somewhere to land at the top of every section. */
.section-label{
  font-family:var(--mono); font-size:12px; letter-spacing:.18em; text-transform:uppercase;
  color:var(--ink-faint); margin:0 0 14px;
}

/* The wordmark: the same two waves as the icon, then the name. */
.brand{display:inline-flex; align-items:center; gap:9px}
.brand-mark{width:26px; height:20px; color:var(--ink); flex:0 0 auto}
.brand{opacity:1; transition:opacity .15s ease}
.brand:hover{opacity:.72}

/* Text painted with the accent range. Guarded: without background-clip the rule set
   never applies and the element keeps its solid accent colour, rather than going
   transparent and disappearing. */
@supports (background-clip:text) or (-webkit-background-clip:text){
  .hero .kicker, .fig b{
    background:var(--grad-warm);
    -webkit-background-clip:text; background-clip:text;
    color:transparent; -webkit-text-fill-color:transparent;
  }
}


/* ---------- landing: the terminal replay ---------- */
.cast{
  margin:28px 0 0; padding:0; white-space:normal; border:1px solid var(--line); border-radius:12px;
  background:var(--code-bg); overflow:hidden; box-shadow:var(--panel-shadow);
  transition:opacity .4s ease;
}
.cast[data-fading]{opacity:0}
.cast-bar{
  display:flex; align-items:center; gap:12px; padding:10px 14px;
  border-bottom:1px solid var(--line);
  font-family:var(--mono); font-size:12px; color:var(--ink-faint);
}
.cast-dots{display:inline-flex; gap:6px}
.cast-dots i{display:block; width:10px; height:10px; border-radius:50%; background:var(--line)}
.cast-title{flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.cast-clock{color:var(--ink-dim); font-variant-numeric:tabular-nums}
.cast-body{
  height:clamp(320px, 54vh, 480px); overflow:auto; padding:16px 18px;
  font-family:var(--mono); font-size:13px; line-height:1.55; color:var(--code-ink);
  white-space:pre-wrap; overflow-wrap:anywhere;
}
.cast-body .tl{display:block}
.cast-body .in{color:var(--ink); margin-top:2px}
.cast-body .in::before{content:"❯ "; color:var(--accent)}
.cast-body .ask{color:var(--accent-warm)}
.cast-body .ans{color:var(--ink-dim)}
.cast-body .art{color:var(--ink-faint)}
.cast-body .cur{
  display:inline-block; width:.6em; height:1.05em; background:var(--accent);
  vertical-align:-.15em; animation:blink 1s steps(1) infinite;
}
@keyframes blink{50%{opacity:0}}
@media (prefers-reduced-motion:reduce){
  .cast-body .cur{animation:none} .cast{transition:none}
  /* The dots stop moving, but they stay visible and the clock keeps counting — the
     reader still needs to know the answer is coming. */
  .thinking-dots i{animation:none; opacity:.6}
}


/* ---------- landing: the zone map ---------- */
/* One column, read top to bottom, because that is the direction truth flows in and the
   layout should say so without an arrowhead having to. The governance zone spans the
   top like a rule everything under it is subject to. */
.zones{margin:32px 0 18px; display:grid; gap:0}
.zone{
  display:grid; grid-template-columns:minmax(150px, 210px) 1fr; gap:10px 28px;
  padding:20px 22px; border:1px solid var(--line); border-radius:12px; background:var(--panel);
}
@media(max-width:620px){ .zone{grid-template-columns:1fr; gap:8px; padding:16px 18px} }
.zone-path{font-family:var(--mono); font-size:14px; color:var(--accent); align-self:start; padding-top:3px; word-break:break-all}
.zone b{display:block; font-size:17px; margin-bottom:6px; color:var(--ink)}
.zone span{display:block; font-size:15px; line-height:1.6; color:var(--ink-dim); word-break:keep-all}
.zone em{display:block; font-style:normal; font-size:14px; line-height:1.55; color:var(--ink-faint); margin-top:8px; word-break:keep-all}
.zone code{font-size:13px; color:var(--ink)}
.zone-gov{
  margin-bottom:22px; border-style:dashed;
  border-color:color-mix(in srgb, var(--ink) 22%, transparent); background:transparent;
}
.zone-core{border-color:color-mix(in srgb, var(--accent) 55%, transparent); background:var(--bg-soft)}
.zone-read{background:transparent}
.zone-flow{
  display:flex; gap:14px; align-items:flex-start; margin:0; padding:14px 22px 14px 30px;
  font-size:14.5px; line-height:1.6; color:var(--ink-dim); word-break:keep-all;
  border-left:1px solid color-mix(in srgb, var(--accent) 45%, transparent); margin-left:44px;
}
@media(max-width:620px){ .zone-flow{margin-left:22px; padding-left:18px} }
.zone-arrow{font-family:var(--mono); color:var(--accent); flex:0 0 auto; line-height:1.6}


/* ---------- landing: one skill per row, its replay beside it ---------- */
.stages{display:grid; gap:0; margin:8px 0 26px}
.stage{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:20px 32px;
  align-items:start; padding:22px 0; border-top:1px solid var(--line);
}
.stage:first-child{border-top:0}
@media(max-width:900px){ .stage{grid-template-columns:1fr; gap:14px} }
.stage-copy code{
  display:inline-block; font-family:var(--mono); font-size:14px; color:var(--accent);
  margin:0 10px 8px 0; padding-top:2px;
}
.stage-copy p{margin:0; font-size:16px; line-height:1.65; color:var(--ink-dim); max-width:46ch; word-break:keep-all}
.stage-copy .who{
  display:inline-block; font-family:var(--mono); font-size:12px; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink); border:1px dashed var(--accent);
  border-radius:999px; padding:3px 10px; margin:0 10px 8px 0;
}
.stage-text{grid-template-columns:1fr}
.stage .cast{margin:0}
.stage .cast-body{height:clamp(220px, 34vh, 320px); font-size:12.5px; padding:14px 16px}
.h3-gap{margin-top:56px}
h3.phase{margin-top:34px}

/* Chips. One vocabulary for the whole page: a solid chip is a thing that exists (a
   path, a file, a field, a command), a dashed chip is a rule it runs under, and a
   coloured one is an artifact type. Small, mono, and never a sentence. */
.chips-row{display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin-top:8px}
.cl{
  font-family:var(--mono); font-size:10.5px; letter-spacing:.09em; text-transform:uppercase;
  color:var(--ink-faint); min-width:6.5em;
}
.ch{
  display:inline-block; font-family:var(--mono); font-size:12px; line-height:1.3;
  padding:4px 9px; border-radius:6px; color:var(--ink-dim);
  border:1px solid var(--line); background:color-mix(in srgb, var(--ink) 4%, transparent);
  white-space:nowrap;
}
.ch-type{color:var(--accent); border-color:color-mix(in srgb, var(--accent) 40%, transparent); background:color-mix(in srgb, var(--accent) 8%, transparent)}
.ch-cmd{color:var(--ink)}
.ch-rule{font-family:var(--sans); font-size:12.5px; border-style:dashed; background:transparent; white-space:normal; word-break:keep-all}
.ch-yes,.ch-no{font-family:var(--sans); font-size:13.5px; padding:6px 12px; white-space:normal}
.ch-yes{color:var(--ink); border-color:color-mix(in srgb, var(--accent) 45%, transparent)}
.ch-no{color:var(--ink-faint)}
.chips-lg{margin:10px 0 12px}
.stage-tech{margin:10px 0 0}
.zone .chips-row{margin-top:10px}

/* The spine. The rows are one pass of a loop, not eleven independent entries, so on
   a wide screen they hang off a single line with a node each — and the line runs on
   past the last one and turns back into the note that says the next pass starts here.
   Below the breakpoint the deck is a stepper showing one row at a time, where a rail
   joining rows that are not on screen together would mean nothing; none of this
   applies there. */
@media(min-width:900px){
  .stage-deck{position:relative; padding-left:34px}
  .stage-deck::before{
    /* 2px on a centre of 11.5, which is where the nodes are — widening from the
       left edge instead would walk the line off them by half a pixel. */
    content:""; position:absolute; left:10.5px; top:10px; bottom:-14px; width:2px;
    border-radius:2px;
    /* Fades in under the first phase label and runs warm to cool down the pass, so
       the eye is told where it starts without a hard cap on the line. */
    background:linear-gradient(to bottom,
      transparent 0,
      color-mix(in srgb, var(--accent) 85%, transparent) 56px,
      color-mix(in srgb, var(--accent-cool) 82%, transparent) 78%,
      color-mix(in srgb, var(--accent-cool) 82%, transparent) 100%);
  }
  /* One node per row, on the rail, level with the command that names the row. */
  .stage{position:relative}
  .stage::before{
    /* 32px puts the node's centre on the command's, measured — the row's 22px of
       padding plus the code chip's own half-height. */
    content:""; position:absolute; left:-27px; top:32px;
    width:9px; height:9px; border-radius:50%; box-sizing:border-box;
    background:var(--bg); border:2px solid var(--accent);
    /* A ring of page colour, so the rail reads as passing behind each node rather
       than butting into it. */
    box-shadow:0 0 0 3px var(--bg);
  }
  /* The row a person does, not a command: hollow and dashed, like the .who chip. */
  .stage.is-human::before{border-style:dashed; border-color:var(--accent)}
  /* A phase label crosses the rail rather than sitting beside it. */
  .stage-deck h3.phase{position:relative}
  .stage-deck h3.phase::before{
    content:""; position:absolute; left:-27px; top:.62em; width:9px; height:2px;
    background:var(--accent); box-shadow:0 0 0 3px var(--bg);
  }
  /* The turn back. The rail carries on below the last row, then curves in to meet
     the note at its ↺ — dashed, because this is the return and not the pass. */
  .loop-back{margin-left:34px; position:relative}
  .loop-back::before{
    content:""; position:absolute; left:-23.5px; top:-26px; height:calc(50% + 26px);
    width:22px; border-left:2px dashed var(--accent-cool);
    border-bottom:2px dashed var(--accent-cool); border-bottom-left-radius:10px;
  }
}

/* On a phone the eleven rows of the flow are eleven screens of scrolling with a
   terminal in every one, so the deck shows a single step and the reader pages through
   it. Nothing here applies above the breakpoint; the desktop keeps the full column. */
.stage-nav{
  display:flex; flex-wrap:nowrap; align-items:center; justify-content:space-between; gap:10px;
  margin:6px 0 0; padding:12px 0 0; border-top:1px solid var(--line);
}
.stage-nav button{
  flex:0 0 auto; font:inherit; font-size:14px; font-weight:600; color:var(--accent);
  background:transparent; border:1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius:999px; padding:9px 16px; cursor:pointer;
}
.stage-nav button:disabled{opacity:.3; cursor:default}
.stage-pos{flex:1 1 auto; min-width:0; display:flex; flex-direction:column; align-items:center; gap:2px; text-align:center}
.stage-phase{font-size:12px; color:var(--ink); font-weight:600; word-break:keep-all}
.stage-count{font-family:var(--mono); font-size:11.5px; color:var(--ink-faint); letter-spacing:.06em}
@media(max-width:900px){
  .stage-deck[data-stepper] .stage{display:none; border-top:0; padding-top:8px}
  .stage-deck[data-stepper] .stage[data-active]{display:grid}
  .stage-deck[data-stepper] h3.phase{display:none}
  .stage-deck[data-stepper] .stages{margin:0}
}

/* The sources browser on a phone: one pane at a time. */
.src-back{display:none}
@media(max-width:900px){
  /* The list drops its own scroller here. Capped at 300px it is a porthole inside a
     page that also scrolls — order-service alone puts 3,800px of file names behind it,
     and a drag inside the porthole never moves the page. Only one group is open at a
     time, so letting it run its natural height leaves the page as the single scroller. */
  .src-group ul{max-height:none; overflow-y:visible}
  .src-browser[data-mode] .src-view{display:none}
  .src-browser[data-mode="file"] .src-view{display:block}
  .src-browser[data-mode="file"] .src-tree{display:none}
  .src-browser[data-mode="file"] .src-back{
    display:inline-block; flex:0 0 auto; font:inherit; font-family:var(--mono); font-size:12px;
    color:var(--accent); background:transparent; border:0; padding:0 4px 0 0; cursor:pointer;
  }
  /* A cap, not a height. Beside the tree on a desktop the pane holds a fixed size so
     the two columns do not jump as files change; alone on a phone that same fixed size
     hangs three hundred pixels of nothing under an eleven-line file. */
  .src-browser[data-mode="file"] .src-view-body{
    height:auto; max-height:min(62vh, 560px);
    white-space:pre-wrap; overflow-wrap:anywhere;
  }
}

/* The cover shot: the hero fills the 16:9 frame with its copy centred, rather than
   sitting in the top half of it over nothing. */
body[data-shot] .hero{
  min-height:100vh; justify-content:center; margin-top:0; padding-top:0; padding-bottom:0;
}

/* ---------- the sections added for the repositioned narrative ---------- */

/* The line under the call to action. The hero states what reef is; this says what
   kind of thing it is, which is the part a reader carries into the next section. */
.hero-note{
  /* The hero is centred, so this has to centre with it: a max-width alone leaves the
     line hanging off the left of everything above it. */
  margin:18px auto 0; font-size:14.5px; line-height:1.65; color:var(--ink-faint);
  max-width:52ch; text-align:center; word-break:keep-all;
}

/* The last line of the problem section, which is the first mention of reef on the
   page. It is a body line, so it is not a heading — but it is the turn, so it is not
   dimmed with the rest either. */
.lede-close{color:var(--ink); margin-top:22px}

/* What reef leaves behind, as four numbered properties. A list rather than cards:
   they are read in order — evidence, then the gaps, then staleness, then the human —
   and a grid of four boxes would invite reading any one of them alone. */
.makes{list-style:none; margin:26px 0 0; padding:0; display:grid; gap:2px}
.makes li{
  display:flex; gap:18px; align-items:baseline;
  padding:20px 0; border-top:1px solid var(--line);
}
.makes li:last-child{border-bottom:1px solid var(--line)}
.makes-n{
  font-family:var(--mono); font-size:12px; letter-spacing:.1em; color:var(--accent);
  flex:0 0 auto; padding-top:2px;
}
.makes li>div{min-width:0}
.makes b{display:block; font-size:clamp(16px,1.8vw,19px); color:var(--ink); margin-bottom:6px}
.makes span{
  display:block; font-size:14.5px; line-height:1.65; color:var(--ink-dim);
  max-width:var(--measure); word-break:keep-all;
}
.makes code{font-family:var(--mono); font-size:13px; color:var(--accent)}

/* What to look at in the two answers. The instruction sits above; these are the three
   things to check, and they are deliberately checkable rather than persuasive. */
.watch-list{margin:-8px 0 16px; padding-left:20px; max-width:var(--measure)}
.watch-list li{
  font-size:14px; line-height:1.6; color:var(--ink-faint); margin-bottom:5px;
  word-break:keep-all;
}

/* The three checkpoints the build log supports, on the brief. Each number is only as
   good as the timestamp beside it in log.md, which is why the last cell counts the
   timestamps themselves. */
.result-strip{
  display:flex; flex-wrap:wrap; gap:14px 32px; margin:22px 0 18px; padding:0;
}
.result-strip div{margin:0}
.result-strip dt{
  font-family:var(--mono); font-size:clamp(20px,2.8vw,28px); color:var(--accent);
  line-height:1.15;
}
.result-strip dd{margin:4px 0 0; font-size:13px; color:var(--ink-faint)}

/* The closing statement. Four lines that each end, so they are set as separate
   paragraphs rather than one block that the eye runs through. */
.band-final .band-inner{max-width:var(--measure)}
.final-line{margin:0 0 10px; color:var(--ink-dim)}
.final-last{
  margin:26px 0 0; font-size:clamp(16px,1.9vw,20px); line-height:1.6; color:var(--ink);
  word-break:keep-all;
}

/* ---------- the page's own entrance ---------- */

/* All of it arrives from data — i18n text, chips, the terminal replays, the
   comparison — so with no reveal treatment the page used to sit blank (structure
   only, no text) for however long that takes, then snap into place all at once. On
   a slow connection that reads exactly like something broke, not like something is
   loading. This fades the whole page in as one deliberate motion instead, once
   site.js's reveal() says everything that page needs is actually in the DOM.

   The `html{background:...}` inline style in <head> keeps painting underneath
   regardless — only body's own content fades, never the page going white or black. */
body{
  opacity:0; transition:opacity .28s ease;
  /* Safety net: if boot() never runs — a script error, JS disabled, a data file that
     404s somewhere this catch-free path did not anticipate — the page must not stay
     blank forever. This snaps it visible on its own after a delay no real load
     should reach, and reveal() cancels it by removing the animation once it actually
     fires for real. */
  animation:reveal-fallback .01s 4s forwards;
}
html.is-ready body{opacity:1; animation:none}
@keyframes reveal-fallback{ to{opacity:1} }
@media(prefers-reduced-motion:reduce){ body{transition:none} }
/* Screenshot mode needs the frame fully painted the instant shotReady() sets the
   title, not mid-fade — tools/shoot.sh polls for the title, not for this. */
body[data-shot]{opacity:1!important; animation:none!important; transition:none!important}
