/* Harobanda — the declared machine. Shared stylesheet. */
:root{
  --bg:#e8e8e3; --surface:#f3f2ee; --raise:#fbfaf6;
  --ink:#191d22; --muted:#585f67; --faint:#8b9099;
  --line:#d3d2cb; --line-strong:#bebdb4;
  --river:#1c5c66; --river-bright:#2b7d88; --river-wash:#dde8e8;
  --laterite:#a9552a; --laterite-wash:#efe0d5;
  --kept:#3f7350; --kept-wash:#dde7dd;
  --panel:#14181d; --panel-ink:#d9d6cc; --panel-faint:#7f8994;
  --panel-river:#5bb3bd; --panel-lat:#d98a52; --panel-kept:#79b98c;
  --panel-line:#2a3138;
  --serif:'Spectral',Georgia,'Times New Roman',serif;
  --sans:'IBM Plex Sans',system-ui,-apple-system,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,'SF Mono',Menlo,monospace;
  --gutter:clamp(20px,5vw,64px);
  --measure:66ch;
  /* the top bar is the logo plus its padding (11 + 11) and its 1px rule; the
     home page pulls its photograph up by exactly this much, so the two read
     one number (app.js makes it exact if the bar is ever taller) */
  --logo-h:57px;
  --bar-h:calc(var(--logo-h) + 23px);
  color-scheme:light;
}
*{box-sizing:border-box}
body{background:var(--bg);color:var(--ink);font-family:var(--sans);
  font-size:16px;line-height:1.6;margin:0;-webkit-font-smoothing:antialiased;
  text-underline-offset:.18em;}
h1,h2,h3,h4{font-family:var(--serif);font-weight:500;line-height:1.12;
  text-wrap:balance;margin:0;letter-spacing:-.01em;}
p{margin:0}
a{color:var(--river);text-decoration-color:color-mix(in srgb,var(--river) 40%,transparent);}
a:hover{text-decoration-color:var(--river);}
:focus-visible{outline:2px solid var(--river-bright);outline-offset:3px;border-radius:2px;}
code,pre{font-family:var(--mono);}

.wrap{max-width:1080px;margin:0 auto;padding-inline:var(--gutter);}
.prose{max-width:var(--measure);}
.eyebrow{font-family:var(--mono);font-size:15px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--river);font-weight:500;}
.eyebrow.lat{color:var(--laterite);}
.lead{font-family:var(--serif);font-size:18px;line-height:1.45;
  color:var(--ink);font-weight:400;}
.prose p:not(.lead):not(.eyebrow):not(.pull){font-size:18px;line-height:1.65;}
p.prose:not(.lead):not(.pull){font-size:18px;line-height:1.65;}
.muted{color:var(--muted);}
.sec-head{display:flex;flex-direction:column;gap:14px;margin-bottom:clamp(26px,4vw,42px);}
.sec-head h2{font-size:clamp(27px,4.2vw,44px);}

/* ---------- top bar ---------- */
.bar{position:sticky;top:env(safe-area-inset-top,0px);z-index:40;
  background:color-mix(in srgb,var(--bg) 86%,transparent);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border-bottom:1px solid var(--line);}
.bar-in{max-width:1080px;margin:0 auto;padding:11px var(--gutter);
  display:flex;align-items:center;gap:16px;position:relative;}
.brand{font-family:var(--serif);font-weight:600;font-size:17px;letter-spacing:-.01em;
  display:flex;align-items:center;gap:10px;color:var(--ink);text-decoration:none;}
.brand svg{width:22px;height:14px;color:var(--river);flex:none;}
.brand .brandtag{color:var(--muted);font-family:var(--mono);font-size:13px;
  letter-spacing:.1em;text-transform:uppercase;font-weight:400;}
.brandmark{display:block;height:var(--logo-h);width:auto;flex:none;}
@media(max-width:560px){
  .brand .brandtag{display:none;}
  :root{--logo-h:48px;}
}
.nav{margin-left:auto;display:flex;gap:clamp(15px,2vw,30px);align-items:center;}
.nav a{font-size:16.5px;color:var(--muted);text-decoration:none;font-weight:500;
  position:relative;white-space:nowrap;}
.nav a:hover{color:var(--river);}
.nav a.active{color:var(--river);}
.nav a.active::after{content:"";position:absolute;left:0;right:0;bottom:-7px;
  height:2px;border-radius:2px;background:var(--river);}
