/* ==========================================================================
   redisunarta.xyz — Direction A (editorial neutral), Inter
   Tokens per Personal Website Checklist §4
   ========================================================================== */

:root {
  --ink:        #1A1A1A;
  --ink-muted:  #5A5A5A;
  --rule:       #E3E3DF;
  --paper:      #FAFAF8;
  --paper-alt:  #F2F2EE;
  --accent:     #0B5FFF;
  --accent-ink: #0847C4;

  /* Okabe–Ito, colourblind-safe — for charts only, never UI */
  --c1: #0072B2; --c2: #E69F00; --c3: #009E73;
  --c4: #CC79A7; --c5: #56B4E9; --c6: #D55E00;

  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  --s1: 4px;  --s2: 8px;  --s3: 16px; --s4: 24px;
  --s5: 32px; --s6: 48px; --s7: 64px; --s8: 96px;

  --measure: 68ch;
}

/* --- reset ---------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body, h1, h2, h3, p, ul, ol, figure, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img { max-width: 100%; display: block; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* --- base ----------------------------------------------------------------- */

body {
  font-family: var(--font);
  font-size: 19px;
  line-height: 1.65;
  font-weight: 400;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  /* numerate audience: keep digits in columns */
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

@media (max-width: 640px) { body { font-size: 17px; } }

h1, h2, h3 { line-height: 1.2; letter-spacing: -0.015em; }
h1 { font-size: 40px; font-weight: 700; }
h2 { font-size: 28px; font-weight: 650; line-height: 1.25; }
h3 { font-size: 21px; font-weight: 600; line-height: 1.35; }

@media (max-width: 640px) {
  h1 { font-size: 32px; }
  h2 { font-size: 24px; }
}

p { max-width: var(--measure); }

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--accent-ink); }
a:focus-visible {
  outline: 2px solid var(--accent-ink);
  outline-offset: 3px;
  border-radius: 2px;
}

strong { font-weight: 600; }
hr { border: 0; border-top: 1px solid var(--rule); margin: var(--s7) 0; }

.small { font-size: 15px; line-height: 1.5; }
.muted { color: var(--ink-muted); }
.nowrap { white-space: nowrap; }

/* skip link */
.skip {
  position: absolute; left: -9999px;
  background: var(--ink); color: var(--paper);
  padding: var(--s2) var(--s3); z-index: 100; border-radius: 0 0 4px 0;
}
.skip:focus { left: 0; top: 0; color: var(--paper); }

/* --- layout --------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
  padding: 0 var(--s4);
}

section { padding: var(--s7) 0; }
section + section { border-top: 1px solid var(--rule); }

@media (max-width: 640px) { section { padding: var(--s6) 0; } }

/* --- header / nav --------------------------------------------------------- */

.site-head {
  border-bottom: 1px solid var(--rule);
  background: var(--paper);
}
.site-head .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s4); padding-top: var(--s4); padding-bottom: var(--s4);
  flex-wrap: wrap;
}
.brand {
  font-weight: 650; font-size: 17px; color: var(--ink);
  text-decoration: none; letter-spacing: -0.01em;
}
.brand:hover { color: var(--ink); }
.nav { display: flex; gap: var(--s4); font-size: 16px; }
.nav a {
  color: var(--ink-muted); text-decoration: none;
  padding: var(--s2) 0; display: inline-block; min-height: 44px;
  display: flex; align-items: center;
}
.nav a:hover, .nav a[aria-current='page'] {
  color: var(--ink); text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: 4px;
}

/* --- page head -------------------------------------------------------------
   One component for the top of every page. Same rhythm everywhere; the only
   variation is whether a portrait sits alongside (--with-portrait).
   -------------------------------------------------------------------------- */

.page-head { padding: var(--s7) 0 var(--s6); }
.page-head h1 { margin-bottom: var(--s4); }
.page-head .lede {
  font-size: 21px; line-height: 1.5; color: var(--ink); margin: 0 0 var(--s3);
}
.page-head .sub { color: var(--ink-muted); margin: 0; }
.page-head .cta-row { margin-top: var(--s5); }
.page-head .note { margin-top: var(--s3); }

