/* soldermask — the shared surface: the bar, the type, the footer, the thread
   pages' masthead and figures, and the build page's deck. The index has its
   own sheet, home.css, since 15 Sep 2026.

   The mono is Libertad Mono (ATK Studio, Radinal Riki, 2022) in its Medium,
   the weight Tron: Ares set its screens in, since 16 Sep 2026: one file for
   every weight the sheets ask, declared 100-900 so a 600 label is the same
   Medium and not a synthetic bold. Libertad is unicase -- every lowercase
   glyph is the capital -- so whatever is set in it reads in capitals, which
   is the look of a legend and is why there are two more tokens. JetBrains
   Mono stays under it for the glyphs it lacks (µ, ², ≈, the Greek), filled
   in per glyph, and it is the whole face of --mono-code, for a command or a
   path whose case is the text, and of --mono-draw: Libertad has no
   box-drawing or block glyphs, and a wordmark whose spaces are one face and
   whose blocks are another walks its columns. The file is not open (the
   sheet it came with says personal use), so it is not in the credits'
   licence column until it is. */
  @font-face{
    font-family:"Libertad Mono";
    font-style:normal;
    font-weight:100 900;
    font-display:swap;
    src:local("Libertad Mono Medium"),local("LibertadMono-Medium"),
        url(fonts/libertad-mono-500.woff2) format("woff2");
  }

  :root{
    --bg:#0b0c0f;
    --ink:#f4f3ef;
    --dim:#8b93a1;
    --dimmer:#565d68;
    --brand:#ff8a1f;
    --tron-red:#ff3a1f;   /* Rinzler's: the notice's second slide */
    --rule:#1d2027;
    --wide:1160px;
    --bar:54px;          /* the sticky bar's height; the hero fills what is left */
    --mono:"Libertad Mono","JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
    --mono-code:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
    --mono-draw:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
    --sans:"Manrope",ui-sans-serif,system-ui,-apple-system,sans-serif;
  }
  *{box-sizing:border-box}
  html,body{margin:0;padding:0}
  body{
    background:var(--bg);
    color:var(--ink);
    font-family:var(--sans);
    -webkit-font-smoothing:antialiased;
    min-height:100svh;
    display:flex;
    flex-direction:column;
  }

  /* the bar, persistent on every page: mark left, the three threads and the
     lab's own sections right. Sticky, and it grows a rule once you leave
     the top of the page. */
  header{
    position:sticky;top:0;z-index:60;
    flex:none;
    display:flex;align-items:center;justify-content:space-between;gap:20px;
    height:var(--bar);padding:0 26px;
    background:rgb(11 12 15 / .82);
    -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
    border-bottom:1px solid transparent;
    transition:border-color .18s linear;
  }
  header.scrolled{border-bottom-color:var(--rule)}
  header svg{width:15px;height:15px;flex:none;color:var(--brand)}
  /* the wordmark is the app's: three rows of box-drawing text at 6px, the
     same lettering as the README banner, crisp at any pixel ratio and no
     request. Under 760px the mark stands alone, as it does in the app. */
  header .mark .bword{
    font-family:var(--mono-draw);font-size:6px;line-height:1;margin:0;
    white-space:pre;font-weight:400;letter-spacing:0;color:var(--dim);
    -webkit-font-smoothing:antialiased;
  }
  header a.mark:hover .bword{color:var(--ink)}
  /* the labels are set in ink at 12.5px since 16 Sep 2026: they were --dimmer
     at 10.5px, 2.9:1 against the page and read as barely there. Hover is the
     one place the brand colour touches text. */
  nav.bar{
    display:flex;align-items:center;gap:26px;
    font-family:var(--mono);font-size:12.5px;font-weight:500;
    letter-spacing:.14em;text-transform:uppercase;color:var(--ink);
  }
  nav.bar a{position:relative;padding:5px 0;white-space:nowrap}
  nav.bar a:hover{color:var(--brand)}
  nav.bar a[aria-current]{color:var(--ink)}
  nav.bar a[aria-current]::after{
    content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
    background:var(--brand);
  }
  nav.bar .rule{width:1px;height:10px;background:var(--rule);flex:none}

  /* the notice: one line above the bar for what is next. Not sticky -- it
     scrolls away and the bar takes the top. A page that carries one sets
     has-notice on body so the hero can give up its height. */
  body.has-notice{--notice:36px}
  .notice{
    flex:none;
    display:flex;align-items:center;justify-content:center;gap:12px;
    min-height:var(--notice);padding:7px 26px;
    background:var(--brand);color:var(--bg);
    font-family:var(--mono);font-size:12.5px;font-weight:500;
    letter-spacing:.14em;text-transform:uppercase;line-height:1.4;text-align:center;
  }
  .notice p{margin:0}
  .notice .stamp{
    font-size:10px;padding:3px 7px 2px;flex:none;
    background:var(--bg);color:var(--brand);
  }
  /* the notice rotates (index.html): the alpha, then what is in development
     in Rinzler's red, the change between them a derez (Tron.swap). The strip
     carries the slide's class and cuts colour at the switch. Readers get the
     one still sentence and not the animated copy. */
  .notice .said{
    position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);
    clip-path:inset(50%);white-space:nowrap;
  }
  .notice.rinzler{background:var(--tron-red)}
  .notice.rinzler .stamp{color:var(--tron-red)}
  /* a text resolving here keeps the strip's own colours, not the brand's:
     brand on brand would be invisible */
  .notice .materialising{color:var(--bg) !important}
  .notice .stamp.materialising{color:var(--brand) !important}
  .notice.rinzler .stamp.materialising{color:var(--tron-red) !important}
  .notice p,.notice .stamp{transition:opacity .26s linear}

  main{
    flex:1;
    display:flex;
    align-items:center;
    justify-content:center;
    padding:24px 26px 60px;
  }
  .wrap{
    max-width:640px;
    width:100%;
  }

  .banner-wrap{
    margin:0 0 30px;
    overflow-x:auto;
  }
  .banner-wrap::-webkit-scrollbar{display:none}
  .banner{
    margin:0;
    font-family:var(--mono-draw);
    color:var(--brand);
    line-height:1.15;
    white-space:pre;
    font-size:8px;
    letter-spacing:0;
  }

  .tag{
    font-family:var(--mono);
    font-size:13px;
    color:var(--dim);
    margin:0 0 28px;
    letter-spacing:.01em;
  }

  p.lede{
    font-size:19px;
    line-height:1.55;
    color:var(--ink);
    margin:0 0 20px;
    font-weight:400;
  }
  p.sub{
    font-size:15px;
    line-height:1.65;
    color:var(--dim);
    margin:0 0 20px;
  }
  strong{color:var(--ink);font-weight:600}
  em{font-style:italic}

  section{
    margin:38px 0 0;
    padding:30px 0 0;
    border-top:1px solid var(--rule);
  }
  .sec{
    font-family:var(--mono);
    font-size:11px;
    font-weight:500;
    letter-spacing:.14em;
    text-transform:uppercase;
    color:var(--dim);
    margin:0 0 22px;
  }
  .sec::before{content:"▚ ";color:var(--brand);letter-spacing:0}
  section p{
    font-size:15px;
    line-height:1.65;
    color:var(--dim);
    margin:0 0 14px;
  }
  section p:last-child{margin-bottom:0}

  .thread{margin:0 0 34px}
  .thread:last-child{margin-bottom:0}
  .thread h3{
    font-family:var(--mono);
    font-size:15px;
    font-weight:600;
    color:var(--brand);
    letter-spacing:.01em;
    margin:0 0 10px;
  }
  .thread h3 span{
    color:var(--dim);
    font-weight:400;
    font-size:13px;
  }
  .thread h3 span::before{content:" — "}
  .thread p.next b{
    font-family:var(--mono);
    font-weight:500;
    font-size:12.5px;
    color:var(--ink);
    letter-spacing:.02em;
  }

  .principles{counter-reset:principle}
  .principle{margin:0 0 24px}
  .principle:last-child{margin-bottom:0}
  .principle h3{
    counter-increment:principle;
    font-family:var(--mono);
    font-size:14px;
    font-weight:600;
    color:var(--ink);
    letter-spacing:.005em;
    margin:0 0 8px;
  }
  .principle h3::before{
    content:"0" counter(principle) " — ";
    color:var(--brand);
    font-weight:500;
  }

  footer{
    flex:none;
    border-top:1px solid var(--rule);
    padding:54px 26px 30px;
    font-family:var(--mono);
    font-size:11.5px;
    color:var(--dimmer);
    letter-spacing:.02em;
  }
  .foot{
    max-width:var(--wide);margin:0 auto;
    display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:36px 26px;
  }
  .foot h4{
    font-family:var(--mono);font-size:10.5px;font-weight:500;
    letter-spacing:.15em;text-transform:uppercase;color:var(--dim);
    margin:0 0 14px;
  }
  .foot ul{list-style:none;margin:0;padding:0;display:grid;gap:10px}
  .foot li{
    font-family:var(--sans);font-size:13.5px;line-height:1.4;
    color:var(--dim);letter-spacing:0;
  }
  .foot li em{font-style:normal;color:var(--dimmer)}
  .foot-mark{display:flex;align-items:center;gap:9px}
  .foot-mark svg{width:15px;height:15px;color:var(--brand)}
  .foot-mark span{font-size:13px;font-weight:500;color:var(--dim)}
  .foot-brand p{
    font-family:var(--sans);font-size:13.5px;line-height:1.6;
    color:var(--dimmer);letter-spacing:0;margin:14px 0 0;max-width:36ch;
  }
  .foot-legal{
    max-width:var(--wide);margin:42px auto 0;padding-top:18px;
    border-top:1px solid var(--rule);
    display:flex;justify-content:space-between;align-items:center;
    gap:12px;flex-wrap:wrap;
  }

  /* Narrow: the lab's own links go, because the bar cannot hold the mark and
     seven names. They are all in the footer, which is where a phone finds
     them — including the build, which no footer used to list. */
  
  /* A withdrawn claim stays on the page with the withdrawal beside it, which
     is the repository's rule for a number that turned out to be wrong. */
  p.correction{
    border-left:2px solid var(--dimmer);
    padding:2px 0 2px 16px;margin:18px 0;
    color:var(--dim);
  }
  p.correction strong{color:var(--ink)}

  /* under 1040px the six labels and the button no longer clear the wordmark:
     the mark keeps its glyph and the labels close up a step */
  @media (max-width:1040px){
    header .mark .bword{display:none}
    nav.bar{gap:20px;font-size:11.5px;letter-spacing:.12em}
  }
  @media (max-width:760px){
    nav.bar{gap:18px;font-size:11px;letter-spacing:.12em}
    nav.bar .rule,nav.bar a.lab{display:none}
  }
  @media (max-width:520px){
    :root{--bar:50px}
    header{padding:0 20px;height:var(--bar)}
    .notice{gap:10px;padding:8px 20px;font-size:11px;letter-spacing:.1em}
    main{padding:10px 20px 40px}
    p.lede{font-size:17px}
    nav.bar{gap:14px;font-size:10.5px;letter-spacing:.1em}
    /* a thumb, not a cursor: the link fills the bar it sits in */
    nav.bar a{padding:16px 0}
    footer{padding:40px 20px 22px;font-size:10.5px}
    .foot{grid-template-columns:1fr 1fr;gap:28px 20px}
    .foot-brand{grid-column:1/-1}
  }
  /* narrower than any shipping phone: the mark keeps its glyph, the nav keeps
     the threads. 320px still fits both, with 20px between them */