/* The one link on this site that leaves it. Always visible: it is the only
   thing a convinced reader can act on, so it does not hide behind a menu. */
.ghlink{display:inline-flex;align-items:center;color:var(--muted);flex:none;
  padding:4px;border-radius:6px;}
.ghlink svg{display:block;width:22px;height:22px;fill:currentColor;}
.ghlink:hover{color:var(--ink);}
.menu-btn{display:none;background:none;border:1px solid var(--line-strong);border-radius:7px;
  padding:7px 10px;cursor:pointer;color:var(--ink);margin-left:auto;}
.menu-btn svg{display:block;width:18px;height:14px;stroke:currentColor;stroke-width:1.9;fill:none;}
@media(max-width:900px){
  /* DOM order is brand, button, nav, mark -- but the mark reads better
     beside the wordmark's end than past the button, so it is ordered. */
  .menu-btn{display:inline-flex;order:2;margin-left:12px;}
  .ghlink{order:1;margin-left:auto;}
  .nav{position:absolute;top:calc(100% + 1px);left:0;right:0;margin-left:0;flex-direction:column;
    align-items:stretch;gap:0;background:var(--surface);border-bottom:1px solid var(--line);
    padding:2px var(--gutter) 12px;box-shadow:0 22px 44px -30px rgba(0,0,0,.45);}
  .nav:not(.open){display:none;}
  .nav a{padding:14px 2px;border-bottom:1px solid var(--line);font-size:17px;color:var(--ink);}
  .nav a.active{color:var(--river);}
  .nav a.active::after{left:2px;right:auto;width:30px;bottom:8px;}
}

/* The path (StzZui: the-path-shows-every-depth). A map of the branch, not a
   record of the walk: it reads the same on every page of the branch and only
   the highlight moves, so a reader who follows it can SEE that he moved. The
   top depth is the menu's job, so the path shows only what sits under it.
   Current position by COLOUR ALONE, and hover left unstyled -- the pointer
   already becomes a hand, and painting hover in the current-position colour
   claims "you are here" about a place the reader is not. */
.path{border-bottom:1px solid var(--line);background:var(--surface);}
.path-in{max-width:1080px;margin:0 auto;padding:11px var(--gutter);
  display:flex;flex-wrap:wrap;gap:4px clamp(20px,3vw,34px);}
.path a{font-size:18px;line-height:1.5;color:var(--muted);text-decoration:none;
  white-space:nowrap;}
.path a.here{color:var(--river);font-weight:700;}
/* The author asked for bold on the current step. StzZui's
   the-path-shows-every-depth says 'mark the current position by colour
   alone'; this is an amendment to that rule, made knowingly, not an
   oversight. Hover stays unstyled, which is the part of the rule that
   guards against claiming 'you are here' about a place you are not. */

/* ---------- pages ---------- */
.pagehead{padding-top:clamp(40px,6vw,74px);padding-bottom:clamp(28px,4vw,46px);border-bottom:1px solid var(--line);}
.pagehead .eyebrow{margin-bottom:14px;}
.pagehead h1{font-size:clamp(32px,5.4vw,54px);letter-spacing:-.02em;line-height:1.04;max-width:22ch;}
.pagehead .lead{margin-top:18px;max-width:64ch;}
.block{padding-top:clamp(40px,5.5vw,68px);}


.explore{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,2vw,18px);}
@media(max-width:820px){.explore{grid-template-columns:1fr 1fr;}}
@media(max-width:520px){.explore{grid-template-columns:1fr;}}
.xcard{display:flex;flex-direction:column;gap:6px;text-decoration:none;background:var(--surface);
  border:1px solid var(--line);border-radius:13px;padding:clamp(18px,2.4vw,24px);
  transition:border-color .2s,transform .2s;}
.xcard:hover{border-color:var(--river);transform:translateY(-2px);}
/* The actionable card is the only one that leaves the site, so it looks
   unlike the eight that do not. */
.xcard.act{border-color:var(--river);background:var(--river-wash);}
.xcard.act .k,.xcard.act .go{color:var(--river);}
.xcard.act h3{color:var(--ink);}
/* It is also where every way in ends, so it takes the whole last row --
   as wide as the bridge beneath it -- instead of sitting alone in the
   first column while the others stand empty. Its text keeps a reading
   measure, because a row this wide is not a line anyone reads. */