.page-head--with-portrait .page-head-grid {
  display: grid; grid-template-columns: 1fr 200px;
  gap: var(--s6); align-items: start;
}
.page-head--home h1 { max-width: 16ch; }

.portrait {
  width: 200px; height: 200px; border-radius: 3px;
  object-fit: cover; border: 1px solid var(--rule);
}

/* Timur logo mark — no frame, it is line art on white */
.logo-mark {
  width: 200px; height: 200px; object-fit: contain;
  mix-blend-mode: multiply;
}

@media (max-width: 700px) {
  .page-head { padding: var(--s6) 0 var(--s5); }
  .page-head--with-portrait .page-head-grid { grid-template-columns: 1fr; gap: var(--s5); }
  .portrait, .logo-mark { width: 132px; height: 132px; order: -1; }
  .page-head--home h1 { max-width: none; }
  .page-head .lede { font-size: 19px; }
}

/* --- buttons -------------------------------------------------------------- */

.cta-row { display: flex; gap: var(--s3); flex-wrap: wrap; }
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: var(--s2) var(--s4);
  border-radius: 3px; font-size: 16px; font-weight: 550;
  text-decoration: none; border: 1px solid transparent;
  transition: background-color .15s ease, border-color .15s ease;
}
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-ink); color: #fff; }
.btn-secondary { border-color: var(--rule); color: var(--ink); background: transparent; }
.btn-secondary:hover { border-color: var(--ink); color: var(--ink); background: var(--paper-alt); }

/* --- proof bar ------------------------------------------------------------ */

.proof {
  background: var(--paper-alt);
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding: var(--s4) 0;
}
.proof ul {
  display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4);
  font-size: 15px; color: var(--ink-muted);
}
.proof li { display: flex; align-items: center; gap: var(--s4); }
.proof li:not(:last-child)::after {
  content: ''; width: 1px; height: 14px; background: var(--rule);
}
@media (max-width: 640px) {
  .proof li:not(:last-child)::after { display: none; }
  .proof ul { flex-direction: column; gap: var(--s1); }
}

/* --- section body rhythm ---------------------------------------------------
   So pages don't need per-element inline margins. Applies to plain sections;
   .prose, .cards, .cv and .posts manage their own spacing.
   -------------------------------------------------------------------------- */

section > h2 + p,
section > .sec-head + p,
section > * + .callout { margin-top: var(--s4); }
section > p + p { margin-top: var(--s3); }
.note { margin-top: var(--s3); }

/* --- section heads -------------------------------------------------------- */

.sec-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s4); margin-bottom: var(--s5); flex-wrap: wrap;
}
.sec-head h2 { margin: 0; }
.sec-head a { font-size: 16px; }
.eyebrow {
  font-size: 13px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-muted); margin-bottom: var(--s2);
}

/* --- work cards ----------------------------------------------------------- */

.cards { display: grid; gap: var(--s3); }
.card {
  display: block; padding: var(--s4);
  border: 1px solid var(--rule); border-radius: 3px;
  background: var(--paper); text-decoration: none; color: var(--ink);
  transition: border-color .15s ease, background-color .15s ease;
}
.card:hover { border-color: var(--ink); background: var(--paper-alt); color: var(--ink); }
.card h3 { margin-bottom: var(--s2); }
.card p { font-size: 16px; color: var(--ink-muted); margin: 0; max-width: none; }
.card .meta {
  font-size: 13px; color: var(--ink-muted); margin-bottom: var(--s2);
  letter-spacing: .04em; text-transform: uppercase; font-weight: 600;
}

/* --- prose / case studies ------------------------------------------------- */

.prose > * + * { margin-top: var(--s4); }
.prose h2 { margin-top: var(--s7); }
.prose h3 { margin-top: var(--s5); }
.prose ul { list-style: disc; padding-left: var(--s4); max-width: var(--measure); }
.prose ol { list-style: decimal; padding-left: var(--s4); max-width: var(--measure); }
.prose li + li { margin-top: var(--s2); }

