/* Shared stylesheet for the /blog pages.
 *
 * index.html stays deliberately self-contained (inline CSS, single file). The blog
 * is many pages, so it gets one shared sheet instead — same tokens, same voice.
 * The :root block below is generated: run `node scripts/sync-tokens.mjs`, which
 * writes into both index.html and this file between the tokens:start/end markers.
 */

:root{
  /* tokens:start — generated from lesofi-brand/dist/tokens.css · run: node scripts/sync-tokens.mjs */
  --ink:#0F172A;      /* anchor · text · dark surfaces */
  --paper:#FFFFFF;    /* cards / panels */
  --base:#F6F7F9;     /* page background */
  --line:#E6E8ED;     /* hairlines */
  --mute:#5B6472;     /* secondary text (AA) */
  --faint:#6B7280;    /* labels / captions (AA-safe) */
  --teal:#0E8F86;     /* HandInLoop accent — strip/mark/graphic + large text */
  --teal-ink:#0C7A72; /* HandInLoop text on white (AA-safe) */
  --gold:#CA9A2C;     /* gigsdata accent — strip/mark only */
  --gold-ink:#8A6410; /* gigsdata gold text (AA-safe) */
  /* tokens:end */
}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{
  font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  color:var(--ink);background:var(--base);line-height:1.55;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
.mono{font-family:'IBM Plex Mono',ui-monospace,monospace}
.wrap{max-width:1080px;margin:0 auto;padding:0 28px}
a{color:inherit}
::selection{background:rgba(14,143,134,.16)}

.label{
  font-family:'IBM Plex Mono',monospace;font-size:11.5px;
  letter-spacing:.18em;text-transform:uppercase;color:var(--faint);
}

/* ---- top bar (matches index.html) ---- */
header.bar{position:sticky;top:0;z-index:20;background:rgba(246,247,249,.82);
  backdrop-filter:saturate(160%) blur(10px);border-bottom:1px solid var(--line)}
.bar .wrap{display:flex;align-items:center;justify-content:space-between;height:62px}
.brand{display:flex;align-items:center;gap:10px;font-weight:700;letter-spacing:-.02em;
  font-size:17px;text-decoration:none}
.brand .dot{width:9px;height:9px;border-radius:50%;
  background:conic-gradient(from 200deg,var(--teal) 0 50%,var(--gold) 50% 100%)}
nav.top{display:flex;gap:26px}
nav.top a{font-family:'IBM Plex Mono',monospace;font-size:12.5px;color:var(--mute);
  text-decoration:none;letter-spacing:.02em;transition:color .15s}
nav.top a:hover{color:var(--ink)}
nav.top a[aria-current="page"]{color:var(--ink)}
@media(max-width:640px){nav.top a:not(.nav-contact){display:none}}

/* keyboard skip link — off-screen until focused */
.skip{position:absolute;left:8px;top:-56px;z-index:40;background:var(--ink);color:#fff;
  font-family:'IBM Plex Mono',monospace;font-size:13px;padding:10px 16px;border-radius:8px;
  text-decoration:none;transition:top .15s}
.skip:focus{top:8px;outline:2px solid #fff;outline-offset:2px}

a:focus-visible{outline:2px solid var(--teal);outline-offset:3px;border-radius:6px}

/* ---- index listing ---- */
.idx-hero{padding:76px 0 40px}
.idx-hero .label{display:block;margin-bottom:22px}
.idx-hero h1{font-size:clamp(32px,5vw,52px);line-height:1.05;letter-spacing:-.035em;
  font-weight:700;max-width:18ch}
.idx-hero .lede{margin-top:22px;font-size:clamp(16px,2vw,19px);color:var(--mute);
  max-width:60ch;line-height:1.55}

.posts{padding:20px 0 76px}
.posts .blk-head{display:flex;align-items:baseline;justify-content:space-between;
  border-top:1px solid var(--line);padding-top:22px;margin-bottom:8px}
.posts .blk-head .count{font-family:'IBM Plex Mono',monospace;font-size:11.5px;color:var(--faint)}

.post-row{display:block;text-decoration:none;border-bottom:1px solid var(--line);
  padding:28px 0;transition:padding-left .18s ease}
.post-row:hover{padding-left:8px}
.post-row .meta{display:flex;flex-wrap:wrap;gap:14px;align-items:center;margin-bottom:12px}
.post-row .kind{font-family:'IBM Plex Mono',monospace;font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--teal-ink);border:1px solid rgba(14,143,134,.3);
  border-radius:999px;padding:3px 10px}
.post-row .kind.gig{color:var(--gold-ink);border-color:rgba(202,154,44,.42)}
.post-row time{font-family:'IBM Plex Mono',monospace;font-size:11.5px;color:var(--faint);
  letter-spacing:.06em}
.post-row h2{font-size:clamp(21px,2.6vw,27px);font-weight:700;letter-spacing:-.025em;
  line-height:1.2;max-width:30ch}
.post-row:hover h2{color:var(--teal-ink)}
/* A gigsdata piece keeps its own accent on hover — gold-ink, never gold-500,
   which fails AA on white. */
.post-row.gig:hover h2{color:var(--gold-ink)}
.post-row p{margin-top:10px;font-size:15.5px;color:var(--mute);max-width:64ch;line-height:1.6}

/* ---- article ---- */
.doc{padding:56px 0 24px}
.doc .backlink{font-family:'IBM Plex Mono',monospace;font-size:12px;color:var(--faint);
  text-decoration:none;letter-spacing:.04em;display:inline-block;margin-bottom:30px}
.doc .backlink:hover{color:var(--ink)}
.doc h1{font-size:clamp(30px,4.6vw,46px);line-height:1.06;letter-spacing:-.035em;
  font-weight:700;max-width:22ch}
.doc .standfirst{margin-top:22px;font-size:clamp(16px,2vw,19px);color:var(--mute);
  max-width:62ch;line-height:1.6}
.doc .byline{margin-top:28px;padding-top:18px;border-top:1px solid var(--line);
  display:flex;flex-wrap:wrap;gap:18px;align-items:center}
.doc .byline span{font-family:'IBM Plex Mono',monospace;font-size:11.5px;color:var(--faint);
  letter-spacing:.08em;text-transform:uppercase}

/* article body — narrower measure than the shell */
.prose{max-width:none}
.prose > *{max-width:70ch}
.prose h2{font-size:clamp(22px,2.9vw,30px);font-weight:700;letter-spacing:-.025em;
  line-height:1.2;margin:60px 0 6px;padding-top:26px;border-top:1px solid var(--line);
  max-width:34ch;scroll-margin-top:80px}
.prose h3{font-size:clamp(17px,2.1vw,20px);font-weight:600;letter-spacing:-.015em;
  margin:38px 0 4px;max-width:44ch;scroll-margin-top:80px}
.prose h4{font-family:'IBM Plex Mono',monospace;font-size:12px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--faint);font-weight:500;margin:30px 0 4px}
.prose p{margin-top:16px;font-size:16.5px;color:var(--mute);line-height:1.68}
.prose p strong,.prose li strong{color:var(--ink);font-weight:600}
.prose em{font-style:italic}
.prose a{color:var(--teal-ink);text-decoration:underline;
  text-underline-offset:2px;text-decoration-thickness:1px}
