/* ferlogs — editorial monocromo con un acento que sale del Sol de Mayo.
   El dorado #fcbf49 sobre blanco da 1.66:1, así que el acento cambia por
   tema: dorado en oscuro, y en claro el marrón #843511 del trazo del sol
   (8.4:1). Los dos salen del mismo dibujo, así que el sitio no gana un
   color nuevo: usa los que ya tenía.
   Cristal: la cabecera se despega al hacer scroll. Sin fuentes web,
   sin imágenes de decoración, sin dependencias. */

:root{
  /* superficie e ink */
  --paper:#ffffff;
  --obsidian:#000000;
  --inkstone:#181818;
  --felt:#595959;          /* 7.0:1 sobre papel — antes #6d6d6d, 5.2:1 */
  --ash:#a8a8a8;           /* 8.8:1 sobre negro */
  --hair:rgba(0,0,0,.14);
  --hair-strong:rgba(0,0,0,.32);
  --wash:rgba(0,0,0,.035);

  --bg:var(--paper);
  --fg:var(--obsidian);
  --body:var(--inkstone);
  --muted:var(--felt);

  /* acento: el sol, en la versión que contrasta con el fondo de cada tema */
  --accent:#843511;
  --accent-line:rgba(132,53,17,.38);
  --accent-wash:rgba(132,53,17,.08);

  /* cristal de la isla flotante */
  --glass:rgba(255,255,255,.68);
  --glass-edge:rgba(0,0,0,.10);
  --glass-shadow:0 10px 34px rgba(0,0,0,.10),0 2px 8px rgba(0,0,0,.05);

  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,"Helvetica Neue",Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;

  /* escala: 300 solo en titulares grandes; el cuerpo va a 400 */
  --t-display:clamp(3rem,8.5vw,6.25rem);
  --t-title:clamp(2rem,4.6vw,3.25rem);
  --t-section:clamp(1.35rem,2.6vw,1.9rem);
  --t-body:1.0625rem;
  --t-sm:.9375rem;
  --t-label:.75rem;        /* 12px — antes 11px, demasiado con tracking */

  --page:1078px;
  --section-gap:clamp(46px,7vw,86px);
  --gap:14px;

  /* estados: pastel de fondo con texto profundo del mismo matiz */
  --ok-bg:#dcfce7; --ok-fg:#14532d;
  --go-bg:#dbeafe; --go-fg:#1e3a8a;
  --idle-bg:#ececec; --idle-fg:#3f3f46;
  --warm-bg:#fef3c7; --warm-fg:#713f12;

  --pill:75px;
  --ease:cubic-bezier(.19,1,.22,1);
  --slow:.85s;
  --quick:.4s;
}
[data-theme=dark]{
  --bg:#000000; --fg:#ffffff; --body:#ededed; --muted:var(--ash);
  --hair:rgba(255,255,255,.16); --hair-strong:rgba(255,255,255,.42);
  --wash:rgba(255,255,255,.05);
  --accent:#fcbf49;
  --accent-line:rgba(252,191,73,.42);
  --accent-wash:rgba(252,191,73,.10);
  --glass:rgba(18,18,18,.62);
  --glass-edge:rgba(255,255,255,.14);
  --glass-shadow:0 10px 34px rgba(0,0,0,.55),0 2px 8px rgba(0,0,0,.4);
  --ok-bg:#0e2a1a; --ok-fg:#86efac;
  --go-bg:#10233d; --go-fg:#93c5fd;
  --idle-bg:#1f1f24; --idle-fg:#c9c9d4;
  --warm-bg:#2c2312; --warm-fg:#fcd34d;
}
@media (prefers-color-scheme:dark){:root:not([data-theme=light]){
  --bg:#000000; --fg:#ffffff; --body:#ededed; --muted:var(--ash);
  --hair:rgba(255,255,255,.16); --hair-strong:rgba(255,255,255,.42);
  --wash:rgba(255,255,255,.05);
  --accent:#fcbf49;
  --accent-line:rgba(252,191,73,.42);
  --accent-wash:rgba(252,191,73,.10);
  --glass:rgba(18,18,18,.62);
  --glass-edge:rgba(255,255,255,.14);
  --glass-shadow:0 10px 34px rgba(0,0,0,.55),0 2px 8px rgba(0,0,0,.4);
  --ok-bg:#0e2a1a; --ok-fg:#86efac;
  --go-bg:#10233d; --go-fg:#93c5fd;
  --idle-bg:#1f1f24; --idle-fg:#c9c9d4;
  --warm-bg:#2c2312; --warm-fg:#fcd34d;}}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--bg);color:var(--body);
  font:400 var(--t-body)/1.58 var(--sans);-webkit-font-smoothing:antialiased;
  font-feature-settings:"kern","liga"}
h1,h2,h3{margin:0;color:var(--fg);font-weight:300;letter-spacing:-.022em;line-height:1.1}
p,ul{margin:0}ul{list-style:none;padding:0}
img,svg{max-width:100%}

/* enlaces: sin subrayado en navegación y listas; en prosa van en el acento
   con un subrayado que se completa al pasar por encima, porque dentro de un
   párrafo el contexto no basta para señalar el destino */
a{color:inherit;text-decoration:none}
.prose a,.article-body a{color:var(--accent);position:relative;
  text-decoration:underline;text-decoration-thickness:1px;
  text-underline-offset:.22em;text-decoration-color:var(--accent-line);
  transition:text-decoration-color var(--quick) ease,background var(--quick) ease}
.prose a:hover,.article-body a:hover{text-decoration-color:currentColor;
  background:var(--accent-wash)}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:2px}