.case { padding-top: var(--s7); }
.case + .case { border-top: 1px solid var(--rule); }
.case-num {
  font-size: 13px; font-weight: 700; letter-spacing: .1em;
  color: var(--ink-muted); margin-bottom: var(--s2);
}

/* labelled field inside a case study */
.field { margin-top: var(--s4); }
.field-label {
  font-size: 13px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-muted); margin-bottom: var(--s1);
}

.callout {
  border-left: 3px solid var(--rule);
  padding: var(--s2) 0 var(--s2) var(--s4);
  color: var(--ink-muted);
}
.callout p { max-width: none; }

/* stat strip inside a case */
.stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--s3); margin-top: var(--s4);
  border-top: 1px solid var(--rule); padding-top: var(--s4);
}
.stat .n { font-size: 26px; font-weight: 700; line-height: 1.1; letter-spacing: -0.02em; }
.stat .l { font-size: 14px; color: var(--ink-muted); line-height: 1.35; margin-top: var(--s1); }

/* --- writing list --------------------------------------------------------- */

.series { margin-top: var(--s5); }
.series > summary {
  cursor: pointer; font-size: 21px; font-weight: 600;
  padding: var(--s3) 0; border-bottom: 1px solid var(--rule);
  list-style: none; display: flex; align-items: baseline; gap: var(--s3);
  min-height: 44px;
}
.series > summary::-webkit-details-marker { display: none; }
.series > summary::before {
  content: '▸'; color: var(--ink-muted); font-size: 15px;
  transition: transform .15s ease; display: inline-block;
}
.series[open] > summary::before { transform: rotate(90deg); }
.series > summary:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 3px; }
.series .count { font-size: 15px; font-weight: 400; color: var(--ink-muted); margin-left: auto; }

.pieces li { border-bottom: 1px solid var(--rule); }
.pieces a, .pieces .pending {
  display: block; padding: var(--s3) 0; text-decoration: none; color: var(--ink);
}
.pieces a:hover { color: var(--ink); background: var(--paper-alt); }
.pieces .t { font-weight: 550; display: block; }
.pieces .f { font-size: 16px; color: var(--ink-muted); display: block; margin-top: var(--s1); }
.pieces .n { font-size: 13px; color: var(--ink-muted); font-weight: 600; margin-right: var(--s2); }

.tag-pending {
  display: inline-block; font-size: 11px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  color: #8A5A00; background: #FFF3D6; border: 1px solid #E8CE93;
  padding: 1px 6px; border-radius: 2px; margin-left: var(--s2);
  vertical-align: 2px;
}

/* build-time notice — delete before launch */
.todo-banner {
  background: #FFF3D6; border: 1px solid #E8CE93; border-radius: 3px;
  padding: var(--s3) var(--s4); margin-bottom: var(--s5);
  font-size: 16px; color: #6B4700;
}
.todo-banner p { max-width: none; }
.todo-banner strong { color: #4A3100; }

/* --- next-page continuity --------------------------------------------------
   Every page ends pointing somewhere. Turns separate documents into one path.
   -------------------------------------------------------------------------- */

.next-nav {
  display: block; margin-top: var(--s7); padding: var(--s5) 0 var(--s6);
  border-top: 1px solid var(--rule);
  text-decoration: none; color: var(--ink);
}
.next-label {
  display: block; font-size: 13px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-muted); margin-bottom: var(--s2);
}
.next-title {
  display: block; font-size: 28px; font-weight: 650; letter-spacing: -0.015em;
  line-height: 1.25;
}
.next-title::after {
  content: '→'; margin-left: .4em; color: var(--accent);
  display: inline-block; transition: transform .15s ease;
}
.next-nav:hover { color: var(--ink); }
.next-nav:hover .next-title::after { transform: translateX(4px); }
.next-blurb {
  display: block; color: var(--ink-muted); font-size: 16px;
  margin-top: var(--s2); max-width: 52ch;
}
@media (max-width: 640px) { .next-title { font-size: 24px; } }