/* ---- links ------------------------------------------------------------- */
a{color:inherit;text-decoration:none}
a:focus-visible,summary:focus-visible{outline:2px solid var(--brand);
  outline-offset:3px;border-radius:2px}

header a.mark{display:flex;align-items:center;gap:9px}


/* ---- a thread page's masthead ------------------------------------------ */
body.thread-page main{align-items:flex-start;padding-top:44px}

h1{
  font-family:var(--mono);
  font-size:clamp(30px,8vw,40px);
  font-weight:600;
  line-height:1;
  letter-spacing:-.015em;
  color:var(--brand);
  margin:0 0 10px;
}
p.dek{
  font-family:var(--mono);
  font-size:13px;
  color:var(--dim);
  letter-spacing:.01em;
  margin:0 0 26px;
}

/* ---- the point-cloud hero ---------------------------------------------- */
.cloud{margin:0 0 11px}
.cloud canvas{display:block;width:100%;height:380px;touch-action:pan-y}
@media (max-width:520px){.cloud canvas{height:300px}}
.cloud-cap{
  display:flex;justify-content:space-between;align-items:baseline;gap:16px;
  font-family:var(--mono);font-size:11px;letter-spacing:.02em;
  color:var(--dimmer);margin:0 0 30px;
  border-top:1px solid var(--rule);padding-top:9px;
}
.cloud-cap output{color:var(--dim);font-variant-numeric:tabular-nums;
  white-space:nowrap;text-align:right}
