/* =====================================================================
   theme.css · blog.tranie.org · "Swiss x Serif"

   Swiss International Style skeleton (asymmetric grid with a right
   aligned margin rail, huge red index numerals, Inter Tight for
   headlines and labels) over an editorial reading surface (Newsreader
   serif body 19.5px/1.7 on a 680px measure, warm off-white ground).
   No cards, no boxes, no shadows: hierarchy comes from scale, weight,
   and a small budget of structural rules (1px ink under table heads
   and reading-list heads, warm hairlines between rows, a red divider).
   Red is strictly functional: numerals, links, labels that direct.

   FONTS: loaded by each page via Google Fonts link tags, not here.
     Inter Tight 500 600 700 800
     Newsreader ital,opsz,wght 0,400 0,500 0,600 1,400 1,500
     IBM Plex Mono 400 500 600

   THE GRID: every full-width block is one grid row.
     <div class="g">
       <span class="col-m mlabel">Rail label</span>
       <div class="col-c"> ...content... </div>
     </div>
   .g      the row: 236px rail + 60px gap + 680px content column
   .col-m  margin rail cell, right aligned; below 900px it stacks
           above the content and left aligns
   .col-c  content cell, the reading measure
   .col-m may be omitted: .col-c places itself in column 2 anyway.
   Blocks that need their own rail label (sections, figures, tables,
   callouts) are separate sibling .g rows, never nested in each other.

   PAGE SKELETON
     <nav class="sitenav g" aria-label="Site">
       <a class="col-m brand" href="/">blog.tranie.org</a>
       <a class="col-c byline" href="/">All articles</a>   (or a span)
     </nav>
     <footer class="foot g">
       <span class="col-m">copyright</span>
       <span class="col-c">colophon</span>
     </footer>

   LANDING HERO
     <header class="hero g">
       <div class="col-m hero-m">
         <span class="mlabel">Field Notes</span>
         <div class="meta"><span>LABEL: <b>value</b></span>...</div>
       </div>
       <div class="col-c">
         <h1 class="hero-title">Engineering<br>Notes, <em>Mostly</em></h1>
         <p class="hero-sub">...</p>
       </div>
     </header>
   The <em> inside a headline renders as the serif italic splice.

   ARTICLE HEADER (replaces the old boxed header)
     <header class="arthead g">
       <div class="col-m arthead-m">
         <span class="mlabel">kicker text</span>
         <div class="meta"><span>SNAPSHOT: <b>22 JULY 2026</b></span>...</div>
       </div>
       <div class="col-c">
         <h1>Title</h1>
         <p class="subtitle">Serif italic standfirst.</p>
       </div>
     </header>

   ARTICLE SECTION (replaces .eyebrow "01 · Orientation" + h2):
   the number becomes a big red rail numeral, the label a small
   letterspaced grotesque under it.
     <section class="sec g" id="...">
       <div class="col-m sec-m">
         <span class="num" aria-hidden="true">01</span>
         <span class="mlabel">Orientation</span>
       </div>
       <div class="col-c">
         <h2>Section title</h2>
         <p class="lede">Opening paragraph.</p>
         <p>Body...</p>
         <h3>Subhead</h3>
       </div>
     </section>
   Text that continues AFTER an interrupting block (figure, callout,
   table) goes in a continuation row with an empty rail:
     <div class="cont g"><div class="col-c"> <p>...</p> </div></div>

   TOC, as a Swiss index, no boxed card:
     <nav class="toc g" aria-label="Table of contents">
       <span class="col-m tlabel">Contents</span>
       <ol class="col-c">
         <li><span class="n">01</span><a href="#...">...</a></li>
       </ol>
     </nav>

   CALLOUT: no box; a rail label plus a typographic shift (medium
   weight serif). The warn variant gets a red dash over its label.
     <aside class="callout g">                 (or class="callout warn g")
       <span class="col-m clabel">How to use this guide</span>
       <div class="col-c"> <p>...</p> <p>...</p> </div>
     </aside>

   DECK EMBED: a PDF deck read in place. The viewer breaks the reading
   measure and spans the full grid (976px, near the 960x540 native
   size); intro and actions stay in the text column. Below 900px the
   iframe is hidden, because mobile browsers refuse to scroll an
   embedded PDF, and .deck-fallback takes over.
     <div class="deck g">
       <span class="col-m mlabel">Le deck</span>
       <div class="col-c deck-intro"> <p>...</p> </div>
       <div class="deck-frame"><iframe src="...pdf" title="..."></iframe></div>
       <p class="col-c deck-fallback">Shown on phones only.</p>
       <div class="col-c deck-acts">
         <a class="deck-act" href="...">Open fullscreen &#8599;</a>
         <a class="deck-act" href="..." download>Download &#8595;</a>
       </div>
     </div>

   FIGURE: shares the text column width exactly.
     <figure class="fig g">
       <span class="col-m mlabel">Fig. 1</span>
       <div class="col-c">
         <svg>...</svg>
         <figcaption><b>Fig. 1: name.</b> caption text</figcaption>
       </div>
     </figure>
   Inline SVG diagrams drop their embedded <style> and use the .d-*
   classes defined at the end of this file (boxes, titles, flows).

   DIAGRAMS: rules for the inline SVGs inside .fig.
   Most figures ship two arts, swapped by the stylesheet at 640px:
     <svg class="d-wide" viewBox="0 0 680 H" role="img" aria-label="...">
     <svg class="d-tall" viewBox="0 0 340 H" role="img" aria-label="...">
     <figcaption>...</figcaption>            one caption serves both
   .d-wide  landscape desktop art. Draw on a 680-unit-wide viewBox so
            type renders 1:1 in the 680px column. The .d-* class sizes
            are minimums: titles/items 13u, subs 12.5u, caps 10.5u;
            never inline a font-size below them. Art on a wider
            viewBox (legacy, up to 900) must multiply every font-size
            by width/680 to reach the same rendered size; redrawing
            at 680 is preferred.
   .d-tall  portrait phone art, shown below 640px, capped at 340px so
            it renders 1:1 on a 390px phone. viewBox exactly 340 units
            wide, any height. Re-stack the .d-wide composition
            vertically at the same .d-* type sizes; grow downward,
            never shrink type to fit. Same text content as .d-wide,
            verbatim (re-wrapping one line as tspans is fine). Repeat
            role="img" and the identical aria-label on both svgs; only
            the visible one reaches the accessibility tree. Ids inside
            the two svgs (markers, gradients) must differ: suffix
            -w and -t, e.g. url(#arr-w) / url(#arr-t).
   .d-solo  single-art shortcut for compositions that are already one
            vertical stack: one svg on a 340-unit-wide viewBox, shown
            at every size, capped at 340px. Use it only when nothing
            sits side by side. Horizontal flows, side-by-side panels,
            column grids, and bar charts always ship the pair, with
            the .d-tall re-stacking columns top to bottom.
   No width or height attributes on the svg element; the stylesheet
   sizes it. figcaption and the Fig. rail label are shared, unchanged.

   TABLE
     <div class="tbl g">
       <span class="col-m mlabel">Table 01</span>
       <div class="col-c">
         <h3 class="tbl-title">Optional title</h3>
         <div class="tblwrap"><table>...</table></div>
       </div>
     </div>
   Cell helpers: <span class="mono"> for prices and identifiers,
   <span class="tag">, .tag.core (red), .tag.open (ink): plain
   letterspaced text now, no pills.

   READING LIST and CHECKLIST live inside a .col-c:
     <div class="read">
       <div class="read-h"><span class="wk">Week 1</span><span class="tt">Theme</span></div>
       <ul>
         <li><span class="star">&#9733;</span><a href="...">Title</a>
             <span class="src">· source</span>
             <span class="why">Why it matters.</span></li>
       </ul>
     </div>
     <div class="steps">
       <div class="step"><div><b>Lead phrase.</b> Body text.</div></div>
     </div>

   LANDING POST ENTRY
     <a class="post g" href="/slug/">
       <span class="col-m num" aria-hidden="true">01</span>
       <div class="col-c">
         <div class="post-kicker">Essay · date · read time</div>
         <h2 class="post-title">Title</h2>
         <p class="post-sub">Description.</p>
         <div class="post-foot">
           <div class="post-tags"><span class="tag">Tag</span>...</div>
           <span class="post-more">Read the article <span class="arr">&#8594;</span></span>
         </div>
       </div>
     </a>

   DIVIDER (a labeled red rule between major page parts):
     <div class="divider g" role="separator">
       <span class="div-label">Label</span><span class="div-rule"></span>
     </div>

   Legacy aliases kept so half-migrated markup still reads correctly:
   .kicker and .eyebrow and .tlabel render like .mlabel; .mstack like
   .meta. Prefer the rail patterns above in new markup.
   ===================================================================== */

