/* ============================================================================
   The Vertex web standard — bAIbel Technologies
   ----------------------------------------------------------------------------
   Derived from the brand pack README (C:\Users\jon\Downloads\baibel-brand-vertex)
   and from the "bAIbel Technologies" artifact of 2026-09-04, whose CSS is the
   visual system this file continues. The artifact's *content* is not carried
   over: it predates the evidence register and several of its claims are now
   REFUTED or narrowed. See build/README.md.

   Palette rule, verbatim from the brand README: "The ramp is a legend, not a
   mood." Light mode is a tint of the same ramp, never a redraw. So the four
   ramp hues keep their roles in both themes and only their values change.

   Three theme states, per the artifact and the design contract:
     :root                                    -> dark (the brand ground)
     @media (prefers-color-scheme: light)     -> light, guarded against an
                                                 explicit dark stamp
     :root[data-theme="light"]                -> explicit light wins
   ========================================================================== */

:root{
  /* ramp — dark grounds */
  --intake:#FF2D9B;      /* TMS */
  --process:#9B5CFF;
  --resolved:#22D3EE;    /* AV */
  --apex:#9BF0FA;

  --ground:#0B0A12;      /* obsidian */
  --slab:#15131F;        /* raised */
  --raised:#1B1828;
  --ink:#EFEDF6;         /* ice */
  --muted:#8A85A0;
  --line:#241F33;
  --line-soft:#1B1826;

  --measure:1180px;
  --gutter:32px;
  /* The zone's own hue, named once. vertex-dark and vertex-strata already
     carried this; vertex did not, and six devices were each repeating the
     same two overrides. New accents use var(--rail) and inherit the legend
     instead of restating it. */
  --rail:var(--process);
  color-scheme:dark light;
}
body.zone-av{--rail:var(--resolved)}
body.zone-tms{--rail:var(--intake)}

/* The rail at two lower weights. The brand README already works this way --
   "light mode is a tint of the same ramp, never a redraw" -- so a tint ladder
   is the house's own idea one level down, not a second idea. The rule it buys:
   TINT THE LINES, NEVER THE GROUNDS. A faint coloured outline is the legend at
   low volume; a faint coloured fill on every card is a mood, which is the thing
   the README is warning about. --rail-wash is therefore spent on exactly one
   element, the starred panel, where the colour is already earning its place.

   Declared on body, not :root: var(--rail) inside a custom property resolves
   against the element that DECLARES it, and the zone class is on body. On
   :root every tint would silently come out purple. The plain values come
   first so a browser without color-mix gets the hairlines it has today. */
body{
  --rail-soft:var(--line);
  --rail-wash:var(--slab);
}
@supports (color:color-mix(in srgb,red,blue)){
  body{
    --rail-soft:color-mix(in srgb,var(--rail) 30%,var(--line));
    --rail-wash:color-mix(in srgb,var(--rail) 5%,var(--slab));
  }
}

@media (prefers-color-scheme: light){
  :root:not([data-theme="dark"]){
    --intake:#C4006F; --process:#6E2FD9; --resolved:#0E8CA8; --apex:#1FB6D6;
    --ground:#F5F3F9; --slab:#FFFFFF; --raised:#FAF8FD;
    --ink:#0B0A12; --muted:#6A6582; --line:#DED9EB; --line-soft:#EBE7F3;
  }
}
:root[data-theme="light"]{
  --intake:#C4006F; --process:#6E2FD9; --resolved:#0E8CA8; --apex:#1FB6D6;
  --ground:#F5F3F9; --slab:#FFFFFF; --raised:#FAF8FD;
  --ink:#0B0A12; --muted:#6A6582; --line:#DED9EB; --line-soft:#EBE7F3;
}

*{box-sizing:border-box}

body{
  margin:0;
  background:var(--ground);
  color:var(--ink);
  font-family:"Source Serif 4",Georgia,"Times New Roman",serif;
  font-size:18px; line-height:1.62;
  -webkit-font-smoothing:antialiased;
}

h1,h2,h3,h4,.grot{
  font-family:"Space Grotesk",-apple-system,"Segoe UI",sans-serif;
  font-weight:600; margin:0;
}
h1,h2,h3{text-wrap:balance}
p{margin:0}
a{color:inherit}
strong{font-weight:600}
code,.mono{font-family:"Space Mono","SFMono-Regular",Consolas,monospace}
code{font-size:.86em}

.eyebrow{
  font-family:"Space Mono",monospace; font-size:11px; letter-spacing:.18em;
  text-transform:uppercase; color:var(--muted); margin:0;
}

.wrap{max-width:var(--measure);margin:0 auto;padding:0 var(--gutter)}
/* measure encodes the argument: the apex is narrow, the base is wide */
.narrow{max-width:680px}

/* ---------------------------------------------------------------- masthead */
.top{
  display:flex;align-items:center;justify-content:space-between;
  gap:24px;padding:22px 0 20px;border-bottom:1px solid var(--line);
  flex-wrap:wrap;
}
.brandline{display:flex;align-items:center;gap:12px;text-decoration:none}
.brandline img{width:26px;height:26px;display:block}
.wm{font-family:"Space Grotesk",sans-serif;font-weight:600;font-size:19px;letter-spacing:-.02em}
.wm .sfx{font-family:"Space Mono",monospace;font-size:16px;letter-spacing:.04em;margin-left:7px}

/* §6.4 — the stage marker. In the chrome, once, same place on every page,
   never absent. Not a banner and not a badge on a claim. */
.stage{
  font-family:"Space Mono",monospace;font-size:10.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--muted);
  border:1px solid var(--line);border-radius:2px;padding:4px 9px;white-space:nowrap;
}

/* No text-transform here: these carry the wordmark, and bAIbel survives no
   upper-casing (RULES.md 8; deploy/preflight.py fails a page that does it). */
.navlinks{
  display:flex;gap:22px;flex-wrap:wrap;
  font-family:"Space Mono",monospace;font-size:12px;
  letter-spacing:.08em;color:var(--muted);
}
.navlinks a{text-decoration:none}
.navlinks a:hover{color:var(--ink)}
.navlinks a[aria-current="true"]{color:var(--ink)}
.navlinks a:focus-visible{outline:2px solid var(--apex);outline-offset:3px;border-radius:2px}

/* zone strip — the current zone's own pages */
.zonebar{
  display:flex;gap:28px;flex-wrap:wrap;padding:16px 0;
  border-bottom:1px solid var(--line-soft);
  /* Reading size (Jon, 2026-11-06): with the feature pages under Features the strip holds four
     items, so it no longer needs the 11.5px monospace that eyebrow labels use. */
  font-family:"Space Grotesk",-apple-system,"Segoe UI",sans-serif;font-size:17px;font-weight:500;
  letter-spacing:-.005em;color:var(--muted);
}
.zonebar a{text-decoration:none}
.zonebar a:hover{color:var(--ink)}
.zonebar a[aria-current="true"]{color:var(--ink);text-decoration:underline;text-underline-offset:4px}
.zonebar .zonename{color:var(--ink)}

/* ---------------------------------------------------------------- page head */
.pagehead{padding:64px var(--gutter) 10px}
.pagehead .sect-head{display:flex;align-items:center;gap:14px}
.tick{width:22px;height:6px;border-radius:2px;flex:none;background:var(--muted)}
.zone-av .tick{background:var(--resolved)}
.zone-tms .tick{background:var(--intake)}
.zone-co .tick{background:var(--process)}
.pagehead h1{font-size:clamp(30px,4.2vw,50px);line-height:1.06;letter-spacing:-.022em;margin-top:18px}
.lede{margin-top:26px;font-size:20px;opacity:.88}
.lede p + p{margin-top:16px}

/* ---------------------------------------------------------------- panels */
.band{padding:56px 0 0}
.band-name{display:flex;align-items:center;gap:13px}
.band-name h2{font-size:clamp(21px,2.4vw,27px);letter-spacing:-.016em}
/* Cards, not a ruled table. The grid used to be one object drawn with a 1px gap
   over a --line ground, which is why an outline per cell was wrong THEN: it
   would have doubled every interior hairline. Pulling the cells apart removes
   the interior line entirely, so each card can carry its own soft rail outline
   and the count stays the same.

   The cards are EQUAL HEIGHT (the grid's default stretch), because a ragged
   lower edge across a 3x3 looks like a mistake rather than a stagger. That
   makes card length an editorial constraint, not a layout one: a two-line
   panel beside an eleven-line one is now a visibly empty box, so the copy in a
   panel grid has to be levelled. See PANEL-PLAN-av.md. */