/* enlace externo: la flecha va dentro del enlace, nunca suelta en el DOM */
.ext{display:inline-block;width:.62em;height:.62em;margin-left:.42em;
  vertical-align:baseline;fill:none;stroke:currentColor;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round;opacity:.75;
  transition:transform var(--slow) var(--ease),opacity var(--quick) ease}
a:hover .ext{opacity:1;transform:translate(2px,-2px)}

.label{font:400 var(--t-label)/1.36 var(--sans);letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted)}
.skip{position:absolute;left:-9999px}
.skip:focus{left:24px;top:24px;z-index:20;background:var(--bg);color:var(--fg);
  border:1px solid var(--fg);padding:12px 20px}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

.wrap{width:min(100% - 48px,var(--page));margin-inline:auto}
@media (max-width:640px){.wrap{width:min(100% - 32px,var(--page))}}

/* ---------- navegación: se despega en isla flotante al bajar ----------
   En reposo es una cabecera normal pegada arriba. Pasado el umbral, el
   .wrap se convierte en una píldora de cristal que flota sobre el
   contenido. Solo cambian el contenedor y el fondo: los enlaces no se
   mueven de sitio, así que no hay salto de foco ni de lectura.          */
.top{position:sticky;top:0;z-index:60;height:68px;display:flex;align-items:center;
  border-bottom:1px solid var(--hair);
  transition:border-color var(--quick) ease}
/* El padding y el borde existen siempre, aunque sean transparentes: al
   fijarse solo cambian color, radio y sombra. Si la altura cambiara, el
   documento se movería bajo el dedo y el scroll daría un tirón — pasaba,
   medido: de y=52 saltaba a y=79. */
.top .wrap{display:flex;align-items:center;gap:28px;
  padding:10px 14px 10px 20px;
  border:1px solid transparent;border-radius:var(--pill);
  transition:background var(--quick) ease,border-color var(--quick) ease,
             box-shadow var(--quick) ease}

.top.pinned{border-bottom-color:transparent}
.top.pinned .wrap{
  border-color:var(--glass-edge);
  background:var(--glass);
  box-shadow:var(--glass-shadow);
  -webkit-backdrop-filter:blur(22px) saturate(180%);
  backdrop-filter:blur(22px) saturate(180%)}
/* sin backdrop-filter el cristal sería un panel translúcido ilegible */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .top.pinned .wrap{background:var(--bg);border-color:var(--hair-strong)}
}

.brand{font:500 1rem/1 var(--sans);letter-spacing:-.01em;color:var(--fg)}
.top nav{margin-left:auto;display:flex;flex-wrap:wrap;align-items:center;gap:26px}
.top nav a{position:relative;font:500 var(--t-label)/1.36 var(--sans);
  letter-spacing:.12em;text-transform:uppercase;color:var(--muted);
  padding-block:4px;transition:color var(--quick) ease}
.top nav a::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1.5px;
  background:var(--accent);transform:scaleX(0);transform-origin:left;
  transition:transform var(--slow) var(--ease)}