:root{
  --paper:#FCFBF8;
  --ink:#231E19;
  --soft:#4C463E;
  --quiet:#7A7268;
  --red:#E30613;
  --hairline:#EAE5DB;
  --grot:'Inter Tight','Helvetica Neue',Helvetica,Arial,sans-serif;
  --serif:'Newsreader',Georgia,'Times New Roman',serif;
  --mono:'IBM Plex Mono',ui-monospace,'SF Mono',Menlo,monospace;
}

/* ---------- base ---------- */
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{
  background:var(--paper);
  color:var(--ink);
  font-family:var(--serif);
  font-optical-sizing:auto;
  font-size:19.5px;
  line-height:1.7;
  min-height:100vh;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;height:auto}
::selection{background:var(--red);color:#fff}
:focus-visible{outline:2px solid var(--red);outline-offset:3px}
[id]{scroll-margin-top:28px}

/* ---------- grid ---------- */
.g{
  display:grid;
  grid-template-columns:236px minmax(0,680px);
  column-gap:60px;
  width:min(100% - 88px,976px);
  margin-inline:auto;
  align-items:start;
}
.col-m{grid-column:1;text-align:right}
.col-c{grid-column:2;min-width:0}

/* ---------- shared type roles ---------- */
.mlabel,.tlabel,.kicker,.eyebrow{
  font-family:var(--grot);font-size:11.5px;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;color:var(--quiet);
  line-height:1.9;
}
.num{
  display:block;color:var(--red);font-family:var(--grot);font-weight:800;
  font-size:132px;line-height:.78;letter-spacing:-.05em;
  font-variant-numeric:tabular-nums;
}
.meta,.mstack{
  font-family:var(--grot);font-size:11px;font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;color:var(--quiet);
  line-height:2.15;
}
.meta{display:flex;flex-direction:column}
.meta b,.mstack b{color:var(--ink);font-weight:600}

h1{
  font-family:var(--grot);font-weight:800;
  font-size:clamp(38px,5.5vw,54px);line-height:1.03;letter-spacing:-.03em;
}
h1 em{
  font-family:var(--serif);font-style:italic;font-weight:500;
  font-size:.95em;letter-spacing:-.015em;
}
h2{
  font-family:var(--grot);font-size:30px;font-weight:700;
  letter-spacing:-.02em;line-height:1.12;
}
h3{
  font-family:var(--grot);font-size:20px;font-weight:700;
  letter-spacing:-.015em;line-height:1.3;margin-top:48px;
}
p{margin-top:24px}
.lede{font-size:22.5px;line-height:1.6;margin-top:28px}
b,strong{font-weight:600}
code,.m{font-family:var(--mono);font-size:.82em;letter-spacing:-.01em}
.mono{font-family:var(--mono);font-size:13.5px;letter-spacing:0}

/* ---------- links ---------- */
a{color:inherit}
.col-c a{
  color:var(--red);text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:3px;
}
.col-c a:hover{color:var(--ink)}

/* ---------- sitenav ---------- */
.sitenav{padding-top:40px}
.brand{
  font-family:var(--grot);font-size:15px;font-weight:700;
  letter-spacing:-.01em;text-decoration:none;color:var(--ink);
}
.brand:hover{color:var(--red)}
.byline{
  justify-self:end;font-family:var(--grot);font-size:11.5px;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;color:var(--quiet);
  text-decoration:none;
}
a.byline:hover{color:var(--red)}
.navlinks{display:flex;justify-content:flex-end;align-items:baseline;gap:12px 26px;flex-wrap:wrap}
.navlinks .byline{justify-self:auto}

/* ---------- landing hero ---------- */
.hero{padding:118px 0 110px}
.hero-m{display:flex;flex-direction:column;gap:26px;padding-top:14px}
.hero-title{
  font-size:clamp(46px,8.2vw,108px);line-height:.97;letter-spacing:-.045em;
}
.hero-sub{font-size:20.5px;line-height:1.62;margin-top:38px;max-width:640px;color:var(--soft)}

/* ---------- landing index ---------- */
.index-note{
  font-style:italic;font-size:18.5px;line-height:1.6;
  color:var(--soft);max-width:600px;margin-top:0;
}
.post{text-decoration:none;margin-top:96px}
.post-kicker{
  font-family:var(--grot);font-size:11.5px;font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;color:var(--quiet);
}
.post-title{
  font-size:34px;line-height:1.14;letter-spacing:-.02em;margin-top:14px;
}
.post:hover .post-title{color:var(--red)}
.post:hover .num{color:var(--ink)}
.post-sub{font-size:18.5px;line-height:1.62;color:var(--soft);margin-top:16px;max-width:640px}
.post-foot{
  display:flex;justify-content:space-between;align-items:baseline;
  gap:14px 24px;flex-wrap:wrap;margin-top:24px;
}
.post-tags{display:flex;gap:6px 18px;flex-wrap:wrap}
.tag{
  font-family:var(--grot);font-size:11px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--quiet);
  white-space:nowrap;
}
.tag.core{color:var(--red)}
.tag.open{color:var(--ink)}
.post-more{
  font-family:var(--grot);font-size:11.5px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--red);
  white-space:nowrap;
}
.post:hover .post-more{text-decoration:underline;text-underline-offset:3px}