/* --- footer --------------------------------------------------------------- */

.site-foot {
  border-top: 1px solid var(--rule);
  background: var(--paper-alt);
  padding: var(--s6) 0 var(--s5);
}
.foot-grid {
  display: grid; grid-template-columns: 1fr auto;
  gap: var(--s6); align-items: start;
}
.foot-name { font-weight: 650; margin-bottom: var(--s2); }
.foot-id .small { max-width: 34ch; }
.foot-cols { display: flex; gap: var(--s7); }
.foot-col { display: flex; flex-direction: column; gap: var(--s1); }
.foot-col-h {
  font-size: 13px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-muted); margin-bottom: var(--s2);
}
.foot-col a {
  font-size: 16px; color: var(--ink); text-decoration: none;
  padding: 3px 0; min-height: 28px; display: block;
}
.foot-col a:hover {
  color: var(--accent); text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: 3px;
}
.foot-legal {
  margin-top: var(--s6); padding-top: var(--s4);
  border-top: 1px solid var(--rule);
}
.site-foot .small { color: var(--ink-muted); }

@media (max-width: 640px) {
  .foot-grid { grid-template-columns: 1fr; gap: var(--s5); }
  .foot-cols { gap: var(--s6); }
}

/* --- 404 ------------------------------------------------------------------ */

.center-page { padding: var(--s8) 0; text-align: left; }

/* --- cross-document view transitions ---------------------------------------
   Progressive enhancement. Supporting browsers cross-fade between pages so
   navigation reads as one site rather than four documents; everywhere else
   this block is inert.
   -------------------------------------------------------------------------- */

@view-transition { navigation: auto; }

::view-transition-old(root),
::view-transition-new(root) { animation-duration: .18s; }

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* --- small layout modifiers ------------------------------------------------ */

.tight-top { padding-top: var(--s5); }
.page-head--tall { padding-top: var(--s8); }
.series-blurb { margin: var(--s3) 0; }

/* --- Timur post rows -------------------------------------------------------
   Compact scan list. Title (with an inline part label) spans the top; small
   thumbnail left, one-sentence summary right. Row height is governed by the
   90px thumbnail, so ~5 rows fit a laptop viewport.
   -------------------------------------------------------------------------- */

.posts { border-top: 1px solid var(--rule); }

.post {
  display: grid;
  grid-template-columns: 160px 1fr;
  grid-template-areas:
    "head head"
    "thumb sum";
  column-gap: var(--s4);
  row-gap: var(--s2);
  align-items: start;
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--rule);
  text-decoration: none;
  color: var(--ink);
}
.post:hover { color: var(--ink); background: var(--paper-alt); }
.post:hover .post-t { text-decoration: underline; text-underline-offset: 3px; }
.post:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: -2px; }

.post-head {
  grid-area: head; display: block;
  font-size: 19px; font-weight: 600; line-height: 1.3; letter-spacing: -0.012em;
}
.post-n {
  font-size: 11px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-muted);
  background: var(--paper-alt); border: 1px solid var(--rule);
  border-radius: 2px; padding: 2px 6px; margin-right: var(--s2);
  vertical-align: 2px; white-space: nowrap;
}
.post-t { }

.post-thumb {
  grid-area: thumb;
  width: 160px; height: 90px;
  object-fit: cover; border-radius: 3px;
  border: 1px solid var(--rule); background: var(--paper-alt);
}

.post-sum {
  grid-area: sum; display: block;
  font-size: 16px; line-height: 1.5; color: var(--ink-muted);
  max-width: 54ch;
}

.posts + .note { margin-top: var(--s4); }

@media (max-width: 640px) {
  .post {
    grid-template-columns: 104px 1fr;
    column-gap: var(--s3);
    padding: var(--s3) 0;
  }
  .post-head { font-size: 17px; }
  .post-thumb { width: 104px; height: 59px; }
  .post-sum { font-size: 15px; }
}