.cloud-cap output b{color:var(--ink);font-weight:500}
@media (max-width:560px){
  .cloud-cap{flex-direction:column;gap:5px}
  /* stacked, the readout has the full column and no longer has to fit on one
     line: nowrap here pushed "wirelength 2.57x" off a 320px screen */
  .cloud-cap output{text-align:left;white-space:normal}
}
@media (max-width:430px){.cloud-cap{font-size:10px}}

/* ---- measured rows ------------------------------------------------------ */
.figures{margin:4px 0 0;border-top:1px solid var(--rule)}
.figures div{
  display:flex;gap:18px;align-items:baseline;
  padding:9px 0;border-bottom:1px solid var(--rule);
}
.figures b{
  font-family:var(--mono);font-size:13px;font-weight:500;color:var(--ink);
  font-variant-numeric:tabular-nums;flex:none;width:104px;text-align:right;
  white-space:nowrap;
}
.figures span{font-size:13.5px;line-height:1.5;color:var(--dim)}
.figures em{font-style:normal;color:var(--dimmer)}
@media (max-width:520px){
  .figures div{flex-direction:column;gap:3px}
  .figures b{width:auto;text-align:left}
}
p.note{font-size:12.5px;line-height:1.6;color:var(--dimmer);margin:12px 0 0}
p.note a,section p a{color:var(--dim);border-bottom:1px solid var(--rule)}
p.note a:hover,section p a:hover{color:var(--ink);border-bottom-color:var(--dim)}

