/* Nyxtale Docs — presentation.
 *
 * Direction: this is the STUDIO surface mode from docs/22, not the storefront one. The landing is a
 * marketing surface and is allowed to breathe — animated sky, big display type, one micro-choice.
 * Documentation has the opposite job: an author opens it mid-sentence, with a broken scene on the
 * other monitor, and needs one fact fast. So: no hero, no ambient motion, no scroll reveals. Dense,
 * scannable, still. "Atmosphere in the frame, clarity in the work."
 *
 * Boldness is spent in exactly ONE place (docs/22): the example verdict — the stamp and node spine
 * showing that the real engine compiled this very block during the build. That is the thing this
 * site has that no other docs site can have, so it is the thing that gets the ink.
 *
 * Colour and type are the project's own tokens (docs/22 · nyxtale-studio/src/platform/tokens.ts),
 * not new values invented here. Directive categories and node types reuse the Studio graph's node
 * palette, so a category reads the same colour here as the node does in the editor.
 */

:root {
  /* Atmosphere (docs/22 "Dusk") */
  --void:#0A0B12; --pit:#121019; --dusk:#15141F; --ash:#26232F;
  --smoke:#4A4653;   /* borders ONLY — 1.68:1, may never carry text */
  --haze:#918B99;    /* quiet text, 4.66:1 */
  --bone:#D6D0C4;    /* reading text */
  --ember:#C15A2B;   /* the single light source — never a fill */
  --tallow:#E39A63;  /* readable ember register for text */

  /* Working palette — categorical, each ≥5.5:1 on ash (tokens.ts) */
  --signal:#3FB6E8; --amber:#F0912C; --gild:#E4CB4C; --terminal:#5FD183;
  --glitch:#F26FAE; --veil:#C77FE8; --hush:#8A97F2; --slate:#9DB2BB;
  --brass:#D9B37A; --lichen:#7FC894; --sodium:#D8873F; --flare:#E0705E;

  --bg:var(--void); --surface:var(--dusk); --raised:var(--ash); --code-bg:var(--pit);
  --text:var(--bone); --quiet:var(--haze); --line:color-mix(in srgb, var(--smoke) 55%, transparent);

  --font-display:"Fraunces","Playfair Display",Georgia,serif;
  --font-read:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,serif;
  --font-mono:"JetBrains Mono","SFMono-Regular",Consolas,ui-monospace,monospace;

  --xs:4px; --sm:8px; --md:16px; --lg:24px; --xl:40px;
  --r-sm:3px; --r-md:6px;
  --t-fast:120ms; --t-base:220ms;

  --measure:40rem;
  --rail:16rem;
  --toc:13rem;
}

/* A reference read in daylight is a real case; the tokens carry over, the values invert. */
@media (prefers-color-scheme: light) {
  :root {
    --bg:#EFEBE3; --surface:#E6E1D7; --raised:#DBD5C9; --code-bg:#E9E4DA;
    --text:#1E1B24; --quiet:#5C5665; --line:color-mix(in srgb, #1E1B24 18%, transparent);
    --ember:#A8471F; --tallow:#8A3A18;
    --signal:#1A6F94; --amber:#94550E; --gild:#7A6410; --terminal:#1F7A44;
    --glitch:#A32A66; --veil:#6B3A90; --hush:#3F4CA8; --slate:#4A5B63;
    --brass:#7A5A28; --lichen:#2F6B41; --sodium:#8A4E17; --flare:#A83A2C;
  }
}

*,*::before,*::after{box-sizing:border-box}

body{
  margin:0; background:var(--bg); color:var(--text);
  font-family:var(--font-read); font-size:1.0625rem; line-height:1.7;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
}

a{color:var(--tallow); text-decoration-thickness:1px; text-underline-offset:2px}
a:hover{color:var(--ember)}
:focus-visible{outline:2px solid var(--tallow); outline-offset:2px; border-radius:var(--r-sm)}

.skip{position:absolute; left:-9999px; top:var(--sm); background:var(--raised); color:var(--text);
  padding:var(--sm) var(--md); border-radius:var(--r-sm); z-index:10}