/* --- viz grid (Tableau) ---------------------------------------------------- */

.viz-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--s4); margin-top: var(--s4);
}
.viz-grid--teaser { margin-top: 0; }
.viz-card {
  display: block; text-decoration: none; color: var(--ink);
  border: 1px solid var(--rule); border-radius: 3px; overflow: hidden;
  background: var(--paper); transition: border-color .15s ease;
}
.viz-card:hover { border-color: var(--ink); color: var(--ink); }
.viz-card img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover; object-position: top;
  display: block; border-bottom: 1px solid var(--rule); background: var(--paper-alt);
}
.viz-card span {
  display: block; font-size: 14px; font-weight: 550; line-height: 1.35;
  padding: var(--s2) var(--s3) var(--s3);
}
@media (max-width: 640px) { .viz-grid { grid-template-columns: 1fr 1fr; gap: var(--s3); }
  .viz-grid--teaser { grid-template-columns: 1fr; } }

/* --- current-role strip ----------------------------------------------------- */

.lead-strip {
  margin-top: var(--s4); padding: var(--s3) var(--s4);
  background: var(--paper-alt); border: 1px solid var(--rule); border-radius: 3px;
}
.lead-strip p { max-width: none; font-size: 16px; margin: 0; }

/* --- compact case outcome --------------------------------------------------- */

.case-out {
  border-left: 3px solid var(--accent);
  padding-left: var(--s3);
}

/* bulleted list inside a case study */
.prose-list {
  list-style: disc; padding-left: var(--s4);
  margin-top: var(--s3); max-width: var(--measure);
}
.prose-list li + li { margin-top: var(--s2); }
.case > p { margin-top: var(--s3); }
.case .stats { margin-bottom: var(--s2); }


/* --- wide container for media galleries ------------------------------------
   Text stays at 720px for readability; image grids get room so 16:9 covers
   and dashboard thumbnails render large enough to actually read.
   -------------------------------------------------------------------------- */

.wrap--wide { max-width: 1080px; }

/* --- Datawrapper grid ------------------------------------------------------
   Charts vary widely in aspect ratio (from 3048x576 to 1360x906), so height is
   left natural — cropping to a fixed ratio would destroy them.
   -------------------------------------------------------------------------- */

.dw-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: var(--s4); margin-top: var(--s4);
  align-items: stretch;
}
.dw-card {
  display: flex; flex-direction: column;
  text-decoration: none; color: var(--ink);
  border: 1px solid var(--rule); border-radius: 3px; overflow: hidden;
  background: #fff; transition: border-color .15s ease;
}
.dw-card:hover { border-color: var(--ink); color: var(--ink); }
/* Uniform 5:3 box for every chart, so all cards render identically.
   `contain` fits the whole chart inside rather than cropping — these carry
   axis labels and value annotations, so nothing may be cut off. Charts that
   aren't exactly 5:3 sit centred with a little white space around them.
   5:3 was chosen by measuring the current charts (1.50, 1.61, 1.91): it gives
   ~9% average empty space with no chart worse than 13%. If you add charts of a
   very different shape, that balance shifts — the ratio is a single value to
   retune here. */
.dw-card img {
  width: 100%; aspect-ratio: 5 / 3; height: auto; display: block;
  object-fit: contain; background: #fff;
  padding: var(--s2);
  border-bottom: 1px solid var(--rule);
}
.dw-card .dw-t { margin-top: auto; }
.dw-t {
  display: block; font-size: 16px; font-weight: 550; line-height: 1.35;
  padding: var(--s3) var(--s3) 2px;
}
.dw-b {
  display: block; font-size: 14px; color: var(--ink-muted); line-height: 1.45;
  padding: 0 var(--s3) var(--s3);
}

/* --- current-role strip at page top ---------------------------------------- */

.lead-strip--top { margin-top: 0; margin-bottom: var(--s6); padding: var(--s4); }
.lead-role {
  font-weight: 650; font-size: 15px; letter-spacing: .01em;
  margin-bottom: var(--s2) !important;
}
.lead-strip--top p + p { margin-top: var(--s2); }