/* ---- footer links ------------------------------------------------------- */
.thread h3 a{border-bottom:1px solid var(--rule)}
.thread h3 a:hover{border-bottom-color:currentColor}
footer a:hover{color:var(--dim)}

/* =========================================================================
   the home page. Where a thread page is one 640px column of reading, the
   home page is a stack of full-bleed bands: a media hero, a statement, the
   pipeline as an index, the three threads as an index, the numbers, the
   retro, and how we work. Each band carries its own rule and its own
   gutter label; nothing here reaches the thread pages.
   ========================================================================= */
/* the small tracked label above a masthead: the index's hero and the build
   page's deck both set one. A stamp in the notice strip's shape -- ink on
   ink, the type cut dark into a light box -- since 18 Sep; it was a tick
   and a dim line at 10.5px before (12px is that up 15%). */
.kicker{
  font-family:var(--mono);font-size:12px;font-weight:500;
  letter-spacing:.18em;text-transform:uppercase;line-height:1.4;
  color:var(--bg);background:var(--ink);
  display:block;width:fit-content;padding:4px 9px 3px;
  margin:0 0 26px;
}
/* the bar is sticky, so an anchor must not land under it */
section[id]{scroll-margin-top:calc(var(--bar) + 12px)}


/* =========================================================================
   the build page: a deck beside a stage, 30 / 70, one screen high. The deck
   carries what the canvas used to draw for itself -- the act, its legend,
   the readout, the ladder -- as real text, so it can be read and clicked and
   put on a projector. The canvas is bare and fills its cell.
   ========================================================================= */
body.present main{
  display:grid;grid-template-columns:minmax(300px,3fr) 7fr;
  /* one row, allowed to be smaller than its content: otherwise the deck's
     text sizes the row and the page grows past the screen */
  grid-template-rows:minmax(0,1fr);
  /* main is a flex item of body, and a flex item will not shrink below its
     content unless told; flex:none lets the height rule govern */
  flex:none;min-height:0;
  height:calc(100svh - var(--bar));padding:0;align-items:stretch;
}
body.present .deck{
  display:flex;flex-direction:column;min-width:0;min-height:0;overflow:auto;
  padding:30px 30px 22px;border-right:1px solid var(--rule);
  scrollbar-width:thin;scrollbar-color:var(--rule) transparent;
}
body.present .deck-head{margin:0 0 26px}
body.present .kicker{margin:0 0 14px}
body.present h1{
  font-family:var(--mono);font-size:clamp(28px,2.6vw,40px);font-weight:600;
  line-height:1;letter-spacing:-.02em;color:var(--brand);margin:0 0 14px;
}
body.present .dek{font-size:13.5px;line-height:1.55;color:var(--dim);margin:0;max-width:44ch}

/* the act in progress */
body.present .now{padding:22px 0 20px;border-top:1px solid var(--rule)}
body.present .now .entry-id{
  font-family:var(--mono);font-size:10.5px;font-weight:500;
  letter-spacing:.16em;color:var(--dimmer);margin:0 0 10px;display:flex;gap:14px;align-items:baseline;
}
body.present .now .who{color:var(--ink);letter-spacing:.06em;text-transform:none;font-weight:500}
body.present .now h2{
  font-family:var(--mono);font-size:clamp(22px,2.2vw,30px);font-weight:600;
  line-height:1;letter-spacing:-.02em;color:var(--brand);margin:0 0 10px;
}
body.present .now .say{font-size:13.5px;line-height:1.5;color:var(--dim);margin:0 0 16px;max-width:40ch}
body.present .legend{list-style:none;margin:0 0 16px;padding:0;display:flex;flex-direction:column;gap:7px}
body.present .legend li{
  display:flex;align-items:center;gap:10px;
  font-family:var(--mono);font-size:11px;line-height:1.4;color:var(--dim);
}
body.present .legend i{width:8px;height:8px;flex:none;display:block}
body.present .readout{
  display:block;font-family:var(--mono);font-size:11.5px;line-height:1.55;
  color:var(--dim);font-variant-numeric:tabular-nums;
  padding:12px 0 0;border-top:1px dashed var(--rule);
}
body.present .readout b{color:var(--ink);font-weight:500}
body.present .files{
  list-style:none;margin:12px 0 0;padding:0;
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:3px 10px;
  font-family:var(--mono);font-size:10.5px;color:var(--brand);
}
body.present .files .aux{color:var(--dimmer)}
body.present .files[hidden]{display:none}