.skip:focus{left:var(--sm)}

/* ---------- top bar ---------- */

.top{
  position:sticky; top:0; z-index:5;
  display:flex; align-items:center; gap:var(--lg);
  padding:var(--sm) var(--lg);
  background:color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter:blur(8px);
  border-bottom:1px solid var(--line);
}
.brand{
  display:flex; align-items:center; gap:var(--sm);
  font-family:var(--font-display); font-size:1rem; letter-spacing:.02em;
  color:var(--text); text-decoration:none; white-space:nowrap;
}
/* The candle: the one ember mark in the chrome. Not a logo — a light source. */
.brand__mark{
  width:7px; height:7px; border-radius:50%;
  background:var(--ember); box-shadow:0 0 10px color-mix(in srgb, var(--ember) 70%, transparent);
  flex:none;
}
.find{position:relative; flex:1; max-width:26rem; display:flex; align-items:center}
.find input{
  width:100%; padding:var(--xs) 2.2rem var(--xs) var(--sm);
  background:var(--surface); color:var(--text);
  border:1px solid var(--line); border-radius:var(--r-sm);
  font-family:var(--font-mono); font-size:.8rem;
}
.find input::placeholder{color:var(--quiet)}
.find kbd{
  position:absolute; right:var(--sm); pointer-events:none;
  font-family:var(--font-mono); font-size:.65rem; color:var(--quiet);
  border:1px solid var(--line); border-radius:3px; padding:0 4px;
}

/* ---------- shell ---------- */

.shell{
  display:grid; grid-template-columns:var(--rail) minmax(0,1fr) var(--toc);
  gap:var(--xl); align-items:start;
  max-width:78rem; margin:0 auto; padding:var(--lg);
}

.nav{position:sticky; top:4rem; max-height:calc(100vh - 5rem); overflow-y:auto; font-size:.85rem}
.nav ul{list-style:none; margin:0; padding:0}

/* The first division in the rail is PRODUCT, not topic: the platform half is the same for every app
   built on Nyxtale, the app half belongs to one app and will differ in the next one. A reader who
   cannot tell which half he is in will carry a mechanic into an app that does not have it. The
   platform reads neutral; an app section is marked with the ember, the way an app is a light lit on
   top of the engine rather than part of it. */
.nav__product{margin-bottom:var(--xl)}
.nav__product + .nav__product{
  padding-top:var(--md); border-top:1px solid var(--line);
}
.nav__producttitle{
  margin:0; font-family:var(--font-display); font-weight:400; font-size:.95rem;
  letter-spacing:.01em; color:var(--text); display:flex; align-items:baseline; gap:var(--xs);
}
.nav__product + .nav__product .nav__producttitle::before{
  content:""; width:5px; height:5px; border-radius:50%; background:var(--ember);
  box-shadow:0 0 7px color-mix(in srgb, var(--ember) 70%, transparent); flex:none;
  align-self:center;
}
.nav__productblurb{
  margin:2px 0 var(--md); font-size:.7rem; line-height:1.45; color:var(--quiet);
}
.nav__groups{margin:0; padding:0}
.nav__group{margin-bottom:var(--lg)}
.nav__group h3{
  margin:0 0 var(--xs); font-family:var(--font-mono); font-size:.65rem;
  text-transform:uppercase; letter-spacing:.12em; color:var(--quiet); font-weight:500;
}
.nav__item a,.nav__item span{
  display:flex; align-items:baseline; gap:var(--xs);
  padding:2px 0 2px var(--sm); border-left:2px solid transparent;
  color:var(--text); text-decoration:none; line-height:1.45;
}
.nav__item a:hover{border-left-color:var(--smoke); color:var(--tallow)}
.nav__item--current a{border-left-color:var(--ember); color:var(--tallow)}
/* A planned page is shown, un-linked and marked. An author should be able to see the shape of the
   whole book and also see exactly where it stops — a stub page would hide that. */