/* ---------- divider ---------- */
.divider{margin-top:140px;row-gap:14px}
.div-label{
  grid-column:1;text-align:right;font-family:var(--grot);font-size:11.5px;
  font-weight:700;letter-spacing:.24em;text-transform:uppercase;color:var(--red);
}
.div-rule{grid-column:1 / -1;height:1px;background:var(--red)}

/* ---------- article header ---------- */
.arthead{padding:110px 0 16px}
.arthead-m{display:flex;flex-direction:column;gap:26px;padding-top:8px}
.subtitle{
  font-style:italic;font-size:20.5px;line-height:1.6;
  color:var(--soft);margin-top:26px;max-width:620px;
}

/* ---------- toc ---------- */
.toc{margin-top:72px}
.toc ol{list-style:none;columns:2;column-gap:48px}
.toc li{break-inside:avoid;margin-bottom:11px}
.toc .n{
  font-family:var(--grot);font-weight:700;font-size:12.5px;color:var(--red);
  margin-right:12px;font-variant-numeric:tabular-nums;
}
.toc a{
  font-family:var(--grot);font-weight:600;font-size:15.5px;
  letter-spacing:-.01em;color:var(--ink);text-decoration:none;
}
.toc a:hover{color:var(--red)}

/* ---------- sections ---------- */
.sec{margin-top:92px}
.cont{margin-top:36px}
.sec-m .num{font-size:72px;line-height:.85}
.sec-m .mlabel{margin-top:14px;display:block}