.top nav a:hover{color:var(--fg)}
.top nav a:hover::after{transform:scaleX(1)}
.top nav a[aria-current=page]{color:var(--fg)}
.top nav a[aria-current=page]::after{transform:scaleX(1)}

/* tema: un solo botón que cicla auto → claro → oscuro */
.theme-btn{display:inline-flex;align-items:center;justify-content:center;
  width:38px;height:38px;flex:0 0 auto;padding:0;cursor:pointer;
  background:transparent;color:var(--muted);
  border:1px solid var(--hair-strong);border-radius:50%;
  transition:color var(--quick) ease,border-color var(--quick) ease,
             background var(--quick) ease}
.theme-btn:hover{color:var(--accent);border-color:var(--accent-line);
  background:var(--accent-wash)}
.theme-btn svg{width:17px;height:17px;fill:none;stroke:currentColor;
  stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.theme-btn svg{display:none}
.theme-btn[data-mode=system] .i-system,
.theme-btn[data-mode=light] .i-light,
.theme-btn[data-mode=dark] .i-dark{display:block}

/* ---------- hero contenido -------------------------------------------
   Sin banda a sangre ni atmósfera: el mismo ancho editorial que el resto
   de la página. El color queda en el Sol de Mayo y en el rastro del
   puntero, que son gestos pequeños.                                     */
.hero{padding-block:clamp(48px,9vw,104px) clamp(40px,6vw,72px);
  display:flex;gap:clamp(24px,5vw,64px);align-items:center;flex-wrap:wrap}
.hero-main{flex:1 1 26rem;min-width:0}
.wordmark{font:500 clamp(2.1rem,5.4vw,3.4rem)/1 var(--mono);letter-spacing:-.05em;
  color:var(--fg);margin:0 0 clamp(20px,3vw,28px)}
.wordmark .dim{color:var(--muted)}
.hero .lede{max-width:56ch;color:var(--body);font-weight:400;font-size:1.15rem;
  line-height:1.5}
.hero .lede strong{color:var(--fg);font-weight:400}
.hero .lede a{color:var(--accent);text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:.22em;
  text-decoration-color:var(--accent-line);
  transition:text-decoration-color var(--quick) ease}
.hero .lede a:hover{text-decoration-color:currentColor}
.hero .meta{margin-top:clamp(22px,3vw,30px);display:flex;flex-wrap:wrap;
  align-items:center;gap:10px 20px;color:var(--muted)}
.hero .meta .open{display:inline-flex;align-items:center;gap:8px;
  background:var(--ok-bg);color:var(--ok-fg);border-radius:var(--pill);
  padding:5px 14px}
.hero .meta .dot{width:5px;height:5px;border-radius:50%;background:currentColor;
  display:inline-block;flex:0 0 auto}
.hero .sol{width:clamp(84px,13vw,124px);height:auto;flex:0 0 auto;margin-left:auto}
@media (max-width:640px){.hero .sol{margin:0;width:72px}}

/* ---------- rastro del puntero -------------------------------------
   Versión mínima: 8rem, muy desenfocado y a media opacidad, con los
   mismos matices que la atmósfera del hero para que se lea como la
   misma luz filtrándose. Se mueve con `translate` (GPU) y sus giros
   quedan en pausa mientras no se ve.                                  */
.body-wrap{position:relative;isolation:isolate;overflow:clip}
.orb{position:absolute;top:0;left:0;z-index:-1;pointer-events:none;
  width:8rem;aspect-ratio:1;border-radius:50%;margin:-4rem 0 0 -4rem;
  translate:var(--x,-40rem) var(--y,-40rem);
  opacity:0;transition:opacity .7s var(--ease);filter:blur(30px)}
.orb::before,.orb::after{content:"";position:absolute;inset:0;border-radius:50%;
  animation-play-state:paused}
.orb::before{background:conic-gradient(from 0deg,
  rgba(160,224,171,.42),rgba(255,172,46,.38),rgba(165,45,37,.34),rgba(160,224,171,.42));
  animation:orb-a 28s linear infinite}
.orb::after{background:conic-gradient(from 160deg,
  transparent,rgba(255,172,46,.26),transparent 55%);
  animation:orb-b 43s linear infinite}
@media (hover:hover) and (pointer:fine){
  .body-wrap.lit .orb{opacity:.55}
  .body-wrap.lit .orb::before,.body-wrap.lit .orb::after{animation-play-state:running}
}
@keyframes orb-a{to{rotate:360deg}}
@keyframes orb-b{to{rotate:-360deg}}

/* botón pill fantasma: sin relleno; en hover abre el tracking */
.ghost{display:inline-flex;align-items:center;gap:10px;border-radius:var(--pill);
  border:1px solid var(--hair-strong);color:var(--fg);padding:11px 33px;
  font:400 1rem/1 var(--sans);
  transition:border-color var(--slow) var(--ease),letter-spacing var(--slow) var(--ease),
             color var(--slow) var(--ease)}
.ghost:hover{border-color:var(--fg);letter-spacing:.04em}

/* ---------- ritmo editorial ---------- */
main{padding-block:var(--section-gap)}
section + section{margin-top:var(--section-gap)}
.page-head{padding-block:clamp(56px,10vw,120px) clamp(24px,4vw,40px)}
.page-head h1{font-size:var(--t-title);max-width:16ch}
.page-head p{margin-top:24px;max-width:58ch;color:var(--body);font-weight:400}

.shead{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 28px;
  padding-bottom:14px;border-bottom:1px solid var(--hair);margin-bottom:28px}
.shead h2{font-size:var(--t-section);font-weight:300}
.shead .sub{color:var(--muted);font-size:var(--t-sm);font-weight:400}
.shead .right{margin-left:auto}

/* ---------- filas: la fila es contenido, no contenedor ---------- */
.rows{border-top:1px solid var(--hair)}
.row,.log,.crow{position:relative;display:grid;align-items:baseline;
  border-bottom:1px solid var(--hair);gap:6px 28px;
  transition:background var(--quick) ease}
.row{grid-template-columns:96px 1fr 200px;padding:28px 12px 28px 0}
.log{grid-template-columns:96px 1fr 64px;padding:24px 12px 24px 0}
.crow{grid-template-columns:96px 1fr 24px;padding:26px 12px 26px 0}
.row:hover,.log:hover,.crow:hover,
.row:focus-within,.log:focus-within,.crow:focus-within{background:var(--wash)}

.row .name,.log .title,.crow .val{color:var(--fg);font-size:1.15rem;font-weight:400;
  display:inline-block;
  transition:transform var(--slow) var(--ease),letter-spacing var(--slow) var(--ease)}
.row:hover .name,.log:hover .title,.crow:hover .val,
.row:focus-within .name,.log:focus-within .title,.crow:focus-within .val{
  transform:translateX(10px)}
.row a::after,.log a::after,.crow a::after{content:"";position:absolute;inset:0}
.row .desc{grid-column:2;color:var(--body);max-width:52ch;font-weight:400;
  font-size:var(--t-sm)}
.row .stack,.log .mins{color:var(--muted);font-size:var(--t-label);
  letter-spacing:.08em;text-transform:uppercase;text-align:right}
.log time{color:var(--muted);font-size:var(--t-label);letter-spacing:.1em;
  font-variant-numeric:tabular-nums}
.crow .lbl{color:var(--muted)}
.crow .note{grid-column:2;color:var(--body);font-size:var(--t-sm);font-weight:400}
.crow .arrow{color:var(--muted);text-align:right;
  transition:transform var(--slow) var(--ease),color var(--quick) ease}
.crow:hover .arrow,.crow:focus-within .arrow{color:var(--fg);transform:translateX(6px)}

/* estado: píldora fantasma, sin color — el peso y el borde bastan */
.state{display:inline-flex;align-items:center;justify-self:start;
  border-radius:var(--pill);padding:5px 14px;
  font:400 var(--t-label)/1 var(--sans);letter-spacing:.12em;
  text-transform:uppercase;white-space:nowrap;
  background:var(--idle-bg);color:var(--idle-fg)}
.state.on{background:var(--ok-bg);color:var(--ok-fg)}
.state.wip{background:var(--go-bg);color:var(--go-fg)}

@media (max-width:760px){
  .row,.log,.crow{grid-template-columns:1fr;padding:22px 0}
  .row .desc,.crow .note{grid-column:1}
  .row .stack,.log .mins,.crow .arrow{text-align:left}
  .log .mins{display:none}
  .state{margin-bottom:10px}
  /* la cabecera pasa a dos filas: marca + tema arriba, navegación debajo */
  .top{height:auto;padding-block:12px}
  .top .wrap{flex-wrap:wrap;gap:12px 18px}
  .brand{margin-right:auto}
  .theme-btn{order:1}
  .top nav{order:2;width:100%;margin-left:0;gap:10px 18px}
  .top .wrap{border-radius:26px;padding:10px 14px 12px 18px}
}

/* ---------- las apuestas: dos tarjetas en paralelo ----------
   Una por proyecto destacado. En una sola columna por debajo de 720px,
   donde dos tarjetas de este alto serían ilegibles.                    */
.bets{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,330px),1fr));
  gap:20px}