.xcard.act{grid-column:1 / -1;}
.xcard.act p{max-width:66ch;}
.xcard .k{font-family:var(--mono);font-size:13px;color:var(--river);letter-spacing:.08em;text-transform:uppercase;}
.xcard h3{font-size:20px;color:var(--ink);margin-top:2px;}
.xcard p{font-size:18px;color:var(--muted);line-height:1.5;}
.xcard .go{margin-top:auto;padding-top:10px;font-family:var(--mono);font-size:13.5px;color:var(--river);}

/* ---------- hero ---------- */
.hero{padding-top:clamp(30px,4vw,48px);padding-bottom:clamp(14px,2.4vw,26px);}
.hero + .block{padding-top:clamp(8px,2vw,22px);}
.hero-grid{display:grid;grid-template-columns:1fr 1.02fr;gap:clamp(28px,4.5vw,54px);align-items:start;}
@media(max-width:880px){.hero-grid{grid-template-columns:1fr;gap:32px;}}
/* A grid item defaults to min-width:auto, so one long line in a terminal
   widens its whole track and pushes the page sideways -- even though the
   terminal itself scrolls. Measured at 375px: index 412, machine 628. */
.hero-grid>*,.grid2>*,.stack-gap>*{min-width:0;}
.hero-meta{margin:0 0 clamp(20px,3vw,32px);display:flex;flex-wrap:wrap;gap:10px 8px;}
.hero#declare{scroll-margin-top:var(--bar-h);}
.chip{font-family:var(--mono);font-size:13px;letter-spacing:.04em;
  border:1px solid var(--line-strong);color:var(--muted);padding:5px 10px;border-radius:100px;}
.chip b{color:var(--river);font-weight:500;}
.cap{font-family:var(--sans);font-size:18px;color:var(--muted);margin-top:9px;line-height:1.5;}
.cap b{color:var(--river);font-weight:600;}

/* ---------- the home page: a photograph, full screen, the menu over it ----------
   The recipe is the Softanza site's home page (stzsite, assets/css/site.css),
   applied to this photograph. The picture starts at the top of the browser,
   under the menu, and fills the screen; a quiet panel on the water holds the
   sentence and one way to go on. The menu floats over the picture as white
   letters, each with its own dark halo, because no single colour reads over a
   sky that runs from gold to blue; once the reader has scrolled past the
   picture it is the ordinary bar again (app.js says when). On a phone the
   picture is a block of its own and the panel sits under it, on the page's
   own paper. */