/* ---------- callout ---------- */
.callout{margin-top:64px;margin-bottom:56px}
.clabel{
  font-family:var(--grot);font-size:11.5px;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;color:var(--red);
  line-height:1.9;
}
.callout.warn .clabel::before{
  content:"";display:block;height:2px;width:32px;background:var(--red);
  margin-left:auto;margin-bottom:10px;
}
.callout .col-c p{font-size:19px;font-weight:500;line-height:1.65;margin-top:14px}
.callout .col-c p:first-child{margin-top:0}

/* ---------- deck embed ---------- */
.deck{margin-top:64px;margin-bottom:56px}
.deck-frame{
  grid-column:1 / -1;margin-top:40px;
  border:1px solid var(--ink);background:var(--paper);
  aspect-ratio:16 / 9;
}
.deck-frame iframe{display:block;width:100%;height:100%;border:0}
.deck-fallback{display:none}
.deck-acts{display:flex;gap:12px 30px;flex-wrap:wrap;margin-top:22px}
.deck-act{
  font-family:var(--grot);font-size:11.5px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;white-space:nowrap;
}
.col-c a.deck-act{color:var(--red);text-decoration:none}
.col-c a.deck-act:hover{color:var(--ink);text-decoration:underline;text-underline-offset:4px}

/* ---------- figures ---------- */
.fig{margin-top:80px;margin-bottom:56px}
.fig svg,.fig img{width:100%;height:auto;display:block}
figcaption{font-size:15.5px;line-height:1.6;color:var(--soft);margin-top:18px}
figcaption b{color:var(--ink);font-weight:600}