.panels{
  display:grid;grid-template-columns:repeat(2,1fr);gap:14px;
  margin-top:30px;
}
.panel{
  background:var(--slab);border:1px solid var(--rail-soft);border-radius:5px;
  padding:26px 26px 24px;display:flex;flex-direction:column;gap:13px;min-width:0;
}
.panel h3{font-size:21px;letter-spacing:-.018em;line-height:1.24}
.panel p{font-size:16.5px;line-height:1.68;opacity:.87}
/* A panel carrying a figure spans both columns. A screenshot is the strongest
   evidence here; at half measure it renders about 458px wide and a 900px
   capture is halved into type nobody can read. The prose keeps its measure, so
   widening the panel widens the picture and nothing else. */
.panel.wide{grid-column:1/-1}
.panel.wide p,.panel.wide ul,.panel.wide ol{max-width:70ch}
/* A starred panel is one the register marks as load-bearing. Now that every
   card carries the rail softly, the star is the same hue at FULL weight -- soft
   outline means "this zone", solid outline means "and this one carries the
   argument". That is the legend doing the work rather than a badge. The wash is
   the one place a ground is tinted, and only because the colour has already
   earned its place on this card. */
.panel.star{
  background:var(--rail-wash);border-color:var(--rail);
  box-shadow:inset 3px 0 0 var(--rail);
}
.panel h3{margin-top:2px}

/* ---------------------------------------------------------------- prose */
.prose{padding:26px 0 0}
.prose h2{
  font-size:clamp(24px,2.9vw,33px);line-height:1.16;letter-spacing:-.018em;
  margin:62px 0 0;padding-top:26px;border-top:1px solid var(--line);
}
.prose h2:first-child{border-top:0;padding-top:0;margin-top:34px}
.prose h3{font-size:21px;letter-spacing:-.016em;margin:38px 0 0}
.prose h4{font-family:"Space Mono",monospace;font-size:11px;font-weight:400;
  letter-spacing:.16em;text-transform:uppercase;color:var(--muted);margin:32px 0 0}
.prose p{margin-top:18px;max-width:70ch}
.prose ul,.prose ol{margin:18px 0 0;padding-left:22px;max-width:70ch}
.prose li{margin-top:9px}
.prose hr{border:0;border-top:1px solid var(--line);margin:44px 0 0}

table{
  border-collapse:collapse;width:100%;margin-top:26px;
  font-family:"Space Grotesk",sans-serif;font-size:15px;line-height:1.6;
}
thead th{
  font-family:"Space Mono",monospace;font-size:10.5px;font-weight:400;
  letter-spacing:.16em;text-transform:uppercase;color:var(--muted);
  text-align:left;padding:0 16px 10px 0;border-bottom:1px solid var(--line);
}
tbody td{padding:14px 16px 14px 0;border-bottom:1px solid var(--line-soft);vertical-align:top}
tbody tr:last-child td{border-bottom:0}
.tablewrap{overflow-x:auto}

/* ---------------------------------------------------------------- figures */
figure{margin:34px 0 0;border:1px solid var(--line);border-radius:4px;background:var(--slab);padding:20px}
figure img{max-width:100%;height:auto;display:block}
figcaption{
  font-family:"Space Mono",monospace;font-size:11px;letter-spacing:.08em;
  color:var(--muted);margin-top:14px;
}

/* a converse citation: the claim is true because the row is NOT built */


/* ---------------------------------------------------------------- blocked */
.blocked{
  margin-top:40px;border:1px solid var(--intake);border-radius:4px;
  background:var(--slab);padding:28px 30px;
}
.blocked .tag{
  font-family:"Space Mono",monospace;font-size:10.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--intake);
}
.blocked h2{margin-top:14px;font-size:24px;letter-spacing:-.018em;border-top:0;padding-top:0}
.blocked p{margin-top:16px;font-size:16.5px;opacity:.87;max-width:70ch}
.panel.blocked{border-color:var(--intake);box-shadow:inset 3px 0 0 var(--intake)}

/* ---------------------------------------------------------------- footer */
/* More air before the footer (Jon, 2026-11-05). ⚠ footer.wrap, not footer:
   the footer is also a .wrap, and .wrap's margin:0 auto outranks a bare
   element selector -- the 92-96px set here before never applied at all. */
footer.wrap{margin-top:clamp(120px,14vw,176px);
  /* Room under the footer on every page (Jon, 2026-11-10). On footer.wrap for the same reason
     as the margin: a bare footer{padding} lost to .wrap's padding and gave nothing. */
  padding-bottom:calc(clamp(96px,10vw,140px) + env(safe-area-inset-bottom, 0px))}
footer .fline{
  border-top:1px solid var(--line);padding-top:28px;
  display:flex;justify-content:space-between;gap:28px;flex-wrap:wrap;align-items:flex-start;
}
footer .particulars{
  font-family:"Space Mono",monospace;font-size:11.5px;line-height:2.05;color:var(--muted);
}
footer .particulars strong{color:var(--ink);font-weight:700}
footer .routes{
  display:flex;gap:20px;flex-wrap:wrap;
  font-family:"Space Mono",monospace;font-size:11.5px;letter-spacing:.06em;color:var(--muted);
}
footer .routes a{text-decoration:none}
footer .routes a:hover{color:var(--ink)}

/* ---------------------------------------------------------------- responsive */
@media (max-width:940px){
  .panels{grid-template-columns:1fr}
  .navlinks{font-size:11px;gap:16px}
}
@media (max-width:560px){
  :root{--gutter:16px}
  body{font-size:17px}
  .top{padding-bottom:16px}
  .prose p,.prose ul,.prose ol{max-width:none}
}

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

/* ---------------------------------------------------------------------------
   The availability notice (RULES.md 4, second part; build/house.py).
   Above the chrome, full width, on every page. It is deliberately quieter than
   a marketing banner and louder than the stage marker beside it: the stage
   marker says what the software is, this says what we are not yet selling.
   Self-contained so the three standards carry it identically.
   --------------------------------------------------------------------------- */
.notice{
  --notice-accent:var(--process);
  background:var(--slab);
  border-bottom:1px solid var(--line);
  box-shadow:inset 0 2px 0 var(--notice-accent);
}
body.zone-av  .notice{--notice-accent:var(--resolved)}
body.zone-tms .notice{--notice-accent:var(--intake)}

.noticeline{
  display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;
  padding:11px var(--gutter) 12px;
}
.noticetag{
  font-family:"Space Mono",monospace;font-size:10.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--notice-accent);white-space:nowrap;
}
.noticeline p{
  margin:0;flex:1 1 320px;min-width:0;
  font-size:13.5px;line-height:1.5;color:var(--muted);
}
@media (max-width:560px){
  .noticeline{gap:6px}
  .noticeline p{flex-basis:100%}
}

/* ---------------------------------------------------------------------------
   The beta door (build/house.py:BETA_ADDRESS). It replaced a form whose Send
   link pointed at `#`. The address is the control, so it is set as one -- large
   enough to read across a room, and a real link rather than text to copy out.
   --------------------------------------------------------------------------- */
.door{
  margin-top:34px;padding:26px 26px 22px;
  background:var(--slab);border:1px solid var(--line);border-radius:3px;
  box-shadow:inset 3px 0 0 var(--door-accent);
  --door-accent:var(--process);
}
body.zone-av  .door{--door-accent:var(--resolved)}
body.zone-tms .door{--door-accent:var(--intake)}
.door h2{margin:0 0 14px;font-size:19px}
.door ul{margin:0 0 20px;padding-left:20px;color:var(--muted);line-height:1.65}
.door ul li{margin:3px 0}
.doorline{margin:0}
.doormail{
  font-family:"Space Mono",monospace;font-size:17px;letter-spacing:-.01em;
  word-break:break-all;
}
.doornote{margin:12px 0 0;font-size:13px;color:var(--muted)}
@media (max-width:560px){ .doormail{font-size:15px} }

/* ---------------------------------------------------------------------------
   Figures (FIGURE-REGISTER.md) and the three text devices.

   A figure is a claim, so a slot names what will go there rather than saying
   "image". The devices -- chips, stats, pull -- carry no evidence risk at all:
   each is the copy's own words, set differently. Dense prose is more often a
   layout problem than a missing picture.
   --------------------------------------------------------------------------- */