.bet{display:flex;flex-direction:column;
  border:1px solid var(--hair);border-radius:20px;
  padding:clamp(26px,3.4vw,36px);background:var(--wash);
  transition:border-color var(--slow) var(--ease),
             box-shadow var(--slow) var(--ease),
             transform var(--slow) var(--ease)}
.bet:hover,.bet:focus-within{border-color:var(--accent-line);
  box-shadow:var(--glass-shadow);transform:translateY(-3px)}
.bet .top-line{display:flex;flex-wrap:wrap;align-items:center;gap:12px 16px;
  margin-bottom:8px}
.bet h3{font-size:clamp(1.7rem,3.2vw,2.3rem);font-weight:300;letter-spacing:-.03em}
.bet h3 a{color:var(--fg)}
.bet h3 a:hover{color:var(--accent)}
.bet .site{display:block;margin-bottom:20px;color:var(--accent);
  font:400 var(--t-sm)/1 var(--mono);letter-spacing:-.01em}
.bet .site:hover{text-decoration:underline;text-underline-offset:.25em}
.bet .tag{background:var(--warm-bg);color:var(--warm-fg);border-radius:var(--pill);
  padding:6px 14px;font:500 var(--t-label)/1 var(--sans);letter-spacing:.1em;
  text-transform:uppercase;white-space:nowrap}