/* ---------- tables ---------- */
.tbl{margin-top:80px;margin-bottom:56px}
.tbl-title{
  font-family:var(--grot);font-size:22px;font-weight:700;
  letter-spacing:-.015em;margin-top:0;margin-bottom:24px;
}
.tblwrap{overflow-x:auto;margin-top:24px}
.tbl .tblwrap{margin-top:0}
table{border-collapse:collapse;width:100%;min-width:620px}
th{
  font-family:var(--grot);font-size:10.5px;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;color:var(--quiet);
  text-align:left;padding:0 20px 12px 0;border-bottom:1px solid var(--ink);
}
td{
  font-size:16px;line-height:1.55;vertical-align:top;
  padding:14px 20px 14px 0;border-bottom:1px solid var(--hairline);
}
tr:last-child td{border-bottom:none}
th:last-child,td:last-child{padding-right:0}
.tblwrap td a{text-decoration:none}
.tblwrap td a:hover{text-decoration:underline}

/* ---------- reading list ---------- */
.read{margin-top:56px}
.read-h{
  display:flex;align-items:baseline;gap:16px;
  padding-bottom:12px;border-bottom:1px solid var(--ink);
}
.wk{
  font-family:var(--grot);font-size:11.5px;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--red);
  white-space:nowrap;
}
.tt{font-family:var(--grot);font-size:17.5px;font-weight:700;letter-spacing:-.01em}
.read ul{list-style:none}
.read li{
  padding:14px 0;border-bottom:1px solid var(--hairline);
  font-size:16px;line-height:1.55;
}
.read li:last-child{border-bottom:none}
.read li a{
  font-family:var(--grot);font-weight:600;font-size:15.5px;
  letter-spacing:-.01em;color:var(--ink);text-decoration:none;
}
.read li a:hover{color:var(--red)}
.src{font-family:var(--mono);font-size:12px;color:var(--quiet)}
.why{display:block;font-style:italic;font-size:15.5px;color:var(--soft);margin-top:4px}
.star{color:var(--red);font-size:13px;margin-right:6px}