.fig{margin:34px 0 0}
.fig img{
  display:block;width:100%;height:auto;border-radius:4px;
  border:1px solid var(--line);background:var(--slab);
}
.fig-svg svg{
  display:block;width:100%;height:auto;border-radius:4px;
  border:1px solid var(--line);background:var(--slab);
}
.fig figcaption{
  margin-top:11px;font-size:13px;line-height:1.5;color:var(--muted);
}

.figure-slot{
  border:1px dashed var(--line);border-radius:4px;background:transparent;
  padding:22px 22px 20px;text-align:left;margin:34px 0 0;
}
.figure-slot .tag{
  margin:0 0 8px;font-family:"Space Mono",monospace;font-size:10.5px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--muted);
}
.figure-slot p:last-child{
  margin:0;font-size:14px;line-height:1.55;color:var(--muted);
}
.figure-slot.held{border-style:solid;border-color:var(--line)}
.figure-slot.held .tag{color:var(--process)}

/* CHIPS -- a list scanned for one word. Never a paragraph. */
.chips{
  display:flex;flex-wrap:wrap;gap:7px;
  margin:4px 0 0;padding:0;list-style:none;
}
.chips li{
  font-family:"Space Mono",monospace;font-size:12px;letter-spacing:.02em;
  color:var(--ink);background:var(--raised);
  border:1px solid var(--line);border-radius:2px;padding:5px 9px;
  white-space:nowrap;
}

/* STATS -- where the number is the claim. */
.stats{
  display:flex;flex-wrap:wrap;gap:12px;margin:6px 0 0;
}
/* A number box carries the zone's hue on its leading edge -- the same 3px
   inset the door, the pull and a starred panel already use, so the band reads
   as part of the house rather than as four undressed rectangles. It also
   echoes the tick beside "In numbers" four times across the row. */
.stat{
  flex:1 1 150px;min-width:0;
  border:1px solid var(--rail-soft);border-radius:3px;background:var(--slab);
  padding:16px 16px 14px 18px;
  box-shadow:inset 3px 0 0 var(--rail);
}
.statnum{
  display:block;font-family:"Space Grotesk",sans-serif;font-weight:600;
  font-size:30px;line-height:1.05;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;color:var(--ink);
}
.statlab{
  display:block;margin-top:6px;font-family:"Space Mono",monospace;
  font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);
}

/* PULL -- the one line that is the argument. */
.pull{
  margin:26px 0;padding:2px 0 2px 20px;
  border-left:3px solid var(--door-accent, var(--process));
  font-family:"Source Serif 4",Georgia,serif;
  font-size:21px;line-height:1.38;color:var(--ink);text-wrap:balance;
}
body.zone-av  .pull{border-left-color:var(--resolved)}
body.zone-tms .pull{border-left-color:var(--intake)}

@media (max-width:560px){
  .statnum{font-size:25px}
  .pull{font-size:18px;padding-left:14px}
}

/* ------------------------------------------------------------- figures at size
   A figure is evidence, and the prose measure here is deliberately narrow
   (.narrow, 680px -- "the apex is narrow, the base is wide"). A diagram
   authored at 1040 units and squeezed into ~620px renders its 12.5px labels at
   about 7px, which is not small, it is unreadable -- and an unreadable figure
   argues nothing. So a figure breaks out of the measure and takes the window.
   The caption keeps the prose measure: a 1700px line of 13px grey is worse. */
.prose .fig{
  --fig-w:min(calc(100vw - 2*var(--gutter)), 1720px);
  width:var(--fig-w);
  margin-left:calc(50% - var(--fig-w)/2);
}
/* Inside a panel it must NOT break out -- it would simply overhang the card's
   own border. The panel widens to both columns instead (.panel.wide), and the
   figure simply fills it. */
.panel .fig{width:100%;margin-left:0}
.fig figcaption{max-width:70ch}
.fig-svg{cursor:zoom-in}
.fig-svg svg{pointer-events:none}

/* The viewer. Click a figure to open it at whatever size the window allows,
   arrow between the figures on the page, Escape to leave. */
.figview{
  position:fixed;inset:0;z-index:90;display:none;
  background:color-mix(in srgb, var(--ground) 94%, transparent);
  padding:56px 24px 72px;box-sizing:border-box;overflow:auto;
}
.figview[data-open]{display:block}
.figview .fv-stage{display:flex;align-items:center;justify-content:center;min-height:100%}
.figview svg{
  width:100%;height:auto;max-width:2000px;
  border:1px solid var(--line);border-radius:4px;background:var(--slab);
}
.figview img{width:100%;height:auto;max-width:2000px;border-radius:4px}
.fv-bar{
  position:fixed;left:0;right:0;top:0;height:48px;display:flex;align-items:center;
  gap:18px;padding:0 20px;background:var(--slab);border-bottom:1px solid var(--line);
}
.fv-bar .fv-cap{font-size:13px;color:var(--muted);flex:1;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fv-bar button{
  font-family:"Space Mono",monospace;font-size:11px;letter-spacing:.14em;
  background:transparent;color:var(--ink);border:1px solid var(--line);
  border-radius:3px;padding:6px 11px;cursor:pointer;
}
.fv-bar button:hover{border-color:var(--process)}
.fv-bar .fv-n{font-family:"Space Mono",monospace;font-size:11px;color:var(--muted)}
@media (max-width:720px){
  .fig{--fig-w:100%;margin-left:0}
}

/* A zone front page can run its panels three up (cols=3 in the manifest).
   Nine panels then read as a feature grid instead of a long column of pairs.
   The body type drops a step because the column is ~340px, not ~540px. */
.panels.three{grid-template-columns:repeat(3,1fr)}
.panels.three .panel{padding:24px 22px 22px}
.panels.three .panel h3{font-size:19px;line-height:1.26}
.panels.three .panel p{font-size:15.5px;line-height:1.62}
@media (max-width:1040px){ .panels.three{grid-template-columns:repeat(2,1fr)} }
@media (max-width:720px){ .panels.three{grid-template-columns:1fr} }

/* The numbers band. Deliberately off centre: the name holds a narrow left
   column, the figures take the right two thirds, and the whole block is hung
   towards the right edge of the measure so the page breathes on the left.
   Four stat cards inside a panel made that card twice the height of its
   neighbours -- numbers want air, and a grid cell is the wrong container. */
.statband{margin-top:6px}
.statband-in{
  display:grid;grid-template-columns:minmax(150px,.72fr) 2.4fr;
  gap:34px;align-items:center;
  /* Escape whatever measure the page sets -- a prose page is narrow by design
     (.narrow, 680px) and four stat cards inside it collapse to a cramped 2x2.
     Same technique as .prose .fig, with the centre pushed right so the band
     stays deliberately off centre rather than merely wide. */
  /* 100vw counts the vertical scrollbar, and the off-centre push below spends
     whatever slack is left on the right, so a four-card band crossed the
     right gutter on every page that has one. Reserve both: the push twice
     (it moves the right edge out as far as it moves the left edge in) and a
     scrollbar's width twice, for the same reason. */
  --sb-push:5%;
  --sb-w:min(calc(100vw - 2*var(--gutter) - 2*var(--sb-push) - 34px), 1180px);
  width:var(--sb-w);
  margin-left:calc(50% - var(--sb-w)/2 + var(--sb-push));
}
.statband .band-name{margin:0}
.statband .band-name h2{font-size:19px;letter-spacing:-.012em;line-height:1.2}
.statband .stats{margin:0}
.statband .stat{flex:1 1 120px}
@media (max-width:880px){
  .statband-in{grid-template-columns:1fr;width:100%;gap:14px;margin-left:0}
}

/* The globe behind the numbers (Jon, 2026-11-09): every numbers band, large, faint, cropped
   by the band's height, and never in front of anything. Its colour is the muted ink; the
   canvas reads it from here. The clip layer is as wide as the window and centred on it, so
   the band's own column never crops the globe or the cards; the page clips sideways so that
   layer cannot add a scrollbar's width of horizontal scroll. */
body:has(.globe-clip){overflow-x:clip}
.statband.has-globe{position:relative;padding-block:120px;margin-block:24px}
.statband.has-globe > .wrap{position:relative;z-index:1}
.globe-clip{position:absolute;z-index:0;top:0;bottom:0;left:calc(50% - 50vw);width:100vw;
  overflow:hidden;pointer-events:none}
.globe{position:absolute;left:calc(50% + 170px);top:50%;width:min(640px,80vw);aspect-ratio:1;
  transform:translateY(-50%);color:var(--muted);opacity:.22}
@media (max-width:880px){
  .statband.has-globe{padding-block:72px}
  .globe{left:auto;right:-30vw;width:110vw;opacity:.16}
}

/* ------------------------------------------------------------ disclosure
   Detail the reader opens on request (manifest collapse=True, 2026-11-05):
   a panel shows its claim and opens the rest; a band of screenshots stays
   shut until asked for. Native <details>: no script, keyboard and screen
   reader work as they are, and the text is still in the page. */
.panels:has(> .panel.collapsed){align-items:start}
/* Closed cards stay level: a one-line claim keeps two lines of room, the
   longest any claim runs, so the summaries line up across a row. */
.panel.collapsed h3{min-height:2.6em}
details.more,details.band-more{margin-top:14px}
details.more>summary,details.band-more>summary{
  list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:9px;
  font-family:"Space Mono",monospace;font-size:11.5px;letter-spacing:.08em;
  color:var(--muted);user-select:none;
}
details.more>summary::-webkit-details-marker,
details.band-more>summary::-webkit-details-marker{display:none}
details.more>summary::before,details.band-more>summary::before{
  content:"+";font-size:15px;line-height:1;color:var(--ink);width:10px;
}
details.more[open]>summary::before,details.band-more[open]>summary::before{content:"\2212"}
details.more>summary:hover,details.band-more>summary:hover{color:var(--ink)}
details.more>summary:focus-visible,details.band-more>summary:focus-visible{
  outline:2px solid var(--apex);outline-offset:3px;border-radius:2px;
}
details .when-open{display:none}
details[open]>summary .when-open{display:inline}
details[open]>summary .when-closed{display:none}
details.more[open]>summary{margin-bottom:12px}
details.band-more[open] .prose{margin-top:20px}

/* ------------------------------------------------------------------ rows
   One full-width row per claim (a copy file's "## Rows" section): the claim
   large on the left, its sentences on the right, a screenshot shut beneath
   both and opened at the row's full width. For claims that each deserve the
   width a grid cell cannot give them (AV front page, 2026-11-05). */
.band-intro{max-width:62ch;margin:10px 0 26px}
.band-intro p{margin:0;font-size:19px;line-height:1.5;color:var(--muted)}
.rows{border-bottom:1px solid var(--line)}
.row-claim{
  display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);
  gap:18px 64px;padding:46px 0;border-top:1px solid var(--line);
}
.row-claim h3{font-size:30px;line-height:1.16;letter-spacing:-.025em;margin:0}
/* A touch of the product's colour on each claim (Jon, 2026-11-05): the
   row's top rule turns the zone hue for exactly the headline's column,
   1px, so the colour sits with the claim and the text stays neutral. */