/* --- individual project pages ----------------------------------------------
   A case study page: back link, meta line, title, lede, then labelled fields.
   Reuses .field / .field-label / .stats / .callout from the work components.
   -------------------------------------------------------------------------- */

.page-head--case { padding-bottom: var(--s5); }

.back-link {
  display: inline-block; font-size: 15px; font-weight: 550;
  color: var(--ink-muted); text-decoration: none;
  margin-bottom: var(--s4); min-height: 32px;
}
.back-link:hover { color: var(--accent); }

.case-meta {
  font-size: 13px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-muted);
  margin-bottom: var(--s2);
}

.page-head--case h1 { font-size: 34px; line-height: 1.2; }
@media (max-width: 640px) { .page-head--case h1 { font-size: 28px; } }

.case-detail { padding-bottom: var(--s6); }
.case-detail .field + .field { margin-top: var(--s5); }
.case-detail .field p + p { margin-top: var(--s3); }

/* outcome line on the work-index cards */
.card-out {
  display: block; margin-top: var(--s3);
  font-size: 15px; font-weight: 600; color: var(--ink);
  border-left: 3px solid var(--accent); padding-left: var(--s3);
}
.card h2 {
  font-size: 21px; font-weight: 600; line-height: 1.35;
  letter-spacing: -0.012em; margin-bottom: var(--s2);
}


/* --- CV timeline -----------------------------------------------------------
   Compact resume summary on the About page: dates left, one line of scope
   right. Deliberately has no achievement bullets — those live on the project
   pages, and repeating them here made the detail feel redundant on arrival.
   -------------------------------------------------------------------------- */

.cv { margin-top: var(--s5); border-top: 1px solid var(--rule); }

.cv-row {
  display: grid; grid-template-columns: 150px 1fr;
  gap: var(--s4);
  padding: var(--s4) 0;
  border-bottom: 1px solid var(--rule);
}
.cv-when {
  font-size: 14px; color: var(--ink-muted); line-height: 1.5;
  padding-top: 2px; white-space: nowrap;
}
.cv-what p { margin: 0; max-width: 56ch; }
.cv-role { font-weight: 600; font-size: 17px; line-height: 1.4; }
.cv-org { font-weight: 400; color: var(--ink-muted); }
.cv-what p + p { margin-top: var(--s1); font-size: 16px; color: var(--ink-muted); }

@media (max-width: 640px) {
  .cv-row { grid-template-columns: 1fr; gap: var(--s1); padding: var(--s3) 0; }
  .cv-when { order: 2; }
  .cv-what { order: 1; }
}


/* --- on-this-page outline --------------------------------------------------
   A fixed outline to the LEFT of the 720px content column, so it costs the
   reading measure nothing. It only appears when the viewport is wide enough to
   hold it without crowding: 720 content + 180 sidebar + gaps needs ~1180px.
   Below that it is hidden entirely — on a narrow screen a persistent outline
   steals more room than it repays.

   Generated from each page's own <h2> elements at build time, so the links
   work with JavaScript disabled. JS only adds the current-section highlight.
   -------------------------------------------------------------------------- */

.toc { display: none; }

@media (min-width: 1180px) {
  .toc {
    display: block;
    position: fixed;
    top: 132px;
    /* content column starts at calc(50% - 360px); sit 32px to its left */
    left: calc(50% - 360px - 32px - 180px);
    width: 180px;
    z-index: 5;
  }
  .toc-h {
    font-size: 12px; font-weight: 700; letter-spacing: .09em;
    text-transform: uppercase; color: var(--ink-muted);
    margin: 0 0 var(--s3); padding-left: 13px;
  }
  .toc ul { margin: 0; padding: 0; list-style: none; }
  .toc li { margin: 0; }
  .toc a {
    display: block;
    font-size: 14px; line-height: 1.4;
    color: var(--ink-muted); text-decoration: none;
    padding: 7px 0 7px 12px;
    border-left: 1px solid var(--rule);
    transition: color .15s ease, border-color .15s ease;
  }
  .toc a:hover { color: var(--ink); border-left-color: var(--ink-muted); }
  .toc a[aria-current="true"] {
    color: var(--ink); font-weight: 550;
    border-left-color: var(--accent);
  }
  .toc a:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
}