/* ---------- checklist ---------- */
.steps{counter-reset:step;margin-top:36px}
.step{display:flex;gap:24px;padding:18px 0;border-bottom:1px solid var(--hairline)}
.step:last-child{border-bottom:none}
.step::before{
  counter-increment:step;
  content:counter(step,decimal-leading-zero);
  font-family:var(--grot);font-weight:800;font-size:17px;color:var(--red);
  line-height:1.5;min-width:34px;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;
}
.step div{font-size:17px;line-height:1.6}
.step b{font-family:var(--grot);font-weight:600;letter-spacing:-.01em}

/* ---------- footer ---------- */
.foot{
  margin-top:150px;padding-bottom:120px;
  font-family:var(--grot);font-size:11px;font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;color:var(--quiet);
  line-height:2.1;
}
.foot a{color:inherit;text-decoration:none}
.foot a:hover{color:var(--red)}

/* ---------- diagram classes for inline SVG figures ---------- */
.d-box{fill:none;stroke:var(--ink);stroke-width:1}
.d-boxfill{fill:var(--ink)}
.d-title{font-family:var(--grot);font-weight:700;font-size:13px;letter-spacing:.08em;fill:var(--ink)}
.d-title-inv{font-family:var(--grot);font-weight:700;font-size:13px;letter-spacing:.08em;fill:var(--paper)}
.d-sub{font-family:var(--serif);font-style:italic;font-size:12.5px;fill:var(--quiet)}
.d-sub-inv{font-family:var(--serif);font-style:italic;font-size:12.5px;fill:#BDB6AE}
.d-item{font-family:var(--serif);font-size:13px;fill:var(--soft)}
.d-cap{font-family:var(--grot);font-weight:600;font-size:10.5px;letter-spacing:.14em;fill:var(--red)}
.d-flow{stroke:var(--red);stroke-width:1.4;fill:none}
/* responsive diagram variants: .d-wide desktop art, .d-tall phone art
   (swapped at 640px), .d-solo single narrow art shown at every size */
.fig .d-tall{display:none}
.fig .d-tall,.fig .d-solo{max-width:340px}
@media (max-width:640px){
  .fig .d-wide{display:none}
  .fig .d-tall{display:block}
}

/* ---------- mobile: rail collapses above content ---------- */
@media (max-width:900px){
  body{font-size:17.5px}
  .g{grid-template-columns:minmax(0,1fr);width:min(100% - 44px,680px)}
  .col-m{grid-column:1;text-align:left;margin-bottom:18px}
  .col-c{grid-column:1}
  .sitenav{display:flex;justify-content:space-between;align-items:baseline;padding-top:28px}
  .sitenav .col-m{margin-bottom:0}
  .byline{justify-self:start}
  .hero{padding:70px 0 70px}
  .hero-m{gap:14px;padding-top:0}
  .hero-sub{margin-top:26px;font-size:19px}
  .num{font-size:64px;line-height:.9}
  .sec-m .num{font-size:48px}
  .sec-m .mlabel{margin-top:8px}
  .sec{margin-top:64px}
  .post{margin-top:64px}
  .post-title{font-size:26px}
  .toc ol{columns:1}
  .toc{margin-top:52px}
  .divider{margin-top:96px}
  .div-label{text-align:left}
  .arthead{padding:76px 0 8px}
  .arthead-m{gap:14px}
  .lede{font-size:20px}
  .fig,.tbl{margin-top:56px;margin-bottom:44px}
  .deck{margin-top:48px;margin-bottom:44px}
  .deck-frame{display:none}
  .deck-fallback{display:block;font-style:italic;color:var(--soft);font-size:17px}
  .navlinks{justify-content:flex-start}
  .callout{margin-top:48px;margin-bottom:44px}
  .callout.warn .clabel::before{margin-left:0}
  .foot{margin-top:100px;padding-bottom:80px}
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
}