.row-claim{position:relative}
.row-claim::before{content:"";position:absolute;top:-1px;left:0;height:1px;
  width:calc((100% - 64px) * 5 / 12);background:var(--rail)}
.row-claim .row-body p{font-size:17px;line-height:1.68;margin:0 0 12px;max-width:62ch}
.row-claim .row-body p:last-child{margin-bottom:0}
.row-claim details.row-shot{grid-column:1/-1;margin-top:4px}
.row-claim details.row-shot .more-body{margin-top:18px}
.row-claim details.row-shot .fig{margin-top:18px;width:100%;margin-left:0}
@media (max-width:860px){
  .row-claim{grid-template-columns:1fr;gap:14px;padding:34px 0}
  .row-claim h3{font-size:25px}
  .row-claim::before{width:96px}
}

/* ---------------------------------------------------------------- evidence on hover
   {{phrase|evidence}} in the copy: the phrase is underlined in the zone hue
   and its evidence opens above it on hover, keyboard focus or a tap. */
.ev{position:relative;cursor:help;text-decoration:underline dotted var(--rail);
  text-decoration-thickness:1px;text-underline-offset:4px;outline:none}
.ev:focus-visible{outline:2px solid var(--rail);outline-offset:2px;border-radius:2px}
.ev-tip{position:absolute;left:0;bottom:calc(100% + 10px);z-index:20;
  width:max-content;max-width:min(360px,80vw);padding:10px 13px;
  background:var(--slab);border:1px solid var(--rail);border-radius:4px;
  font-size:14px;line-height:1.5;color:var(--ink);font-style:normal;
  box-shadow:0 8px 24px rgba(0,0,0,.35);
  opacity:0;visibility:hidden;transform:translateY(4px);
  transition:opacity .15s,transform .15s,visibility .15s;pointer-events:none}
.ev:hover .ev-tip,.ev:focus .ev-tip{opacity:1;visibility:visible;transform:none}
/* On a phone (2026-11-11): anchored to its phrase, a note on a phrase near the
   right of the column ran off the screen, and even hidden it widened the page
   (Translation scrolled sideways to 640px). There it belongs to the paragraph,
   not the phrase: it opens just above the paragraph, the paragraph's full width,
   so it can never pass the text column. (Not position:fixed: the panels animate
   with transforms, which capture a fixed child.) */
@media (max-width:819px){
  .ev{position:static}
  :is(p,li):has(.ev){position:relative}
  .ev-tip{left:0;right:0;bottom:calc(100% + 8px);width:auto;max-width:none}
}

/* ---------------------------------------------------------------- tabs
   A page's panel bands as tabs (manifest tabs=True; Jon, 2026-11-06). The bar
   exists only once the script has run; without it the bands stack. The tab
   names the band, so the band's own heading is hidden while tabbed. */
.tabset{margin-top:clamp(40px,6vw,64px)}
.tabbar{display:flex;gap:clamp(18px,4vw,44px);border-bottom:1px solid var(--line);flex-wrap:wrap}
.tabbar[hidden]{display:none}
.tabbar [role=tab]{
  appearance:none;background:none;border:0;border-bottom:2px solid transparent;
  margin:0 0 -1px;padding:0 0 14px;cursor:pointer;color:var(--muted);
  font-family:"Space Grotesk",sans-serif;font-weight:600;
  font-size:clamp(20px,2.4vw,27px);letter-spacing:-.016em;line-height:1.2;
}
.tabbar [role=tab]:hover{color:var(--ink)}
.tabbar [role=tab][aria-selected=true]{color:var(--ink);border-bottom-color:var(--rail)}
.tabbar [role=tab]:focus-visible{outline:2px solid var(--rail);outline-offset:4px}
.tabset.tabbed .band-name{display:none}
.tabset.tabbed .band{padding-top:28px}

/* ---------------------------------------------------------------- feature videos
   A row with a video (Jon, 2026-11-06): the heading and a sentence or two on the
   left, the video on the right. Played, it opens near full screen in a <dialog>
   over the page, rather than growing inside the column and pushing the page about. */
.vid-row{align-items:center;grid-template-columns:minmax(0,6fr) minmax(0,5fr)}
.vid-row::before{width:calc((100% - 64px) * 6 / 11)}
.vid-row h3{margin-bottom:14px}
.vid-row .row-body p{font-size:17px;line-height:1.6;margin:0 0 10px;max-width:46ch;color:var(--muted)}
.vid-row .row-body p:last-child{margin-bottom:0}
.vid{position:relative;display:block;aspect-ratio:1602/1032;border:1px solid var(--line);
  border-radius:8px;overflow:hidden;background:var(--slab);text-decoration:none;color:inherit}
.vid img{display:block;width:100%;height:100%;object-fit:cover;transition:transform .4s ease,opacity .2s}
a.vid:hover img,a.vid:focus-visible img{transform:scale(1.02);opacity:.9}
a.vid:focus-visible{outline:2px solid var(--rail);outline-offset:3px}
.vid-play{position:absolute;left:50%;top:50%;width:68px;height:68px;margin:-34px 0 0 -34px;
  border-radius:50%;background:rgba(11,10,18,.72);border:1px solid rgba(255,255,255,.35);
  transition:transform .2s,background .2s}