.bet p{color:var(--body);max-width:46ch;font-weight:400;font-size:var(--t-sm)}
.bet p + p{margin-top:14px}
/* dos columnas fijas: con cuatro datos da un 2×2 limpio y los botones de
   ambas tarjetas quedan a la misma altura */
.bet dl{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:20px 24px;margin:auto 0 0;padding-top:30px}
.bet dt{color:var(--muted);font:500 var(--t-label)/1.36 var(--sans);
  letter-spacing:.12em;text-transform:uppercase}
.bet dd{margin:8px 0 0;color:var(--fg);font-size:var(--t-sm);font-weight:400}
.bet .ghost{margin-top:28px;align-self:flex-start}

/* rol: quién soy en el proyecto. Contorno en el acento, no relleno —
   el relleno pastel ya lo usa el estado y dos rellenos compiten. */
.role{display:inline-flex;align-items:center;border-radius:var(--pill);
  padding:5px 13px;border:1px solid var(--accent-line);color:var(--accent);
  background:var(--accent-wash);
  font:500 var(--t-label)/1 var(--sans);letter-spacing:.1em;
  text-transform:uppercase;white-space:nowrap}

/* aparición al entrar en pantalla: la clase la pone el JS, así que sin JS
   el contenido se ve igual — nunca se esconde nada que no se pueda mostrar */
.reveal{opacity:0;transform:translateY(16px);
  transition:opacity .75s var(--ease),transform .75s var(--ease)}
.reveal.in{opacity:1;transform:none}

.prose{max-width:58ch;color:var(--body);font-weight:400}
.prose p + p{margin-top:18px}
.prose h3{margin-top:48px;font-size:1.15rem;font-weight:400;letter-spacing:-.01em}
.prose h3 + p{margin-top:12px}
.prose strong{color:var(--fg);font-weight:400}
.prose ul{margin-top:18px}
.prose li{padding-left:22px;position:relative}
.prose li::before{content:"";position:absolute;left:0;top:.78em;width:10px;height:1px;
  background:var(--hair-strong)}
.prose li + li{margin-top:12px}