.hero-photo{position:relative;z-index:0;height:100vh;height:100svh;min-height:520px;
  margin-top:calc(-1 * var(--bar-h));overflow:hidden;background:#15110D;}
.hero-img{position:absolute;inset:0;width:100%;height:100%;max-width:none;
  object-fit:cover;object-position:50% 40%;border:0;border-radius:0;}
/* A screen taller than wide shows under half of the picture's width. Centred,
   that slices the sun in two at the edge; the bridge is what the site is named
   for, so a portrait crop keeps the bridge and the water in front of it. */
@media(max-aspect-ratio:9/10){.hero-img{object-position:72% 40%;}}
.hero-panel{position:absolute;bottom:40px;
  left:max(var(--gutter),calc((100% - 1080px) / 2 + var(--gutter)));
  width:min(600px,calc(100% - 2 * var(--gutter)));
  background:rgba(20,24,29,.62);color:#fff;border-radius:14px;padding:24px 28px;
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);}
.hero-panel .eyebrow{color:#fff;}
.hero-panel h1{margin-top:10px;font-size:clamp(34px,3.6vw,48px);font-weight:500;
  letter-spacing:-.02em;line-height:1.05;color:#fff;}
.hero-panel h1 .l1{white-space:nowrap;}
.hero-panel h1 em{font-style:italic;font-weight:400;color:var(--panel-river);}
.hero-sub{margin-top:14px;font-family:var(--serif);font-size:clamp(18px,1.5vw,20px);
  line-height:1.42;color:#fff;}
.down{display:inline-flex;align-items:center;justify-content:center;width:52px;height:52px;
  margin-top:18px;border:2px solid #fff;border-radius:50%;color:#fff;text-decoration:none;
  font-size:1.5rem;line-height:1;}
/* The arrow nudges downward, gently, so a reader who thinks the page ends at
   the picture knows it goes on. It is the one motion on the site, and it stays
   still for a reader whose system asks for reduced motion (the rule at the
   foot of this file). */
.down:hover{background:rgba(255,255,255,.16);}
.down span{display:inline-block;animation:nudge 2.6s ease-in-out infinite;}
@keyframes nudge{0%,55%,100%{transform:translateY(0);}27%{transform:translateY(7px);}}
/* The menu over the picture. Gated on .js, which the page sets in its head, so
   that a reader without script keeps the ordinary frosted bar over the picture
   instead of white letters that nothing ever turns back. */
.js .home-body.over-hero .bar{background:rgba(12,14,13,.40);border-bottom-color:transparent;
  -webkit-backdrop-filter:none;backdrop-filter:none;}
.js .home-body.over-hero .brandmark{filter:brightness(0) invert(1)
  drop-shadow(0 0 1px rgba(0,0,0,.95)) drop-shadow(0 0 4px rgba(0,0,0,.7));}
.js .home-body.over-hero .ghlink{color:#fff;}
.js .home-body.over-hero .menu-btn{color:#fff;border-color:rgba(255,255,255,.85);}
.js .home-body.over-hero .ghlink svg,.js .home-body.over-hero .menu-btn svg{
  filter:drop-shadow(0 0 1px rgba(0,0,0,.95)) drop-shadow(0 0 4px rgba(0,0,0,.7));}
.js .home-body.over-hero :focus-visible{outline-color:#fff;}
/* Only where the links sit on the bar itself: below 900px they are in a
   dropdown with a paper of its own, and white on paper would not be read. */
@media(min-width:901px){
  .js .home-body.over-hero .nav a{color:#fff;
    text-shadow:0 0 1px rgba(0,0,0,.95),0 0 3px rgba(0,0,0,.85),0 0 10px rgba(0,0,0,.6);}
}
@media(max-width:760px){
  .hero-photo{height:auto;min-height:0;background:var(--bg);}
  .hero-img{position:static;display:block;width:100%;height:58svh;min-height:320px;
    object-position:72% 50%;}
  .hero-panel{position:static;width:auto;background:none;color:var(--ink);
    padding:24px var(--gutter) 8px;border-radius:0;}
  .hero-panel .eyebrow,.hero-panel h1 em{color:var(--river);}
  .hero-panel h1{font-size:40px;color:var(--ink);}
  .hero-sub{color:var(--ink);}
  .down{border-color:var(--river);color:var(--river);}
  .down:hover{background:var(--river-wash);}
}

/* transcript panel */
.term{background:var(--panel);border-radius:12px;overflow:hidden;
  border:1px solid var(--panel-line);box-shadow:0 22px 46px -30px rgba(0,0,0,.5);}
.term-bar{display:flex;align-items:center;gap:7px;padding:11px 14px;border-bottom:1px solid var(--panel-line);}
.term-bar i{width:9px;height:9px;border-radius:50%;background:var(--panel-line);display:block;}
.term-bar b{margin-left:8px;font-family:var(--mono);font-size:13px;color:var(--panel-faint);font-weight:400;letter-spacing:.04em;}
.term pre{margin:0;padding:15px 16px 17px;font-family:var(--mono);font-size:14.5px;line-height:1.7;
  color:var(--panel-ink);white-space:pre-wrap;overflow-x:hidden;overflow-wrap:break-word;}
.term .c{color:var(--panel-river);}
.term .k{color:var(--panel-kept);}
.term .r{color:var(--panel-lat);}
.term .d{color:var(--panel-faint);}
.term .b{color:#e9e6dd;font-weight:500;}
.term .kw{color:var(--panel-river);font-weight:500;}

/* ---------- generic ---------- */
.stack-gap{display:flex;flex-direction:column;gap:clamp(14px,2vw,20px);}
/* Below 880 the site is one column. Measured at 768, three columns put the
   comparison table at 188px and a ground row at 170px -- 18px text in a
   column that narrow is text nobody reads -- and squeezed a terminal into
   326px. 880 is where .hero-grid already stacks, so it is one rule, not four. */
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:clamp(18px,2.6vw,30px);}
@media(max-width:880px){.grid2{grid-template-columns:1fr;}}
.panel{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:clamp(20px,2.6vw,28px);}
.panel.ex{border-left:3px solid var(--laterite);}

.four{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;}
@media(max-width:820px){.four{grid-template-columns:1fr 1fr;}}
@media(max-width:440px){.four{grid-template-columns:1fr;}}
.trio{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,2vw,18px);}
@media(max-width:820px){.trio{grid-template-columns:1fr;}}

.card{background:var(--surface);border:1px solid var(--line);border-radius:11px;padding:18px 16px;display:flex;flex-direction:column;gap:9px;}
.card .n{font-family:var(--mono);font-size:13px;color:var(--muted);letter-spacing:.1em;}
.card h4{font-size:18px;color:var(--river);letter-spacing:0;}
.card p{font-size:18px;color:var(--ink);line-height:1.6;}
.kind h4{color:var(--ink);font-size:19px;font-family:var(--serif);}
.kind .tagline{font-family:var(--mono);font-size:13px;color:var(--laterite);letter-spacing:.04em;text-transform:uppercase;}
.kind p{font-size:18px;color:var(--ink);line-height:1.6;}
.kind p b{color:var(--ink);font-weight:600;}
.card ul{margin:2px 0 0;padding:0;list-style:none;display:flex;flex-direction:column;gap:8px;}
.card li{font-size:18px;line-height:1.6;color:var(--ink);padding-left:18px;position:relative;}
.card li::before{content:"›";position:absolute;left:0;color:var(--river);font-family:var(--mono);}
.card li b{color:var(--ink);font-weight:600;}

.cmp{display:grid;grid-template-columns:1.05fr 1.35fr 1.35fr;border:1px solid var(--line);border-radius:12px;overflow:hidden;background:var(--line);gap:1px;}
@media(max-width:880px){.cmp{grid-template-columns:1fr;}}
.cmp>div{background:var(--surface);padding:13px 18px;font-size:18px;line-height:1.5;}
.cmp .h{background:var(--raise);font-family:var(--mono);font-size:15px;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);font-weight:500;}
.cmp .h.us{color:var(--river);}
.cmp .lbl{font-weight:600;color:var(--ink);font-family:var(--sans);}
.cmp .them-c{color:var(--muted);}
.cmp .us-c{color:var(--ink);background:var(--river-wash);}
.cmp .us-c b{color:var(--river);font-weight:600;}
@media(max-width:680px){
  .cmp .lbl{background:var(--raise);}
  .cmp .them-c::before{content:"Their OS — ";color:var(--muted);font-family:var(--mono);font-size:13px;}
  .cmp .us-c::before{content:"Harobanda — ";color:var(--river);font-family:var(--mono);font-size:13px;}
  .cmp .h{display:none;}
}

.versus{display:grid;grid-template-columns:1fr 1fr;gap:2px;border-radius:12px;overflow:hidden;border:1px solid var(--line);}
@media(max-width:680px){.versus{grid-template-columns:1fr;}}
.versus>div{padding:clamp(20px,2.6vw,28px);background:var(--surface);}
.versus .us{background:var(--river-wash);}
.versus h4{font-size:15px;font-family:var(--mono);font-weight:500;letter-spacing:.02em;text-transform:none;margin-bottom:14px;}
.versus .them h4{color:var(--muted);}
.versus .us h4{color:var(--river);}
.versus ul{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:11px;}
.versus li{font-size:18px;line-height:1.5;padding-left:20px;position:relative;color:var(--ink);}
.versus li::before{position:absolute;left:0;top:0;font-family:var(--mono);font-size:14.5px;}
.versus .them li::before{content:"×";color:var(--muted);}
.versus .us li::before{content:"→";color:var(--river);}

.refuses{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--line);border:1px solid var(--line);border-radius:12px;overflow:hidden;}
@media(max-width:560px){.refuses{grid-template-columns:1fr;}}
.refuses>div{background:var(--surface);padding:18px 20px;display:flex;flex-direction:column;gap:5px;}
.refuses b{font-size:18px;color:var(--ink);}
.refuses b::before{content:"no ";color:var(--laterite);}
.refuses span{font-size:18px;color:var(--muted);line-height:1.5;}

.grounds{display:flex;flex-direction:column;gap:1px;background:var(--line);border:1px solid var(--line);border-radius:12px;overflow:hidden;}
.ground-row{background:var(--surface);display:grid;grid-template-columns:.85fr 1.15fr 1fr;gap:18px;padding:18px 20px;align-items:start;}
@media(max-width:880px){.ground-row{grid-template-columns:1fr;gap:8px;}}
.ground-row .p{display:flex;flex-direction:column;gap:3px;}
.ground-row .en{font-size:18px;font-weight:600;color:var(--ink);}
.ground-row .lc{font-family:var(--mono);font-size:13px;color:var(--river);}
.ground-row .prob{font-size:18px;color:var(--muted);line-height:1.5;}
.ground-row .prob b{color:var(--laterite);font-weight:500;}
.ground-row .fix{font-size:18px;color:var(--ink);line-height:1.5;}
.ground-row .fix b{color:var(--river);font-weight:600;}
/* threats.html's ten rows, in two columns: the threat's name and the threat
   itself on the left, the machine's answer on the right -- the answer is the
   long cell, so it takes the width, and a row is as short as its answer.
   The evidence and what stays open sit under the answer at the SAME size,
   told apart by colour and never by shrinking -- the open part in laterite,
   which on this site marks what is not held. */
.grounds.threats .ground-row{grid-template-columns:1fr 1.9fr;grid-template-rows:auto 1fr;row-gap:8px;}
.grounds.threats .ground-row .p{grid-column:1;grid-row:1;}
.grounds.threats .ground-row .prob{grid-column:1;grid-row:2;}
.grounds.threats .ground-row .fix{grid-column:2;grid-row:1 / span 2;}
@media(max-width:880px){
  .grounds.threats .ground-row{grid-template-columns:1fr;grid-template-rows:none;}
  .grounds.threats .ground-row .p,.grounds.threats .ground-row .prob,
  .grounds.threats .ground-row .fix{grid-column:1;grid-row:auto;}
}
.ground-row .fix .seen,.ground-row .fix .open{display:block;margin-top:9px;color:var(--muted);}
.ground-row .fix .seen b{color:var(--ink);font-weight:600;}
.ground-row .fix .open b{color:var(--laterite);font-weight:500;}

.diagram-img{display:block;width:100%;height:auto;border-radius:14px;border:1px solid var(--line-strong);}
.figure{margin:0 0 clamp(28px,4vw,44px);}
/* A figure that opens a section needs no space above it. One that FOLLOWS
   something does -- without this the promises table sat on the diagram. */
* + .figure{margin-top:clamp(30px,4.2vw,48px);}
/* An image FITS. It never scrolls sideways and never widens the page --
   at any width, on any page. A reader who has to drag a picture to read
   it is a reader who does not read it. */
img{max-width:100%;}
/* A diagram drawn for 952px reads at 7.8px on a phone, and an image may never
   be dragged sideways -- so the phone gets a DIFFERENT drawing of the same
   argument, one column at 640px, which lands at about 16px. Swapped in CSS
   rather than with <picture>, because a <picture> chooses once at load and
   never re-evaluates: a reader who rotates a tablet would keep the wrong one.
   loading="lazy" means the hidden variant is never fetched, so nobody pays
   for the one they do not see. */
/* Both variants are capped at the width they were drawn for, so a diagram's
   text is the same size whichever one the reader gets: labels 17px and
   titles 21px, against 18px of prose. Uncapped, a picture's text grows with
   its column while the prose beside it does not -- the wide drawing reached
   22px at desktop and the narrow one 26px in a half-width window. A diagram
   is a figure at its natural size, not a thing that stretches. */
.wide-only{max-width:730px;}
.narrow-only{display:none;}
@media(max-width:700px){
  .wide-only{display:none;}
  /* Capped at the width it was DRAWN for, and centred when the column is
     wider. A picture's text scales with its column while the prose around
     it does not, so an uncapped 640px drawing reaches 26px beside 18px body
     text and shouts. 340px is a phone's own column, which is what the narrow
     variant was laid out against: its labels land at 17px and its titles at
     21px, just under and just over the 18px they sit next to. */
  .narrow-only{display:block;max-width:340px;}
}

.steps{display:flex;flex-direction:column;gap:2px;counter-reset:s;border:1px solid var(--line);border-radius:12px;overflow:hidden;background:var(--line);}
.step{background:var(--surface);padding:16px 20px 16px 58px;position:relative;}
.step::before{counter-increment:s;content:counter(s);position:absolute;left:20px;top:16px;font-family:var(--mono);font-size:14.5px;color:var(--river);border:1px solid var(--line-strong);width:24px;height:24px;border-radius:50%;display:grid;place-items:center;}
.step b{font-family:var(--mono);font-size:18px;color:var(--ink);font-weight:500;}
.step p{font-size:18px;color:var(--muted);margin-top:3px;line-height:1.5;}
.step code{font-size:14.5px;color:var(--laterite);}

.pull{border-left:3px solid var(--river);padding:6px 0 6px 22px;font-family:var(--serif);font-size:18px;line-height:1.34;font-weight:400;color:var(--ink);}
.pull b{font-weight:500;font-style:italic;color:var(--river);}

.honest{display:flex;flex-direction:column;gap:13px;padding:0;margin:0;}
.honest li{list-style:none;padding-left:26px;position:relative;font-size:18px;line-height:1.55;color:var(--muted);}
.honest li::before{content:"—";position:absolute;left:0;color:var(--laterite);font-family:var(--mono);}
.honest li b{color:var(--ink);font-weight:600;}
/* The same honest list in two columns where the page is wide (security.html):
   the same items at the same size, in half the height. */
.honest.two{display:grid;grid-template-columns:1fr 1fr;gap:13px clamp(24px,3vw,40px);}
@media(max-width:760px){.honest.two{grid-template-columns:1fr;}}

.foot{border-top:1px solid var(--line);padding:clamp(30px,4vw,44px) 0;margin-top:clamp(20px,4vw,40px);}
.foot:has(.bridge-band){border-top:0;padding-top:0;margin-top:0;}
/* The footer is set smaller than the page, on the author's word
   (2026-09-28): it is a signature, not something to read, and the credit
   lines beside it were already 14px -- so the whole footer is one size.
   Small, so never also light (StzZui): the ink, not the muted grey. */
.foot p{font-size:14px;color:var(--ink);line-height:1.5;}

p code{color:var(--laterite);}

.hilite{background:var(--river-wash);border:1px solid var(--river);border-radius:12px;padding:clamp(20px,2.8vw,30px);}
.hilite .eyebrow{color:var(--river);margin-bottom:10px;}
.hilite p{font-size:18px;line-height:1.5;color:var(--ink);}
.hilite p b{color:var(--river);font-weight:600;}
.hilite p code{color:var(--river);}
/* Placing the site against what the reader already runs. Deliberately NOT
   .versus or .ground-row: those style one side as the problem and the other
   as the fix, and nothing in this section is a problem. Name and examples
   are told apart by font and colour at the same size, as everywhere else. */
/* The vocabulary panel. Term in mono, because it is the machine's word;
   definition in sans, because it is ours. Same size, as everywhere. */
.words{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:12px;overflow:hidden;}
@media(max-width:760px){.words{grid-template-columns:1fr;}}
.words div{background:var(--surface);padding:15px 19px;}
.words b{display:block;font-family:var(--mono);font-size:18px;color:var(--river);
  font-weight:500;margin-bottom:3px;}
.words span{font-size:18px;color:var(--muted);line-height:1.5;}
.placing{display:flex;flex-direction:column;gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:12px;overflow:hidden;}
.placing-row{background:var(--surface);display:grid;grid-template-columns:.92fr 1.4fr;
  gap:clamp(14px,2.2vw,28px);padding:17px 20px;align-items:start;}
@media(max-width:880px){.placing-row{grid-template-columns:1fr;gap:7px;}}
.placing .nm{font-size:18px;color:var(--ink);font-weight:600;line-height:1.4;}
.placing .eg{display:block;font-family:var(--mono);font-size:18px;color:var(--muted);
  line-height:1.5;margin-top:2px;}
.placing .df{font-size:18px;color:var(--muted);line-height:1.55;}
.placing .df b{color:var(--river);font-weight:600;}
.fam{display:flex;flex-direction:column;gap:1px;background:var(--line);border:1px solid var(--line);border-radius:12px;overflow:hidden;}
.fam-row{background:var(--surface);display:grid;grid-template-columns:132px 1fr auto;gap:18px;padding:15px 20px;align-items:baseline;}
@media(max-width:720px){.fam-row{grid-template-columns:1fr;gap:6px;}}
.fam .nm{font-family:var(--mono);font-size:15px;color:var(--river);font-weight:500;}
.fam .rl{font-size:18px;color:var(--muted);line-height:1.5;}
.fam .rl b{color:var(--ink);font-weight:600;}
.langs{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:2px;}
.langs .lbl{font-family:var(--mono);font-size:13.5px;color:var(--muted);letter-spacing:.04em;}
.langs .lang{font-family:var(--mono);font-size:13.5px;font-weight:500;color:var(--river);border:1px solid var(--river);border-radius:100px;padding:3px 11px;background:var(--river-wash);}
.stage{font-family:var(--mono);font-size:13px;letter-spacing:.06em;text-transform:uppercase;padding:3px 8px;border-radius:100px;white-space:nowrap;height:fit-content;align-self:center;max-width:100%;}
/* A tag that can neither wrap nor shrink pushes the page sideways as soon
   as its words outgrow the screen. Measured at 320px: 291px of chip in a
   305px viewport, and field.html scrolled. Below 640 it wraps instead. */
@media(max-width:640px){.stage{white-space:normal;border-radius:12px;}}
.stage.now{background:var(--kept-wash);color:var(--kept);}
.stage.prog{background:var(--river-wash);color:var(--river);}
/* Not built: an outline and no fill, the mark the diagrams use for absence, in the colour this site
   keeps for what is not held. An outline rather than a border, so the tag is the size of the others. */
.stage.open{background:transparent;color:var(--laterite);box-shadow:inset 0 0 0 1px var(--laterite);}
@media(max-width:720px){.stage{justify-self:start;}}
.osdelta{display:flex;flex-direction:column;gap:8px;margin-top:6px;padding-top:13px;border-top:1px solid var(--line);}
.osdelta p{font-size:18px;line-height:1.5;padding-left:18px;position:relative;}
.osdelta .old{color:var(--muted);}
.osdelta .old::before{content:"×";position:absolute;left:0;color:var(--laterite);font-family:var(--mono);}
.osdelta .old b{color:var(--laterite);font-weight:600;}
.osdelta .new{color:var(--ink);}
.osdelta .new::before{content:"→";position:absolute;left:0;color:var(--river);font-family:var(--mono);}
.osdelta .new b{color:var(--river);font-weight:600;}

/* ---------- brand imagery ---------- */
.foot .foot-in{display:flex;flex-direction:column;align-items:flex-start;gap:14px;}
.footmark{display:block;height:40px;width:auto;flex:none;opacity:.55;}
.foot .foot-in p{max-width:66ch;text-wrap:pretty;}
/* An internal page's footer: the logo, and the project's credit on the
   right of the same row -- under the logo where the screen is too narrow
   for both, at the width where the home page's credits stack too. */
.foot .foot-in.foot-row{flex-direction:row;justify-content:space-between;align-items:center;flex-wrap:wrap;}
.foot .foot-credit{text-align:right;}
@media(max-width:640px){
  .foot .foot-in.foot-row{flex-direction:column;align-items:flex-start;}
  .foot .foot-credit{text-align:left;}
}
.foot .foot-in:has(.credits){flex-direction:row;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:clamp(28px,4vw,56px);}
.foot-id{display:flex;flex-direction:column;align-items:flex-start;gap:14px;max-width:56ch;}
.credits{display:flex;flex-direction:column;align-items:flex-start;gap:clamp(10px,1.4vw,14px);}
@media(min-width:641px){.foot .foot-in:has(.credits) .credits{margin-top:clamp(14px,1.8vw,26px);}}
.foot:has(.bridge-band){padding-bottom:clamp(40px,5vw,64px);}
.credit-logos{display:flex;flex-direction:row;align-items:center;gap:clamp(14px,2vw,28px);}
.credit-logo{height:clamp(76px,8.5vw,100px);width:auto;flex:none;}
.credits .credit-line{font-size:14px;color:var(--ink);text-align:left;line-height:1.5;}
@media(max-width:640px){
  .foot .foot-in:has(.credits){flex-direction:column;align-items:flex-start;}
  .credits{align-self:flex-start;}
}
.bridge-band{display:block;width:100%;height:auto;aspect-ratio:1675 / 430;object-fit:cover;
  object-position:center 72%;margin:0 0 clamp(28px,4.5vw,56px);}

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