.prose a:hover{color:var(--ink)}

.prose ul,.prose ol{margin:16px 0 0 0;padding-left:22px}
.prose li{margin-top:9px;font-size:16.5px;color:var(--mute);line-height:1.62}
.prose li::marker{color:var(--faint)}
.prose ul ul,.prose ol ol,.prose ul ol,.prose ol ul{margin-top:8px}

.prose code{font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:.87em;
  background:#EDEFF3;border:1px solid var(--line);border-radius:5px;padding:1px 5px;
  color:var(--ink);word-break:break-word}
.prose pre{margin:22px 0 0;background:var(--ink);border-radius:12px;padding:20px 22px;
  overflow-x:auto;max-width:100%}
.prose pre code{background:none;border:none;padding:0;color:#E6E8ED;font-size:13.5px;
  line-height:1.7;word-break:normal;white-space:pre}
.prose pre code .c{color:#8C97A8}   /* comment */

/* Scoped to .prose so it outranks `.prose > *{max-width:70ch}` on specificity
   rather than source order — a bare `blockquote` selector loses that contest. */
.prose blockquote{margin:26px 0 0;padding:2px 0 2px 20px;border-left:2px solid var(--teal);
  max-width:66ch}
.prose blockquote p{margin-top:0;color:var(--ink);font-size:17px;line-height:1.6}
.prose blockquote p + p{margin-top:12px}

/* callout — the "we'd push back on this" boxes */
.note{margin:26px 0 0;background:var(--paper);border:1px solid var(--line);
  border-left:3px solid var(--gold);border-radius:0 12px 12px 0;padding:20px 22px;max-width:70ch}
.note .k{font-family:'IBM Plex Mono',monospace;font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--gold-ink);font-weight:500}
.note p{margin-top:8px;font-size:15.5px;line-height:1.62}

/* tables scroll on their own so the page body never does */
.tbl{margin:24px 0 0;overflow-x:auto;border:1px solid var(--line);border-radius:12px;
  background:var(--paper);max-width:100%}
/* `.tbl` and `.prose > *` have equal specificity, so the 70ch measure would win or
   lose on source order alone. State the override explicitly: wide content is meant
   to run full width and scroll inside itself. */