.nav__item--planned span{color:var(--quiet); cursor:default}
.nav__item--planned em{
  font-style:normal; font-family:var(--font-mono); font-size:.55rem;
  text-transform:uppercase; letter-spacing:.08em;
  color:var(--smoke); border:1px solid var(--line); border-radius:2px; padding:0 3px;
}
.nav__gen{
  font-style:normal; font-family:var(--font-mono); font-size:.55rem;
  text-transform:uppercase; letter-spacing:.08em; color:var(--terminal); opacity:.75;
}
/* Untranslated is a DIFFERENT absence from unwritten, and it stays clickable: the Russian original
   exists, so the row leads there instead of pretending the page does not exist. */
.nav__item--untranslated a{color:var(--quiet)}
.nav__item--untranslated em{
  font-style:normal; font-family:var(--font-mono); font-size:.55rem;
  text-transform:uppercase; letter-spacing:.08em; color:var(--slate); opacity:.8;
}

/* ---------- language ---------- */

.lang{display:flex; gap:2px; flex:none}
.lang__chip{
  font-family:var(--font-mono); font-size:.65rem; letter-spacing:.08em;
  padding:2px var(--xs); border:1px solid var(--line); border-radius:2px;
  color:var(--quiet); text-decoration:none;
}
.lang__chip:hover{color:var(--tallow); border-color:var(--smoke)}
.lang__chip--on{color:var(--tallow); border-color:var(--smoke); background:var(--surface)}
/* A locale this page does not exist in is shown, disabled — the reader learns it is missing before
   clicking, not after landing on a 404. */
.lang__chip--off{color:var(--smoke); cursor:default; opacity:.6}
.lang__chip--off:hover{color:var(--smoke); border-color:var(--line)}

/* ---------- page ---------- */

.page{min-width:0; max-width:var(--measure)}
.crumb{
  margin:0; font-family:var(--font-mono); font-size:.65rem;
  text-transform:uppercase; letter-spacing:.12em; color:var(--quiet);
}
.crumb__product::after{content:" · "; color:var(--smoke)}
.page h1{
  font-family:var(--font-display); font-weight:400; font-size:clamp(1.9rem,1.4rem + 1.6vw,2.6rem);
  line-height:1.15; margin:var(--xs) 0 var(--sm); letter-spacing:-.01em;
}
.summary{margin:0 0 var(--xl); color:var(--quiet); font-size:1.05rem; line-height:1.6}
.lede{color:var(--quiet)}