/* ---------- consola ---------- */
#console{display:none}
#console.ready{display:block}
.term{border:1px solid var(--hair);font-family:var(--mono);font-size:.85rem}
.term-bar{padding:12px 16px;border-bottom:1px solid var(--hair);color:var(--muted);
  font:400 var(--t-label)/1 var(--sans);letter-spacing:.14em;text-transform:uppercase}
.term-out{padding:20px 16px;max-height:19rem;overflow-y:auto;white-space:pre-wrap;
  word-break:break-word;color:var(--muted);line-height:1.7}
.term-out .in,.term-out .k{color:var(--fg)}
.term-form{display:flex;align-items:center;gap:10px;border-top:1px solid var(--hair);
  padding:12px 16px}
.term-form > span{color:var(--muted)}
#cmdline{flex:1;font:inherit;font-family:var(--mono);color:var(--fg);background:none;
  border:0;padding:6px 0;min-height:32px}
#cmdline:focus{outline:none}
.term-form:focus-within{outline:1px solid var(--fg);outline-offset:-1px}

footer{border-top:1px solid var(--hair);margin-top:var(--section-gap);
  padding-block:clamp(40px,6vw,68px)}
.foot-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:28px}
footer p,footer a{color:var(--muted);font-size:var(--t-sm);font-weight:400}
footer a:hover{color:var(--fg)}
footer .stack-links{display:flex;flex-direction:column;gap:8px;align-items:flex-start}
footer .sol{width:76px;height:auto;opacity:.95}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;scroll-behavior:auto !important}
  .atmos i,.orb::before,.orb::after{animation:none}
  .orb{display:none}
  /* el reveal deja de ser animación y pasa a no existir: el contenido, quieto */
  .reveal,.reveal.in{opacity:1 !important;transform:none !important}
  .bet:hover,.bet:focus-within{transform:none}
}
@media (prefers-contrast:more){
  :root{--muted:var(--fg);--hair:var(--fg);--hair-strong:var(--fg)}
  .atmos{opacity:.5}
  .orb{display:none}
  /* el cristal se vuelve opaco: translúcido y alto contraste no conviven */
  .top.pinned .wrap{background:var(--bg);border-color:var(--fg);
    -webkit-backdrop-filter:none;backdrop-filter:none}
  .bet{background:transparent;border-color:var(--fg)}
  .role{border-color:var(--fg);color:var(--fg);background:transparent}
}

/* ---------- artículo ---------- */
.article{padding-block:clamp(40px,7vw,80px) 0;max-width:68ch}
.article .meta{display:flex;flex-wrap:wrap;gap:8px 20px;margin-bottom:24px}
.article h1{font-size:var(--t-title);max-width:20ch}
.article .standfirst{margin-top:24px;font-size:1.2rem;font-weight:400;color:var(--body);
  line-height:1.5}
.article-body{max-width:68ch;margin-top:clamp(36px,5vw,56px);color:var(--body);
  font-weight:400}
.article-body > * + *{margin-top:20px}
.article-body h2{font-size:1.5rem;font-weight:400;margin-top:48px;letter-spacing:-.015em}
.article-body h3{font-size:1.15rem;font-weight:400;margin-top:36px}
.article-body ul{margin-left:0}
.article-body li{padding-left:22px;position:relative}
.article-body li::before{content:"";position:absolute;left:0;top:.78em;width:10px;
  height:1px;background:var(--hair-strong)}
.article-body li + li{margin-top:10px}
.article-body pre{background:var(--wash);border:1px solid var(--hair);padding:20px;
  overflow-x:auto;font-family:var(--mono);font-size:.85rem;line-height:1.6;color:var(--fg)}
.article-body code{font-family:var(--mono);font-size:.9em;background:var(--wash);
  padding:2px 6px}
.article-body pre code{background:none;padding:0}
.article-body blockquote{border-left:2px solid var(--hair-strong);padding-left:24px;
  color:var(--muted);font-style:normal}
.article-nav{margin-top:clamp(48px,7vw,80px);padding-top:28px;
  border-top:1px solid var(--hair);display:flex;flex-wrap:wrap;gap:20px}
.todo{background:var(--warm-bg);color:var(--warm-fg);padding:20px 24px;
  border-radius:0;font-size:var(--t-sm);font-weight:400}
.todo strong{display:block;margin-bottom:6px;letter-spacing:.06em;text-transform:uppercase;
  font-size:var(--t-label)}