.prose > .tbl{max-width:100%}
table{border-collapse:collapse;width:100%;min-width:560px}
th,td{text-align:left;vertical-align:top;padding:12px 16px;border-bottom:1px solid var(--line);
  font-size:14.5px;line-height:1.55;color:var(--mute)}
th{font-family:'IBM Plex Mono',monospace;font-size:10.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint);font-weight:500;background:#FAFBFC;
  white-space:nowrap}
tr:last-child td{border-bottom:none}
td strong{color:var(--ink);font-weight:600}
td code,th code{font-size:12.5px}

/* ---- figures: stat tiles and charts ---- */
/* Data pieces need two things prose doesn't: a row of headline numbers, and a
   plotted figure. Both run wider than the 70ch measure, so both restate
   max-width explicitly for the same reason `.tbl` does. */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin:28px 0 0}
.prose > .stats{max-width:100%}
.stat{background:var(--paper);border:1px solid var(--line);border-radius:12px;
  border-top:3px solid var(--gold);padding:18px 20px}
.stat .k{display:block;font-family:'IBM Plex Mono',monospace;font-size:10.5px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--faint)}
.stat .v{display:block;margin-top:10px;font-size:clamp(23px,3.2vw,31px);font-weight:600;
  letter-spacing:-.03em;color:var(--ink);font-variant-numeric:tabular-nums;line-height:1.1}
.stat .u{display:block;margin-top:5px;font-size:13.5px;color:var(--mute);line-height:1.4}
@media(max-width:820px){.stats{grid-template-columns:repeat(2,1fr)}}
@media(max-width:430px){.stats{grid-template-columns:1fr}}

.fig{margin:28px 0 0;background:var(--paper);border:1px solid var(--line);
  border-radius:12px;padding:20px 22px}
.prose > .fig{max-width:100%}
.fig .cap{margin:0;font-size:14.5px;color:var(--mute);line-height:1.6;max-width:70ch}
/* The plot scrolls inside its own box below 640px rather than squeezing 24
   columns into a phone — the page body never scrolls sideways. */
.chart{margin-top:16px;overflow-x:auto}
.chart svg{display:block;max-width:100%;height:auto;min-width:640px}
.chart .grid line{stroke:var(--line);stroke-width:1}
.chart .base{stroke:#CDD2DA;stroke-width:1}
.chart text{font-family:'IBM Plex Mono',monospace;font-size:10.5px;fill:var(--faint)}
.chart .dlab text{font-size:11px;font-weight:500;fill:var(--ink)}
/* Identity never rides on colour alone: the legend is always present, the two
   labelled columns carry their values, and the full series is tabled below. */
.legend{display:flex;flex-wrap:wrap;gap:9px 20px;margin-top:16px}
.legend span{display:inline-flex;align-items:center;gap:8px;
  font-family:'IBM Plex Mono',monospace;font-size:11px;letter-spacing:.06em;color:var(--faint)}
.legend i{flex:none;width:11px;height:11px;border-radius:3px}

/* two callouts side by side */
.pair{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:26px 0 0}
.prose > .pair{max-width:100%}
.pair .note{margin:0;max-width:none}
@media(max-width:760px){.pair{grid-template-columns:1fr}}

/* ---- changelog ---- */
.log{margin-top:20px}
.log .row{display:flex;gap:18px;padding:14px 0;border-bottom:1px solid var(--line);
  max-width:70ch;flex-wrap:wrap}
.log .row:last-child{border-bottom:none}
.log time{font-family:'IBM Plex Mono',monospace;font-size:12px;color:var(--faint);
  letter-spacing:.06em;flex:0 0 96px}
.log .what{font-size:15.5px;color:var(--mute);line-height:1.6;flex:1;min-width:220px}

/* ---- close / footer (matches index.html) ---- */
.close{background:var(--ink);color:#fff;border-radius:20px;padding:52px 44px;
  display:flex;align-items:center;justify-content:space-between;gap:28px;flex-wrap:wrap;
  margin-top:76px}
.close h2{font-size:clamp(24px,3.4vw,34px);letter-spacing:-.025em;font-weight:700;
  line-height:1.1;max-width:22ch}
.close a.mail{font-family:'IBM Plex Mono',monospace;font-size:15px;color:#fff;
  text-decoration:none;border:1px solid rgba(255,255,255,.25);border-radius:10px;
  padding:13px 20px;white-space:nowrap;transition:background .15s,border-color .15s}
.close a.mail:hover{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.5)}

footer{padding:34px 0 60px}
footer .wrap{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px}
footer .label{color:var(--faint)}
footer a{color:var(--mute);text-decoration:underline;text-underline-offset:2px;
  text-decoration-thickness:1px}
footer a:hover{color:var(--ink)}

@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .post-row{transition:none}
}