/* anchored headings should not land flush against the viewport top */
h2[id] { scroll-margin-top: var(--s6); }


/* --- icons -----------------------------------------------------------------
   One inline SVG sprite, defined once per page in _partials/head.html.
   Icons inherit currentColor, so they take the colour of whatever contains
   them and need no separate styling per context.
   -------------------------------------------------------------------------- */

.sprite { display: none; }

.ico {
  width: 20px; height: 20px;
  fill: none; vertical-align: -4px;
  flex: none;
}
.ico-sm { width: 16px; height: 16px; vertical-align: -3px; }

/* --- social icon row -------------------------------------------------------
   Icon-only links, so each carries an aria-label — a screen reader would
   otherwise announce nothing at all. 40px hit area for touch.
   -------------------------------------------------------------------------- */

/* `ul.social` not `.social`: this row can sit inside .prose, where
   `.prose ul { list-style: disc }` would otherwise out-specify it and put a
   bullet beside every icon. */
ul.social {
  display: flex; gap: var(--s2);
  list-style: none; padding: 0; margin: var(--s4) 0 0;
}
ul.social li { list-style: none; margin: 0; }
.social a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; margin-left: -8px;
  color: var(--ink-muted); border-radius: 4px;
  transition: color .15s ease, background-color .15s ease;
}
.social a:hover { color: var(--ink); background: var(--paper-alt); }
.social a:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 1px; }
.social--bio { margin-top: var(--s5); }

/* --- About: bio header -----------------------------------------------------
   Avatar and name on one line, with role and location beneath. More compact
   than a full page-head, which suits a page that is a summary rather than an
   argument.
   -------------------------------------------------------------------------- */

.page-head--bio { padding: var(--s7) 0 0; }

/* The bio text belongs to the header block, so it sits close to the avatar
   rather than a full section gap away. Slightly smaller than body copy —
   this is a summary, and the pages it points to carry the detail. */
.bio-prose { padding-top: var(--s4); }
.bio-prose p { font-size: 17px; line-height: 1.6; max-width: 64ch; }
.bio-prose p + p { margin-top: var(--s3); }

.bio-id { display: flex; align-items: center; gap: var(--s4); }
.avatar {
  width: 112px; height: 112px; flex: none;
  border-radius: 50%; object-fit: cover;
  border: 1px solid var(--rule);
}
.page-head--bio h1 {
  font-size: 34px; line-height: 1.15; margin: 0 0 var(--s1);
}
.bio-meta {
  font-size: 16px; color: var(--ink-muted); margin: 0;
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
.bio-meta .dot { color: var(--rule); }

@media (max-width: 640px) {
  .bio-id { gap: var(--s3); }
  .avatar { width: 80px; height: 80px; }
  .page-head--bio h1 { font-size: 27px; }
  .bio-meta { font-size: 15px; }
}

/* --- contact card ----------------------------------------------------------
   One clear next step at the foot of the About page. The primary action is
   filled; everything else is outlined, so there is never ambiguity about
   which one is the intended path.
   -------------------------------------------------------------------------- */

.contact-card {
  border: 1px solid var(--rule); border-radius: 8px;
  background: var(--paper);
  padding: var(--s5) var(--s5) var(--s5);
}
.contact-card h2 { margin: 0 0 var(--s3); }
.contact-card p { color: var(--ink-muted); margin: 0; max-width: 58ch; }

.contact-actions {
  display: flex; flex-wrap: wrap; gap: var(--s2);
  margin-top: var(--s5);
}
.contact-actions .btn { gap: 8px; }

@media (max-width: 640px) {
  .contact-card { padding: var(--s4); }
  .contact-actions .btn { flex: 1 1 auto; }
}