.page h2{
  font-family:var(--font-display); font-weight:400; font-size:1.5rem;
  margin:var(--xl) 0 var(--sm); padding-bottom:var(--xs); border-bottom:1px solid var(--line);
}
.page h3{font-family:var(--font-read); font-weight:600; font-size:1.1rem; margin:var(--lg) 0 var(--xs)}
.page p{margin:0 0 var(--md)}
.page ul,.page ol{margin:0 0 var(--md); padding-left:1.2rem}
.page li{margin-bottom:var(--xs)}
.page strong{color:var(--bone); font-weight:600}
@media (prefers-color-scheme: light){ .page strong{color:#000} }

.page blockquote{
  margin:var(--md) 0; padding:var(--sm) var(--md);
  border-left:2px solid var(--sodium); background:var(--surface); border-radius:0 var(--r-sm) var(--r-sm) 0;
  color:var(--text);
}
.page blockquote p:last-child{margin:0}

.page code{
  font-family:var(--font-mono); font-size:.85em;
  background:var(--raised); padding:1px 4px; border-radius:2px;
}
.page pre{
  margin:0; padding:var(--md); overflow-x:auto;
  background:var(--code-bg); border:1px solid var(--line); border-radius:var(--r-sm);
  /* .nsx is line-oriented — the prose line-height would read as double-spacing and break the shape
     of the script. Set it on <pre>: line-height on an inline <code> does not govern the block. */
  line-height:1.5;
  /* A line of .nsx is usually a line of PROSE — a narrator's sentence, not a statement of code — and a
     sentence cut off at the right edge of the box is a documentation page failing at its one job. The
     block still scrolls (a long unbroken token has nowhere to wrap), but ordinary lines wrap instead
     of leaving the reader to find a scrollbar that only appears once they touch it.
     ⚑ No hanging indent for the continuation: `text-indent` in a <pre> applies to the block's first
     line, not to each wrapped one, so it pushed every line after the first two characters right and
     the script read as if it were nested. Every Nyx line opens with `@`, a speaker or `*`, which is
     what tells a continuation from a new line. */
  white-space:pre-wrap;
  overflow-wrap:break-word;
}
.page pre code{background:none; padding:0; font-size:.82rem}
pre.code{margin:0 0 var(--md)}

.page table{
  width:100%; border-collapse:collapse; margin:0 0 var(--md); font-size:.9rem;
}
.page th,.page td{text-align:left; padding:var(--xs) var(--sm); border-bottom:1px solid var(--line)}
.page th{
  font-family:var(--font-mono); font-size:.65rem; text-transform:uppercase;
  letter-spacing:.08em; color:var(--quiet); font-weight:500;
}
.muted{color:var(--quiet)}

/* ---------- the signature: a verified example ---------- */

.ex{margin:0 0 var(--md); border:1px solid var(--line); border-radius:var(--r-sm); overflow:hidden}
.ex__src{border:none !important; border-radius:0 !important}
.ex__verdict{
  display:flex; align-items:center; gap:var(--sm); flex-wrap:wrap;
  padding:var(--xs) var(--md);
  background:var(--surface); border-top:1px solid var(--line);
}
/* The claim the whole site rests on: this block went through the real compiler during the build. */
.ex__stamp{
  font-family:var(--font-mono); font-size:.6rem; text-transform:uppercase; letter-spacing:.1em;
  color:var(--terminal); display:flex; align-items:center; gap:5px;
}
.ex__stamp::before{
  content:""; width:5px; height:5px; border-radius:50%; background:var(--terminal);
  box-shadow:0 0 6px color-mix(in srgb, var(--terminal) 80%, transparent);
}
.ex__nodes{display:flex; gap:var(--xs); flex-wrap:wrap; margin-left:auto}
.node{
  font-family:var(--font-mono); font-size:.6rem; letter-spacing:.04em;
  padding:1px 5px; border-radius:2px;
  border:1px solid currentColor; opacity:.85;
}
.node i{font-style:normal; opacity:.6; margin-left:2px}
.node--line{color:var(--brass)} .node--choice{color:var(--amber)} .node--set{color:var(--terminal)}
.node--branch{color:var(--veil)} .node--effect{color:var(--slate)} .node--jump{color:var(--hush)}
.node--end{color:var(--flare)}
.ex--fragment .ex__stamp{color:var(--slate)}
.ex--fragment .ex__stamp::before{background:var(--slate); box-shadow:none}

/* ---------- generated reference ---------- */

.legend{display:flex; gap:var(--md); flex-wrap:wrap; margin:0 0 var(--lg); font-size:.75rem; color:var(--quiet)}
.cat{display:flex; align-items:baseline; gap:var(--sm)}
.cat::before{content:""; width:3px; height:.9em; background:currentColor; border-radius:1px; flex:none}
.cat__count{
  font-family:var(--font-mono); font-size:.6rem; color:var(--quiet);
  border:1px solid var(--line); border-radius:2px; padding:0 4px; letter-spacing:.06em;
}
.cat--signal{color:var(--signal)} .cat--amber{color:var(--amber)} .cat--gild{color:var(--gild)}
.cat--terminal{color:var(--terminal)} .cat--glitch{color:var(--glitch)} .cat--veil{color:var(--veil)}
.cat--hush{color:var(--hush)} .cat--slate{color:var(--slate)} .cat--brass{color:var(--brass)}
.cat--bone{color:var(--bone)} .cat--lichen{color:var(--lichen)} .cat--sodium{color:var(--sodium)}
.cat--flare{color:var(--flare)}
/* The glyph is the colour-free half of the taxonomy (WCAG 1.4.1) — same shape the editor draws. */
.cat__glyph{font-family:var(--font-mono); font-size:.8em; opacity:.9}

/* ---------- a directive that has real documentation ---------- */

.dir__detail{margin:0 0 var(--sm) !important; font-size:.9rem}
.dir__label{
  font-family:var(--font-mono); font-size:.58rem; text-transform:uppercase; letter-spacing:.1em;
  color:var(--quiet); margin-right:var(--xs);
}
/* What the READER gets — the question the signature never answered. */
.dir__reader{margin:var(--sm) 0 0 !important; font-size:.85rem; color:var(--text)}
.dir__reader .dir__label{color:var(--signal)}
.dir__example{
  margin:var(--sm) 0 0 !important; padding:var(--sm) var(--md) !important;
  background:var(--code-bg); border:1px solid var(--line); border-radius:var(--r-sm);
  font-size:.78rem; line-height:1.5;
}
.dir__related{margin:var(--sm) 0 0 !important; font-size:.8rem}
.dir__related a{text-decoration:none}
.dir__related code{background:none; padding:0}
/* The argument's explanation leads; its machine constraints follow, quieter. */
.args__note{display:block; font-family:var(--font-read); font-size:.82rem; color:var(--text)}
.args dd .args__note + .range,
.args dd .args__note + code{display:inline-block; margin-top:2px}
/* The reference is platform-wide, so a category owned by ONE app says so. Without this an author of
   the next app reads a Nightfall mechanic as something the engine gives him. */
.cat__product{
  font-family:var(--font-mono); font-size:.55rem; text-transform:uppercase; letter-spacing:.1em;
  color:var(--quiet); border:1px solid var(--line); border-radius:2px; padding:0 4px;
}
.cat__topic{margin:calc(var(--xs) * -1) 0 var(--sm) !important; font-size:.8rem}
.seealso{
  font-family:var(--font-mono); font-size:.7rem; letter-spacing:.02em;
  text-decoration:none; border-bottom:1px solid var(--line); padding-bottom:1px;
}
.seealso::before{content:"→ "; color:var(--smoke)}
.seealso:hover{border-bottom-color:var(--ember)}

/* The reverse direction: a written page lists the directives it teaches, straight off the registry.
   Nobody maintains this list, so it cannot fall behind the engine. */
.covers{margin-top:var(--xl); padding-top:var(--md); border-top:1px solid var(--line)}
.covers h2{margin-top:0 !important; border-bottom:none !important; font-size:1.2rem}
.covers__list{list-style:none; margin:var(--md) 0 0 !important; padding:0 !important;
  display:grid; grid-template-columns:auto 1fr; gap:var(--xs) var(--md); align-items:baseline}
.covers__list li{display:contents}
.covers__list a{text-decoration:none; font-family:var(--font-mono); white-space:nowrap}
.covers__sum{font-size:.82rem; color:var(--quiet)}

.dir-grid{display:flex; flex-direction:column; gap:var(--sm)}
.dir{
  padding:var(--sm) var(--md); background:var(--surface);
  border:1px solid var(--line); border-radius:var(--r-sm); scroll-margin-top:5rem;
}
.dir h3{margin:0 0 var(--xs); display:flex; align-items:center; gap:var(--sm); font-weight:400}
.sig{
  background:none !important; padding:0 !important;
  font-family:var(--font-mono); font-size:.85rem; color:var(--tallow);
}
.dir__summary{margin:0 0 var(--xs) !important; font-size:.9rem}
.flag{font-size:.7rem; opacity:.9}
.flag--photo{color:var(--sodium)} .flag--int{color:var(--signal)}
.args{
  display:grid; grid-template-columns:auto 1fr; gap:2px var(--md);
  margin:var(--xs) 0 0; font-size:.78rem;
}
.args dt{display:flex; gap:var(--xs); align-items:baseline}
.args dd{margin:0; color:var(--quiet); font-family:var(--font-mono); font-size:.72rem}
.args dd code{background:var(--code-bg); font-size:.9em; color:var(--text)}
.range{color:var(--quiet)}
/* A §17 ceiling is not an ordinary bound — above it the client clamps and the validator warns, so it
   reads in the safety colour, not the neutral one. */
.safemax{color:var(--sodium)}
.argtype{font-family:var(--font-mono); font-size:.62rem; color:var(--quiet)}
.args-none{margin:0 !important; font-size:.78rem}

.diag{
  padding:var(--sm) var(--md); margin-bottom:var(--sm); background:var(--surface);
  border:1px solid var(--line); border-left:2px solid var(--smoke);
  border-radius:0 var(--r-sm) var(--r-sm) 0; scroll-margin-top:5rem;
}
.diag h3{margin:0 0 var(--xs)}
.diag h3 code{background:none; padding:0; color:var(--tallow); font-size:.85rem}
.diag__msg{margin:0 0 var(--xs) !important; font-size:.9rem}
.diag__hint{margin:0 !important; font-size:.82rem; color:var(--quiet)}
.diag__hintlabel{
  font-family:var(--font-mono); font-size:.58rem; text-transform:uppercase; letter-spacing:.1em;
  color:var(--terminal); margin-right:var(--xs);
}

/* ---------- on-page toc ---------- */

.toc{position:sticky; top:4rem; max-height:calc(100vh - 5rem); overflow-y:auto; font-size:.78rem}
.toc h2{
  margin:0 0 var(--xs); font-family:var(--font-mono); font-size:.6rem;
  text-transform:uppercase; letter-spacing:.12em; color:var(--quiet); font-weight:500;
}
.toc ul{list-style:none; margin:0; padding:0}
.toc a{display:block; padding:2px 0 2px var(--sm); border-left:1px solid var(--line);
  color:var(--quiet); text-decoration:none; line-height:1.4}
.toc a:hover{color:var(--tallow); border-left-color:var(--smoke)}
.toc__d3 a{padding-left:var(--md)}

/* ---------- search results ---------- */

.results{
  position:fixed; top:3rem; left:50%; transform:translateX(-50%);
  width:min(34rem,calc(100vw - 2rem)); max-height:60vh; overflow-y:auto; z-index:6;
  background:var(--raised); border:1px solid var(--smoke); border-radius:var(--r-md);
  box-shadow:0 16px 48px rgba(0,0,0,.55); padding:var(--xs);
}
.results[hidden]{display:none}
.res{
  display:flex; align-items:baseline; gap:var(--sm); width:100%;
  padding:var(--xs) var(--sm); border-radius:var(--r-sm);
  color:var(--text); text-decoration:none;
}
.res[aria-selected="true"],.res:hover{background:var(--surface)}
.res__t{font-family:var(--font-mono); font-size:.8rem; color:var(--tallow); white-space:nowrap}
.res__s{font-size:.72rem; color:var(--quiet); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.res__g{
  margin-left:auto; font-family:var(--font-mono); font-size:.55rem; text-transform:uppercase;
  letter-spacing:.08em; color:var(--smoke); white-space:nowrap;
}
.res__none{padding:var(--sm); color:var(--quiet); font-size:.8rem}

/* ---------- narrow ---------- */

@media (max-width:1100px){
  .shell{grid-template-columns:var(--rail) minmax(0,1fr); gap:var(--lg)}
  .toc{display:none}
}
@media (max-width:820px){
  .shell{grid-template-columns:1fr; padding:var(--md)}
  .nav{position:static; max-height:none; border-bottom:1px solid var(--line); padding-bottom:var(--md)}
  .nav__groups{display:flex; flex-wrap:wrap; gap:var(--md)}
  .nav__group{margin-bottom:0}
  .nav__product{margin-bottom:var(--lg)}
  .nav__productblurb{display:none}
  .top{gap:var(--md); padding:var(--sm) var(--md)}
  .find kbd{display:none}
}

@media (prefers-reduced-motion:reduce){
  *{animation:none !important; transition:none !important}
}