/* the ladder, as a list */
body.present .acts{list-style:none;margin:0;padding:12px 0 0;border-top:1px solid var(--rule);flex:1}
body.present .acts li{position:relative}
body.present .acts button{
  all:unset;cursor:pointer;display:grid;grid-template-columns:26px minmax(0,1fr) auto;
  align-items:baseline;gap:10px;width:100%;box-sizing:border-box;
  padding:6px 0;font-family:var(--mono);font-size:12px;line-height:1.4;color:var(--dimmer);
  transition:color .12s ease-out;
}
body.present .acts button:hover{color:var(--dim)}
body.present .acts button:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
body.present .acts b{font-weight:500;letter-spacing:.08em;font-size:10.5px}
body.present .acts em{font-style:normal;font-size:10.5px;letter-spacing:.04em;opacity:.8}
body.present .acts .is-done button{color:var(--dim)}
body.present .acts .is-now button{color:var(--ink)}
body.present .acts .is-now b{color:var(--brand)}
/* a rung fills under the live act, driven by --u from the frame */
body.present .acts li::after{
  content:"";position:absolute;left:36px;right:0;bottom:2px;height:1px;
  background:var(--rule);transform-origin:left;
}
body.present .acts .is-now::after{
  background:var(--brand);transform:scaleX(var(--u,0));
}

/* transport */
body.present .transport{
  display:flex;align-items:center;gap:8px;padding:16px 0 0;border-top:1px solid var(--rule);
  font-family:var(--mono);
}
body.present .transport button{
  all:unset;cursor:pointer;box-sizing:border-box;
  padding:7px 12px;border:1px solid var(--rule);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--dim);transition:color .12s,border-color .12s;
}
body.present .transport button:hover{color:var(--ink);border-color:#2a2f3a}
body.present .transport button:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
body.present .transport #play{min-width:64px;text-align:center;color:var(--brand);border-color:#3a2a14}
body.present .transport .hint{margin-left:auto;font-size:10px;letter-spacing:.06em;color:var(--dimmer);text-align:right}

/* the stage */
body.present .stage{margin:0;min-width:0;min-height:0;position:relative;background:var(--bg)}
body.present .stage canvas{display:block;width:100%;height:100%;border:0;min-height:0;cursor:grab;touch-action:none}
body.present .stage canvas:active{cursor:grabbing}
body.present .stage-bar{
  position:absolute;left:0;bottom:0;height:2px;width:0;background:var(--brand);
  pointer-events:none;transition:none;
}
body.present.is-paused .stage-bar{opacity:.45}

@media (max-width:1100px){
  body.present main{grid-template-columns:minmax(280px,34fr) 66fr}
  body.present .deck{padding:24px 22px 18px}
}
@media (max-width:900px){
  body.present main{
    grid-template-columns:1fr;grid-template-rows:58svh auto;
    height:auto;min-height:calc(100svh - var(--bar));
  }
  body.present .stage{order:-1;border-bottom:1px solid var(--rule)}
  body.present .deck{border-right:0;overflow:visible}
  body.present .acts button{grid-template-columns:26px minmax(0,1fr)}
  body.present .acts em{display:none}
  body.present .transport .hint{display:none}
}

/* a short screen: the deck tightens before it has to scroll */
@media (max-height:940px) and (min-width:901px){
  body.present .deck{padding:22px 26px 16px}
  body.present .deck-head{margin-bottom:16px}
  body.present .dek{display:none}
  body.present h1{font-size:clamp(24px,2.2vw,32px);margin-bottom:0}
  body.present .now{padding:16px 0 14px}
  body.present .now .say{margin-bottom:10px}
  body.present .legend{gap:4px;margin-bottom:10px}
  body.present .acts button{padding:4px 0;font-size:11.5px}
  body.present .transport{padding-top:12px}
}