.vid-play::after{content:"";position:absolute;left:27px;top:21px;border-style:solid;
  border-width:13px 0 13px 21px;border-color:transparent transparent transparent #fff}
a.vid:hover .vid-play,a.vid:focus-visible .vid-play{transform:scale(1.08);background:var(--rail)}
.vid-len{position:absolute;right:10px;bottom:10px;padding:2px 8px;border-radius:4px;
  background:rgba(11,10,18,.78);color:#fff;font-size:13px;font-variant-numeric:tabular-nums}
.vid-soon{display:flex;align-items:center;justify-content:center;text-align:center;
  background:repeating-linear-gradient(135deg,var(--slab) 0 14px,var(--raised) 14px 28px)}
.vid-soon-in{display:flex;flex-direction:column;gap:8px;padding:0 24px}
.vid-soon-tag{font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--rail)}
.vid-soon-title{font-size:17px;line-height:1.35;color:var(--muted);max-width:30ch}
.vid-dialog{padding:0;border:0;background:#000;color:#fff;overflow:visible;
  width:min(96vw,calc(86vh * 1602 / 1032));max-width:none;max-height:none}
.vid-dialog::backdrop{background:rgba(5,4,10,.92)}
.vid-dialog video{display:block;width:100%;height:auto;max-height:86vh;background:#000}
.vid-close{position:absolute;top:-44px;right:0;width:36px;height:36px;border:0;border-radius:50%;
  background:rgba(255,255,255,.14);color:#fff;font-size:24px;line-height:36px;cursor:pointer}
.vid-close:hover,.vid-close:focus-visible{background:rgba(255,255,255,.3)}
@media (max-width:860px){
  .vid-row .row-body p{max-width:none}
  .vid-dialog{width:100vw}
  .vid-close{top:8px;right:8px;z-index:1}
}
@media (prefers-reduced-motion:reduce){
  .vid img,.vid-play{transition:none}
  a.vid:hover img{transform:none}
}

/* ---------------------------------------------------------------- the video ribbon
   A band's feature videos as a loop on a curve (Jon, 2026-11-09). The script places every
   card from one moving position (build_site.py RIBBON_SCRIPT); this sheet only sets the stage.
   Without script (no .ribbon-live) it is a plain strip that scrolls sideways, and every
   heading and sentence shows under it. */
.rows:has(> .ribbon){grid-template-columns:minmax(0,1fr)}
.ribbon{grid-column:1/-1;min-width:0;max-width:100%;margin:0 0 8px}
.ribbon-stage{position:relative;min-width:0}
.ribbon-track{--card:min(480px,calc(100vw - 120px));list-style:none;margin:0;display:flex;gap:20px;
  width:100%;min-width:0;box-sizing:border-box;
  padding:14px calc((100% - var(--card)) / 2) 18px;overflow-x:auto;scroll-snap-type:x mandatory;
  scrollbar-width:thin;scrollbar-color:var(--line) transparent}
.ribbon-item{flex:0 0 var(--card);scroll-snap-align:center;display:flex;flex-direction:column;gap:10px}
.ribbon-cap{font-size:14px;font-weight:600;line-height:1.3;text-align:center;color:var(--muted)}

/* Live: a 3D stage, every card absolutely placed at its middle. */
.rows-band:has(.ribbon-live){overflow-x:clip}
.ribbon-live .ribbon-stage{overflow:hidden;padding-block:6px 10px;margin-inline:calc(50% - 50vw)}
.ribbon-live .ribbon-prev{left:max(16px,calc(50vw - 50% - 8px))}
.ribbon-live .ribbon-next{right:max(16px,calc(50vw - 50% - 8px))}
.ribbon-live .ribbon-track{display:block;position:relative;overflow:visible;padding:0;
  height:calc(var(--card) * 1032 / 1602 + 122px);perspective:1400px;perspective-origin:50% 20%;
  scroll-snap-type:none;touch-action:pan-y;user-select:none;-webkit-user-select:none;cursor:grab}
.ribbon-live .ribbon-track:active{cursor:grabbing}
.ribbon-live .ribbon-item{position:absolute;left:50%;top:96px;width:var(--card);
  margin-left:calc(var(--card) / -2);will-change:transform,opacity;backface-visibility:hidden}
.ribbon-live .vid img{transition:none;will-change:transform}
.ribbon-live .vid{-webkit-user-drag:none}
/* The heading already shows, larger, under the strip (Jon, 2026-11-10: the text was duplicated),
   so the card's own caption is kept only for the plain no-script strip. */
.ribbon-live .ribbon-item .ribbon-cap{display:none}
.ribbon-live .ribbon-item:not([aria-current]) .vid-play,
.ribbon-live .ribbon-item:not([aria-current]) .vid-len{opacity:0}
.ribbon-live .ribbon-item .vid-play,.ribbon-live .ribbon-item .vid-len{transition:opacity .3s ease,transform .2s,background .2s}
.ribbon-live .ribbon-item[aria-current] .vid{box-shadow:0 0 0 2px var(--resolved),0 18px 40px rgba(11,10,18,.16)}

.ribbon-nav{position:absolute;top:calc(50% - 30px);z-index:200;width:44px;height:44px;padding:0;
  border:1px solid var(--line);border-radius:50%;background:var(--slab);color:var(--ink);
  font-size:30px;line-height:40px;cursor:pointer;box-shadow:var(--g-shadow,none)}
.ribbon-prev{left:4px}
.ribbon-next{right:4px}
.ribbon-nav:hover,.ribbon-nav:focus-visible{border-color:var(--resolved);color:var(--resolved)}
.ribbon-bar{display:flex;justify-content:center;align-items:center;gap:14px;margin:0 0 6px}
.ribbon-bar[hidden]{display:none}
.ribbon-count{margin:0;font-size:12px;letter-spacing:.14em;color:var(--muted);font-variant-numeric:tabular-nums}
.ribbon-pause{padding:3px 12px;border:1px solid var(--line);border-radius:999px;background:var(--slab);
  color:var(--muted);font:inherit;font-size:12px;letter-spacing:.08em;cursor:pointer}
.ribbon-pause:hover,.ribbon-pause:focus-visible{border-color:var(--resolved);color:var(--resolved)}
.ribbon-pause .when-held{display:none}
.ribbon-pause[aria-pressed="true"] .when-held{display:inline}
.ribbon-pause[aria-pressed="true"] .when-run{display:none}
.ribbon-detail{max-width:760px;margin:0 auto;text-align:center}
.ribbon-text{padding:6px 0 22px}
.ribbon-live .ribbon-text:not([data-on]){display:none}
.ribbon-live .ribbon-text[data-on]{animation:ribbon-in .45s cubic-bezier(.2,.8,.2,1)}
@keyframes ribbon-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.ribbon-text h3{margin:0 0 10px;font-size:26px}
.ribbon-text .row-body p{font-size:17px;line-height:1.6;color:var(--muted);margin:0 auto 10px;max-width:60ch}
.ribbon-text .row-body p:last-child{margin-bottom:0}
@media (max-width:860px){
  .ribbon-track{--card:calc(100vw - 96px);gap:12px}
  .ribbon-nav{display:none}
}
@media (prefers-reduced-motion:reduce){
  .ribbon-live .ribbon-text[data-on]{animation:none}
}

/* The Features page (Jon, 2026-11-06): each row a page, its title the link. */
.index-row h3 a{color:inherit;text-decoration:none}
.index-row h3 a:hover,.index-row h3 a:focus-visible{text-decoration:underline;text-underline-offset:5px;text-decoration-thickness:1px}
.index-row h3 a::after{content:" \2192";color:var(--rail);font-weight:400}

/* The overview film (2026-11-07): a silent loop at the top of a page; click for sound. */
.lede .vid.film, .vid.film{aspect-ratio:16/9;margin:6px 0 34px;overflow:hidden}
.film video{display:block;width:100%;height:100%;object-fit:cover;background:#F6F5FA}
/* A speaker icon only, bottom right: the film keeps its type inside a wide gutter, so the corner is clear. */
.film-cta{position:absolute;right:14px;bottom:14px;width:44px;height:44px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;background:rgba(11,10,18,.78);color:#fff;
  transition:transform .2s,background .2s}
.film-cta svg{display:block}
a.film:hover .film-cta,a.film:focus-visible .film-cta{transform:scale(1.08);background:#0B0A12}
@media (max-width:560px){
  .film-cta{right:8px;bottom:8px;width:32px;height:32px}
  .film-cta svg{width:18px;height:18px}
}

/* ============================================================================
   guide-light — EXPERIMENT (Jon, 2026-11-06): the marketing site dressed in the
   help site's UI (guides/samples/light, the approved Guide R design). Built as
   vertex.css plus this overlay, so nothing else in the site changes.
     python build/build_site.py --standard=guide-light --out=out/zones-guide-light
   IBM Plex Sans is self-hosted with the others (D5: tools/fonts/fetch_webfonts.py,
   /static/fonts/fonts.css), so nothing here names a third-party host.
   ========================================================================== */

/* Light always, the guides' values. (1,1,1) beats every theme rule above. */
html:root:not(#x){
  --intake:#C4006F; --process:#6E2FD9; --resolved:#0E8CA8; --apex:#1FB6D6;
  --ground:#F6F5FA; --slab:#FFFFFF; --raised:#EEECF4;
  --ink:#0B0A12; --muted:#6A6582; --line:#DEDBE8; --line-soft:#EAE8F1;
  --g-shadow:0 1px 2px rgba(11,10,18,.06), 0 8px 24px rgba(11,10,18,.07);
  --g-av-soft:#E3F5F9;
  color-scheme:light;
}

body{
  font-family:"IBM Plex Sans","Segoe UI",system-ui,sans-serif;
  font-size:17px; line-height:1.6;
}
h1,h2,h3,h4{letter-spacing:-.02em}

/* The masthead as the guides' top bar: a white strip with a hairline. */
header.site, body > header:first-of-type{background:var(--slab)}
.top{border-bottom:1px solid var(--line)}
.navlinks a{font-family:"IBM Plex Sans",sans-serif;font-size:14px;letter-spacing:0}

/* The menu strip: the guides' sans, not a mono label. */
.zonebar{font-family:"Space Grotesk","Segoe UI",sans-serif}
.zonebar a[aria-current="true"]{color:var(--resolved);text-decoration:none;
  box-shadow:inset 0 -2px 0 var(--resolved);padding-bottom:4px}

/* Page head and lede in the guides' proportions. */
.pagehead h1{font-size:clamp(2.2rem,4.4vw,3.1rem)}
.lede, .lede p{font-family:"IBM Plex Sans",sans-serif}

/* Every claim a card, as the guides' panels and index cards are. */
.rows{border-bottom:0;display:grid;gap:14px}
.row-claim{
  background:var(--slab);border:1px solid var(--line);border-radius:12px;
  padding:30px 32px;border-top:1px solid var(--line);box-shadow:var(--g-shadow);
}
.row-claim::before{display:none}
.row-claim h3{font-size:26px}
.row-claim .row-body p, .vid-row .row-body p{font-size:16.5px}
.band-intro p{font-family:"IBM Plex Sans",sans-serif;font-size:18px}

/* Older card grids and panels get the same card. */
.panel{background:var(--slab);border:1px solid var(--line);border-radius:12px;box-shadow:var(--g-shadow)}

/* Numbers band: the guides' metadata pills, larger. */
.stat{background:var(--slab);border:1px solid var(--line);border-left:1px solid var(--line);border-radius:12px;box-shadow:var(--g-shadow)}

/* Tabs as the guides' segmented look. */
.tabbar [role=tab]{border-radius:999px;padding:8px 18px}
/* Centred: the tabs are a switch for the whole section below, not a heading, and centred they sit
   under the centred intro column (Jon, 2026-11-11). The rule under them still runs full width; the
   band intro and the rows keep the left edge. */
.tabbar{justify-content:center}
.tabbar [role=tab][aria-selected="true"]{background:var(--g-av-soft);color:var(--resolved)}

/* Video placeholders and stills: the guides' rounded, shadowed frame. */
.vid{border-radius:12px;box-shadow:var(--g-shadow);border-color:var(--line)}
.vid-soon{background:repeating-linear-gradient(135deg,#F1EFF6 0 14px,#EAE7F2 14px 28px)}
.fig img, figure.fig img{border-radius:10px;box-shadow:var(--g-shadow)}

/* The eyebrow labels the guides keep (path, band names) stay mono but quieter. */
.eyebrow{letter-spacing:.1em}

/* Links in the guides' AV blue. */
.prose a, .row-body a, .lede a{color:var(--resolved);text-underline-offset:3px}

/* ---------------------------------------------------------------- the claim stage
   A band of claim rows as a pinned scroll stage (Jon, 2026-11-09; build_site.py STAGE_SCRIPT).
   .stage-live: the band holds still while the page scrolls through its claims, one card,
   every claim stacked inside it and placed by the script. .stage-rise: where the stage does
   not run (narrow screens), rows rise into view instead. Neither class exists without script,
   and with less motion neither is ever set. */
.rows.stage-live{display:block;position:relative}
.stage-pin{position:sticky;top:0;height:100vh;display:grid;grid-template-columns:auto minmax(0,1fr);
  align-items:center;gap:34px}
.stage-box{position:relative;background:var(--slab);border:1px solid var(--line);border-radius:12px;
  box-shadow:var(--g-shadow,none);padding:0;overflow:hidden;perspective:1100px;perspective-origin:20% 50%}
.stage-live .row-claim{position:absolute;inset:0;margin:0;background:none;border:0;box-shadow:none;
  align-content:center;pointer-events:none}
.stage-live .row-claim.stage-on{pointer-events:auto}
.stage-live .row-claim > *:not(h3){grid-column:2}
.stage-live .row-claim details.row-shot{margin-top:6px}
.stage-live .row-claim > *{will-change:transform,opacity}
.stage-live .row-claim h3,.stage-live .row-claim .row-body{will-change:transform,opacity;
  transform-origin:0 50%;backface-visibility:hidden}
.stage-live .row-claim{padding:40px 56px 40px 48px}
.stage-live .row-claim h3{font-size:clamp(30px,3vw,42px);line-height:1.12}
.stage-live .row-claim .row-body p{font-size:18px}
.stage-rail{display:flex;flex-direction:column;align-items:center;gap:14px;--fill:0%}
.stage-count{margin:0;font-size:12px;letter-spacing:.12em;color:var(--muted);font-variant-numeric:tabular-nums;
  writing-mode:vertical-rl;transform:rotate(180deg)}
.stage-rail ol{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px;position:relative}
.stage-rail ol::before{content:"";position:absolute;left:50%;top:0;width:1px;height:100%;background:var(--line)}
.stage-rail ol::after{content:"";position:absolute;left:50%;top:0;width:1px;height:var(--fill);background:var(--rail)}
.stage-tick{position:relative;z-index:1;display:block;width:14px;height:14px;padding:0;border:0;background:none;cursor:pointer}
.stage-tick::before{content:"";position:absolute;left:4px;top:4px;width:6px;height:6px;border-radius:50%;
  background:var(--line);transition:transform .25s ease,background .25s ease}
.stage-tick:hover::before,.stage-tick:focus-visible::before{background:var(--muted)}
.stage-tick[aria-current]::before{background:var(--rail);transform:scale(1.7)}
.stage-tick:focus-visible{outline:2px solid var(--rail);outline-offset:2px;border-radius:50%}
.stage-rise .row-claim{opacity:0;transform:translateY(28px)}
.stage-rise .row-claim h3{transform:translateX(-18px);transition:transform .7s cubic-bezier(.2,.8,.2,1) .05s}
.stage-rise .row-claim .row-body{opacity:0;transform:translateX(18px);
  transition:opacity .6s ease .18s,transform .7s cubic-bezier(.2,.8,.2,1) .18s}
.stage-rise .row-claim.row-in{opacity:1;transform:none;transition:opacity .5s ease,transform .7s cubic-bezier(.2,.8,.2,1)}
.stage-rise .row-claim.row-in h3,.stage-rise .row-claim.row-in .row-body{opacity:1;transform:none}

/* ---------------------------------------------------------------- animated diagrams
   A claim's signature diagram (build_site.py anim_html), under its text. It runs only while on
   screen (.anim-on), only while its claim is the one in front of the scroll stage, and not at
   all for a reader who asked for less motion, who sees its last frame. */
.anim{margin:22px 0 0;max-width:520px}
.anim svg{display:block;width:100%;height:auto;overflow:visible}
.anim text{font-family:inherit}
.anim:not(.anim-on) *{animation-play-state:paused!important}
.stage-live .row-claim:not(.stage-on) .anim *{animation-play-state:paused!important}
@media (prefers-reduced-motion:reduce){.anim *{animation:none!important}}

/* ---------------------------------------------------------------- the Ascent hero
   (Jon, 2026-11-10) The obsidian band at the top of a landing page, where characters climb the
   ramp and build the mark (build/ascent.js). Obsidian in both themes on purpose: the brand's
   primary mark is drawn for it, and "the ground is a property of the act, not of the reader's
   OS" (the Ascent deck standard). Its foot fades into the page's own ground. Without script, or
   for a reader who asked for less motion, it is the lockup on obsidian and nothing more. */
/* The band is a dark stage plus a 140px foot that fades into the page. The lockup is centred in
   the stage alone and sized by its height as well as its width (container units), so on a short
   window it shrinks rather than sliding into the fade (Jon, 2026-11-10: TECHNOLOGIES was half
   lost in it). 0.893 is the stacked lockup's width over its height. */
/* The band's colours. The site is light always, and the obsidian band on it was too harsh (Jon,
   2026-11-10), so the band is the page's own ground with the brand's light ramp and ink characters,
   and there is no seam. The dark values stay as the base for data-tone="dark" (--hero-tone=dark),
   for comparison. --asc-light tells ascent.js how strong to draw the drifting characters. */
.ascent{--asc-ground:#0B0A12;--asc-c1:#FF2D9B;--asc-c2:#9B5CFF;--asc-c3:#22D3EE;--asc-c4:#9BF0FA;
  --asc-ice:#EFEDF6;--asc-word:#FFFFFF;--asc-rule:#2E2A3E;--asc-bloom:155,240,250;--asc-bloom-k:1;--asc-light:0}
.ascent:not([data-tone="dark"]){--asc-ground:var(--ground);
  --asc-c1:#C4006F;--asc-c2:#6E2FD9;--asc-c3:#0E8CA8;--asc-c4:#1FB6D6;--asc-ice:#0B0A12;
  --asc-word:#0B0A12;--asc-rule:#D8D4E0;--asc-bloom:31,182,214;--asc-bloom-k:.45;--asc-light:1}
.ascent{--foot:140px;position:relative;overflow:hidden;height:calc(clamp(380px,62vh,600px) + var(--foot));
  margin:8px 0 0;isolation:isolate;container-type:size;
  background:linear-gradient(to bottom,var(--asc-ground) calc(100% - var(--foot)),var(--ground))}
.ascent-field{position:absolute;inset:0;width:100%;height:100%;display:block;z-index:1;
  -webkit-mask-image:linear-gradient(to bottom,transparent,#000 56px,#000 calc(100% - 210px),transparent calc(100% - 60px));
  mask-image:linear-gradient(to bottom,transparent,#000 56px,#000 calc(100% - 210px),transparent calc(100% - 60px))}
.ascent-lockup{position:absolute;left:50%;top:calc((100cqh - var(--foot)) / 2);z-index:2;
  width:min(var(--lockw,330px),62cqw,calc((100cqh - var(--foot) - 88px) * var(--ar,.893)));transform:translate(-50%,-50%)}
.ascent:first-child,.notice + .ascent{margin-top:0}
.ascent-lockup svg{display:block;width:100%;height:auto;overflow:visible}
.ascent-bloom{position:absolute;width:360px;height:360px;margin:-180px 0 0 -180px;z-index:0;opacity:0;
  pointer-events:none;background:radial-gradient(closest-side,rgba(var(--asc-bloom),calc(.38 * var(--asc-bloom-k))),
    rgba(var(--asc-bloom),calc(.10 * var(--asc-bloom-k))) 45%,rgba(var(--asc-bloom),0))}
.ascent:not(.ascent-live) .ascent-field{display:none}
.ascent-live .asc-m,.ascent-live .asc-w,.ascent-live .asc-d,.ascent-live .asc-s{opacity:0}
.ascent + .pagehead{margin-top:-40px;position:relative;z-index:4}
@media (max-width:620px){ .ascent{--foot:110px;height:calc(clamp(320px,52vh,460px) + var(--foot))} }

/* Read aloud, not shown (the quiet page head's h1). */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.ascent + .pagehead.quiet{margin-top:-56px}
.pagehead.quiet .lede .film{margin-top:32px;margin-bottom:32px}

/* Margin ornaments (Jon, 2026-11-11; build_site.py ornament_margins): beside the page head in the
   side margins, and a frieze above the footer. Hidden where the margins are too narrow for them. */
.pagehead{position:relative}
.il-mgl,.il-mgr{position:absolute;top:24px;width:280px;pointer-events:none}
/* Never into the bands below (2026-11-11): a page head shorter than the ornament (Philosophy, the
   partner pages) would put the pen and the pilcrow beside a section heading or behind a card. So the
   ornament box ends with its head and the drawing scales down, whole, to fit it (build_site.py sets
   preserveAspectRatio so each sits at the top, toward the text). A floor on the head's height keeps
   it from shrinking to a smudge. */
.il-mgl,.il-mgr{bottom:0}
.pagehead .il-mgl svg,.pagehead .il-mgr svg{height:100%}
@media (min-width:1200px){.pagehead:has(> .il-mgl){min-height:440px}}
.il-mgl{right:calc(100% + 56px)}
.il-mgr{left:calc(100% + 56px)}
.il-mgl svg,.il-mgr svg,.il-frz svg{display:block;width:100%;height:auto}
.il-frz{max-width:1100px;margin:72px auto 8px;padding:0 16px;pointer-events:none}
@media (max-width:1199px){.il-mgl,.il-mgr{display:none}}
@media (max-width:719px){.il-frz{display:none}}

/* ---------------------------------------------------------------- the doors
   The company home's two product cards, directly under the hero (Jon,
   2026-11-11: most visitors want one of the products). The card is the link.
   Its top edge is the product's colour: AV cyan (Resolved), TMS magenta
   (Intake), as the brand's product icons and lockups are. */
.doors-band{margin-top:clamp(28px,4vw,48px)}
.doors{max-width:1120px;margin:0 auto;padding:0 16px;display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(14px,2vw,24px)}
.door{display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:22px;row-gap:4px;
  align-content:start;text-decoration:none;color:var(--ink);background:var(--slab);
  border:1px solid var(--line);border-top:4px solid var(--line);border-radius:14px;
  padding:26px 28px 24px;box-shadow:var(--g-shadow,0 8px 24px rgba(0,0,0,.08));
  transition:transform .2s,box-shadow .2s}
.door:hover{transform:translateY(-3px)}
.door:focus-visible{outline:2px solid var(--apex);outline-offset:3px}
.door[data-p="av"]{border-top-color:var(--resolved)}
.door[data-p="tms"]{border-top-color:var(--intake)}
.door svg{grid-row:1 / span 4;width:64px;height:64px;margin-top:2px}
.door-k{font:11px "Space Mono",ui-monospace,monospace;letter-spacing:.2em;text-transform:uppercase;color:var(--muted)}
.door-t{font:600 clamp(24px,2.4vw,30px)/1.15 "Space Grotesk",system-ui,sans-serif;letter-spacing:-.01em}
.door-p{font-size:16px;line-height:1.55;color:var(--ink);opacity:.85;margin-top:4px}
.door-go{font:12px "Space Mono",ui-monospace,monospace;letter-spacing:.12em;margin-top:12px}
.door[data-p="av"] .door-go{color:var(--resolved)}
.door[data-p="tms"] .door-go{color:var(--intake)}
@media (max-width:719px){
  .doors{grid-template-columns:minmax(0,1fr)}
  .door{padding:22px 20px;column-gap:16px}
  .door svg{width:48px;height:48px}
}
@media (prefers-reduced-motion:reduce){.door{transition:none}.door:hover{transform:none}}
/* Above the fold (2026-11-11): on the company home the hero is shorter and the
   doors rise into its faded foot, so on a laptop screen both cards are in view
   before any scroll. The AV and TMS heroes are unchanged (no doors follow them). */
.ascent:has(+ .doors-band){height:calc(clamp(320px,46vh,480px) + var(--foot))}
.ascent + .doors-band{margin-top:-96px;position:relative;z-index:4}
@media (max-width:620px){
  .ascent:has(+ .doors-band){height:calc(clamp(200px,30vh,260px) + var(--foot))}
  .ascent + .doors-band{margin-top:-64px}
  /* On a phone the two doors are side-by-side tiles, so both are on the first screen: icon, name,
     what it is. The sentence and the "Go to" line wait for the product's own page. */
  .doors{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px}
  .door{display:flex;flex-direction:column;align-items:flex-start;gap:6px;padding:16px 14px 18px}
  .door svg{width:40px;height:40px;margin:0 0 4px}
  .door-t{font-size:20px;order:1}.door-k{order:2;font-size:10px;letter-spacing:.14em}
  .door-p,.door-go{display:none}
}

/* ---------------------------------------------------------------- company home: cards, close
   (2026-11-11) A row of cards ([CARDS] in the copy) and a closing band ([CLOSE]), at the page's
   wide measure. A card with a link is the link. Pictures inside are the anims, played once. */
.doors-note{max-width:1120px;margin:18px auto 0;padding:0 16px;text-align:center;
  font-size:16px;line-height:1.55;color:var(--muted)}
.cards-band{margin:clamp(56px,7vw,96px) 0 0}
.cards-band .wrap{max-width:1120px;margin:0 auto;padding:0 16px}
.cards-band .band-name{display:flex;align-items:center;gap:14px;margin-bottom:22px}
.cards-band .band-name h2{margin:0;font:600 clamp(22px,2.2vw,28px)/1.2 "Space Grotesk",system-ui,sans-serif;letter-spacing:-.01em}
.cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(14px,2vw,22px)}
.card{display:flex;flex-direction:column;gap:8px;text-decoration:none;color:var(--ink);background:var(--slab);
  border:1px solid var(--line);border-radius:14px;padding:22px 24px 20px;box-shadow:var(--g-shadow,none);
  transition:transform .2s}
a.card:hover{transform:translateY(-3px)}
a.card:focus-visible{outline:2px solid var(--apex);outline-offset:3px}
.card figure.anim{margin:0 0 10px;padding:14px 14px 10px;border-radius:10px;background:var(--ground)}
.card figure.anim svg{display:block;width:100%;height:auto}
.card-t{margin:0;font:600 19px/1.3 "Space Grotesk",system-ui,sans-serif;letter-spacing:-.005em}
.card p{margin:0;font-size:15.5px;line-height:1.55;opacity:.88}
.card-go{margin-top:auto;padding-top:10px;font:11.5px "Space Mono",ui-monospace,monospace;letter-spacing:.12em;color:var(--rail)}
.cards-more{margin:18px 0 0;font:12px "Space Mono",ui-monospace,monospace;letter-spacing:.12em}
.cards-more a{color:var(--rail)}
.close-band{margin:clamp(64px,8vw,112px) 0 0}
.close-band .wrap{max-width:1120px;margin:0 auto;padding:0 16px}
.close-in{border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:clamp(36px,5vw,56px) 0;
  display:flex;flex-direction:column;align-items:center;text-align:center;gap:22px}
.close-p{margin:0;max-width:34ch;font:500 clamp(21px,2.3vw,28px)/1.4 "Space Grotesk",system-ui,sans-serif;letter-spacing:-.01em}
.close-btns{display:flex;gap:12px;flex-wrap:wrap;justify-content:center}
.close-btn{font:12px "Space Mono",ui-monospace,monospace;letter-spacing:.14em;text-transform:uppercase;text-decoration:none;
  color:var(--ink);border:1px solid var(--ink);border-radius:999px;padding:11px 20px}
.close-btn:hover{background:var(--ink);color:var(--ground)}
@media (max-width:899px){.cards{grid-template-columns:minmax(0,1fr)}}
@media (prefers-reduced-motion:reduce){.card{transition:none}a.card:hover{transform:none}}
/* The cards share their rows (2026-11-11, Jon: "all the bold headlines to line up better"): each
   card spans the row's four tracks (picture, headline, text, link) through subgrid, so a headline
   that wraps moves every card's text down together, not just its own. And a card no longer lifts
   on hover: beside cards that do not move, a lifted one reads as out of line. Its border answers
   instead. Without subgrid the cards fall back to the column layout above. */
@supports (grid-template-rows:subgrid){
  .cards{grid-template-rows:repeat(4,auto)}
  .card{display:grid;grid-row:span 4;grid-template-rows:subgrid;row-gap:8px}
  .card-pic:empty{display:block;height:0}
  .card-go{align-self:end}
}
.card-pic figure.anim{margin:0 0 10px}
.card-body{display:flex;flex-direction:column;gap:8px}
a.card:hover{transform:none;border-color:var(--rail)}
@media (max-width:899px){
  .cards{grid-template-rows:none}
  .card{grid-row:auto;grid-template-rows:none;display:flex}
}
/* Cards two to a row ([CARDS: 2], the Philosophy page's eight convictions, 2026-11-11), and a
   card's small icon ([ICON: name]). With more than one row of cards the subgrid's tracks are made
   as needed (grid-auto-rows), four per row of cards, so each row still lines up on its own. */
@supports (grid-template-rows:subgrid){ .cards{grid-template-rows:none;grid-auto-rows:auto} }
.cards[data-cols="2"]{grid-template-columns:repeat(2,minmax(0,1fr))}
.card-icon{display:block;width:44px;height:44px;margin:0 0 6px}
.card-icon svg{display:block;width:100%;height:100%}
@media (max-width:899px){.cards[data-cols="2"]{grid-template-columns:minmax(0,1fr)}}
/* A card section's introduction and closing prose (2026-11-11), at the prose measure. Four to a
   row ([CARDS: 4], For consultancies' four words), two on a tablet, one on a phone. */
.cards-lead{margin:0 0 22px;max-width:70ch;font-size:17px;line-height:1.6}
.cards-after{margin:22px 0 0;max-width:70ch;font-size:17px;line-height:1.65}
.cards[data-cols="4"]{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:1099px){.cards[data-cols="4"]{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:899px){.cards[data-cols="4"]{grid-template-columns:minmax(0,1fr)}}
/* Dashed cards ([CARDS: 3 dashed], 2026-11-11): the limits on For consultancies, drawn like the
   "Not built" card above them, so the set reads as one thing. Three to a row. */
.cards[data-cols="3"]{grid-template-columns:repeat(3,minmax(0,1fr))}
.cards[data-tone="dashed"] .card{border-style:dashed;border-color:var(--muted);box-shadow:none;background:transparent}
@media (max-width:899px){.cards[data-cols="3"]{grid-template-columns:minmax(0,1fr)}}

/* ---------------------------------------------------------------- chapters (Jon, 2026-11-11)
   A long page whose manifest says chapters=True (/technology): each chapter's head carries its
   icon and its number set apart, so the six chapters outrank their own subheads (h3). The rail
   lists them in the left margin once the page head has gone by and marks the one being read; it
   steps aside while a full-width figure, the ornaments or the footer pass behind it. */
.chap{display:grid;grid-template-columns:56px 1fr;column-gap:20px;align-items:end;
  margin:96px 0 0;padding-top:34px;border-top:1px solid var(--line);scroll-margin-top:24px}
.prose > .chap:first-child{margin-top:40px;border-top:0;padding-top:0}
.chap-pic{grid-row:1 / span 2;align-self:center;display:block;width:56px;height:56px}
.chap-pic svg{display:block;width:100%;height:100%}
.chap-n{grid-column:2;margin:0 !important;font-family:"Space Mono",monospace;font-size:11px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--rail)}
.prose .chap h2{grid-column:2;margin:4px 0 0;padding:0;border:0;font-size:clamp(26px,3.1vw,36px)}
.prose .chap + h3{margin-top:30px}
/* section_icons (the Price page): the icon beside the heading, no chapter number above it */
.chap.plain{align-items:center;margin-top:72px;padding-top:30px}
.chap.plain .chap-pic{grid-row:1;width:48px;height:48px}
.prose .chap.plain h2{margin:0;font-size:clamp(24px,2.8vw,32px)}

.chap-rail{display:none}
@media (min-width:1240px){
  .chap-rail{display:block;position:fixed;top:120px;right:calc(50% + 372px);width:200px;z-index:5;
    opacity:0;visibility:hidden;transition:opacity .25s ease,visibility 0s linear .25s}
  .chap-rail.on{opacity:1;visibility:visible;transition:opacity .25s ease}
}
@media (min-width:1240px) and (prefers-reduced-motion:reduce){.chap-rail,.chap-rail.on{transition:none}}
.cr-h{margin:0 0 12px;font-family:"Space Mono",monospace;font-size:11px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--muted)}
.chap-rail ol{list-style:none;margin:0;padding:0;border-left:1px solid var(--line)}
.chap-rail a{display:grid;grid-template-columns:18px 1fr;gap:6px;padding:7px 0 7px 14px;margin-left:-1px;
  border-left:2px solid transparent;color:var(--muted);text-decoration:none;font-size:13.5px;line-height:1.35}
.chap-rail a:hover{color:var(--ink)}
.chap-rail a[aria-current]{color:var(--ink);border-left-color:var(--rail)}
.cr-n{font-family:"Space Mono",monospace;font-size:11px;padding-top:2px;color:var(--rail)}
