/* ============================================================
   AM modulation — post styles.
   Same system as the other essays: the three hues come from
   assets/site.css (paper / ink / sig) and nothing here invents
   a colour of its own. The Persian block near the bottom turns
   the article around; the header and footer never move.
   ============================================================ */

/* the blueprint blue was tuned against dark ink; over cream it needs to be
   deeper to keep 11px mono labels above 6:1 */
html:not(.ink){ --sig:#1E49A8; }

/* light-theme legibility — dark ink on cream loses contrast much faster
   than light ink on near-black, so lift the faint tiers */
html:not(.ink) .mono-label{ opacity:1; }
html:not(.ink) .ro dt{ opacity:.8; }
html:not(.ink) .eq .lbl{ opacity:.75; }
html:not(.ink) .byline .dot{ opacity:.55; }

/* ---------- reading column ---------- */
.post{ padding-bottom:4rem; }
.post > *{ max-width:66ch; }
.post > .wide,
.post > figure.fig,
.post > .rule{ max-width:100%; }

.post p{ margin:0 0 1.15rem; }
.post h2{
  display:flex; align-items:baseline; gap:.7rem;
  font-size:1.6rem; font-weight:700; letter-spacing:-.01em;
  margin:3.4rem 0 1rem; scroll-margin-top:5rem;
}
.post h2 .secnum{ font-family:var(--font-mono); font-weight:500; font-size:.95rem; color:var(--sig); }
.post h3{ font-size:1.05rem; margin:2rem 0 .5rem; }
.post strong{ font-weight:700; }
.post em{ font-style:italic; }

.rule{
  border:0; height:1px; margin:3rem 0 0;
  background:color-mix(in srgb, var(--fg) 22%, transparent);
}

/* ---------- article hero ---------- */
.post-hero{ padding:3.4rem 0 .6rem; max-width:100%; }
.post-kicker{ color:var(--sig); margin-bottom:.9rem; display:block; }
.post-hero h1{
  font-size:clamp(2.2rem, 5.6vw, 3.7rem);
  line-height:1.05; letter-spacing:-.025em;
  margin:0 0 1rem; font-weight:700; max-width:16ch;
}
.post-sub{ font-size:1.12rem; max-width:56ch; opacity:.9; }

/* intro text beside a live waveform, so "look at it" has something to look at.
   NOTE: not .hero-grid — site.css already owns that class for the home page. */
.post-lede{
  display:grid; grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  gap:2.4rem; align-items:center;
}
.lede-chart{ margin:0; }
.lede-chart canvas{ display:block; width:100%; height:100%; }
.lede-chart figcaption{ text-align:center; margin-top:.55rem; opacity:.5; }
@media (max-width:760px){
  .post-lede{ grid-template-columns:1fr; gap:1.6rem; }
  .lede-chart{ max-width:340px; margin:0 auto; }
}

.byline{
  display:flex; gap:.7rem; flex-wrap:wrap; align-items:center;
  margin-top:1.6rem; padding-top:1rem;
  border-top:1px solid color-mix(in srgb, var(--fg) 20%, transparent);
  max-width:100%;
}
.byline .dot{ opacity:.4; }

.backlink{
  font-family:var(--font-mono); font-size:.78rem; letter-spacing:.08em;
  text-transform:uppercase; text-decoration:none; opacity:.8;
}
.backlink:hover{ color:var(--sig); opacity:1; }

/* ---------- share row ---------- */
.share{
  display:flex; align-items:center; gap:.45rem; flex-wrap:wrap;
  margin-top:1rem; max-width:100%;
}
.share-label{ color:var(--sig); margin-right:.15rem; }
.share-btn{
  display:inline-flex; align-items:center; gap:.4rem;
  font-family:var(--font-mono); font-size:.72rem; letter-spacing:.05em;
  padding:.36rem .62rem; border-radius:3px;
  border:1.4px solid color-mix(in srgb, var(--fg) 32%, transparent);
  background:none; color:var(--fg); text-decoration:none;
  cursor:pointer; white-space:nowrap;
}
.share-btn svg{ width:13px; height:13px; flex:none; }
.share-btn:hover{ border-color:var(--sig); color:var(--sig); }
.share-btn:focus-visible{ outline:2px solid var(--sig); outline-offset:2px; }
.share-btn.done{ border-color:var(--sig); color:var(--sig); }
@media (max-width:520px){
  .share-btn{ padding:.34rem .5rem; }
  .share.has-native .share-btn:not(#shareCopy):not(#shareNative){ display:none; }
}

/* ---------- plain-English side boxes ---------- */
details.decode{
  margin:1.4rem 0;
  border:1px dashed color-mix(in srgb, var(--fg) 34%, transparent);
  border-radius:4px;
  background:color-mix(in srgb, var(--bg) 91%, var(--sig));
}
html:not(.ink) details.decode{ background:color-mix(in srgb, var(--bg) 94%, var(--sig)); }
details.decode[open]{
  border-style:solid;
  border-color:color-mix(in srgb, var(--sig) 38%, transparent);
}
details.decode > summary{
  cursor:pointer; list-style:none;
  padding:.62rem .9rem;
  font-family:var(--font-mono); font-size:.76rem; letter-spacing:.04em;
  color:var(--sig);
  display:flex; align-items:baseline; gap:.55rem;
}
html.ink details.decode > summary{ color:color-mix(in srgb, var(--sig) 60%, var(--fg)); }
details.decode > summary::-webkit-details-marker{ display:none; }
details.decode > summary::before{ content:"+"; font-weight:700; line-height:1; opacity:.9; flex:none; }
details.decode[open] > summary::before{ content:"−"; }
details.decode > summary:hover{ text-decoration:underline; }
details.decode > summary:focus-visible{ outline:2px solid var(--sig); outline-offset:2px; }
.decode-body{
  margin:0 .9rem; padding:0 0 .9rem;
  border-top:1px dashed color-mix(in srgb, var(--fg) 22%, transparent);
}
.post .decode-body p{ margin:.7rem 0 0; font-size:.93rem; }
.post .decode-body p:last-child{ margin-bottom:0; }
.post .decode-body ul{ margin:.7rem 0 0; font-size:.93rem; }

/* ---------- table of contents ---------- */
.toc{ padding:1.1rem 1.3rem; margin:2.2rem 0 0; }
.toc ol{ margin:.6rem 0 0; padding-left:1.2rem; columns:2; column-gap:2rem; }
.toc li{ margin:.15rem 0; break-inside:avoid; }
.toc a{ text-decoration:none; }
.toc a:hover{ text-decoration:underline; text-decoration-color:var(--sig); }
@media (max-width:640px){ .toc ol{ columns:1; } }

/* ---------- figures ---------- */
figure.fig{
  margin:2rem 0 2.4rem;
  padding:1rem 1.15rem 1.15rem;
  overflow:hidden;
}
.fig-head{
  display:flex; align-items:baseline; gap:.6rem; flex-wrap:wrap;
  margin-bottom:.8rem;
}
.fig-head .fig-n{ color:var(--sig); }
.fig-head .fig-t{ font-weight:500; letter-spacing:.02em; }
figure.fig figcaption{
  margin-top:.9rem; padding-top:.8rem;
  border-top:1px solid color-mix(in srgb, var(--fg) 18%, transparent);
  font-size:.92rem; opacity:.85;
}
figure.fig figcaption b{ opacity:1; }

.canvas-wrap{ position:relative; width:100%; }
figure.fig canvas{
  display:block; width:100%; height:100%;
  /* pan-y, not none: nothing in this post is dragged on the canvas itself, and
     `none` meant a finger that landed on a figure could not scroll the page —
     with seven full-width figures, most of the article was unscrollable. */
  touch-action:pan-y;
  border-radius:4px;
}

/* the schematic that sits under a figure */
.ckt{
  margin-top:1rem; padding-top:.9rem;
  border-top:1px solid color-mix(in srgb, var(--fg) 18%, transparent);
}

/* two-up: plot on the left, controls on the right */
.fig-split{ display:grid; grid-template-columns:1.35fr 1fr; gap:1.2rem; align-items:start; }
.fig-split > *{ min-width:0; }
@media (max-width:760px){ .fig-split{ grid-template-columns:1fr; } }

/* controls in a row under a full-width plot */
.fig-ctls{ display:grid; grid-template-columns:1fr 1fr; gap:.4rem 1.6rem; align-items:start; }
.fig-ctls > *{ min-width:0; }
@media (max-width:640px){ .fig-ctls{ grid-template-columns:1fr; } }

/* ---------- controls ---------- */
.ctl{ margin:0 0 .9rem; }
.ctl:last-child{ margin-bottom:0; }
.ctl-label{
  display:flex; justify-content:space-between; align-items:baseline; gap:.6rem;
  margin-bottom:.25rem;
}
.ctl-val{ font-family:var(--font-mono); font-size:.82rem; color:var(--sig); }

input[type=range].slider{
  -webkit-appearance:none; appearance:none;
  width:100%; height:22px; background:none; cursor:pointer; margin:0;
}
input[type=range].slider::-webkit-slider-runnable-track{
  height:3px; border-radius:2px;
  background:color-mix(in srgb, var(--fg) 30%, transparent);
}
input[type=range].slider::-moz-range-track{
  height:3px; border-radius:2px;
  background:color-mix(in srgb, var(--fg) 30%, transparent);
}
input[type=range].slider::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none;
  width:16px; height:16px; margin-top:-6.5px;
  border-radius:50%; background:var(--sig);
  border:2px solid var(--bg); cursor:grab;
}
input[type=range].slider::-moz-range-thumb{
  width:16px; height:16px; border-radius:50%;
  background:var(--sig); border:2px solid var(--bg); cursor:grab;
}

.chip-row{ display:flex; gap:.4rem; flex-wrap:wrap; margin:0 0 .9rem; }
.pill{
  font-family:var(--font-mono); font-size:.72rem; letter-spacing:.05em;
  padding:.34rem .6rem; border-radius:3px; cursor:pointer;
  border:1.4px solid color-mix(in srgb, var(--fg) 40%, transparent);
  background:none; color:var(--fg);
}
.pill:hover{ border-color:var(--sig); color:var(--sig); }
.pill.on{ background:var(--sig); border-color:var(--sig); color:var(--paper); }

/* the Listen toggle: a pill, but never mistakable for one of the preset pills
   beside it — it is the only control on the page that does something you hear */
.pill.audio{
  border-color:var(--sig); color:var(--sig);
  font-weight:600; letter-spacing:.08em;
}
.pill.audio:hover{ background:color-mix(in srgb, var(--sig) 12%, transparent); }
.pill.audio.on{ background:var(--sig); color:var(--paper); }
.audio-hint{
  font-family:var(--font-mono); font-size:.68rem; letter-spacing:.03em;
  align-self:center; opacity:.6;
}
@media (max-width:400px){ .audio-hint{ display:none; } }

.check-row{ display:flex; gap:1rem; flex-wrap:wrap; margin:.2rem 0 .9rem; }
.check-row label{
  font-family:var(--font-mono); font-size:.74rem; letter-spacing:.04em;
  display:inline-flex; align-items:center; gap:.35rem; cursor:pointer;
}
.check-row input{ accent-color:var(--sig); }

/* ---------- readouts ---------- */
.ro{
  display:grid; grid-template-columns:auto 1fr; gap:.18rem .8rem;
  font-family:var(--font-mono); font-size:.82rem;
  margin:.9rem 0 0; padding-top:.8rem;
  border-top:1px solid color-mix(in srgb, var(--fg) 18%, transparent);
}
.ro dt{ opacity:.65; }
.ro dd{ margin:0; text-align:right; }
.ro dd b{ color:var(--sig); font-weight:500; }

/* a one-line verdict under a figure's controls: neutral, good, or broken */
.verdict{
  font-family:var(--font-mono); font-size:.76rem; line-height:1.5;
  margin:.9rem 0 0; padding:.5rem .65rem; border-radius:3px;
  border-left:3px solid color-mix(in srgb, var(--fg) 35%, transparent);
  background:color-mix(in srgb, var(--bg) 92%, var(--fg));
}
.verdict.good{ border-left-color:var(--sig); }
.verdict.bad{ border-left-color:#C8452F; }
html.ink .verdict.bad{ border-left-color:#E8705A; }

/* ---------- callouts ---------- */
.pull{
  margin:2.4rem 0; padding:.2rem 0 .2rem 1.3rem;
  border-left:3px solid var(--sig);
  font-size:1.16rem; line-height:1.5;
}

.eq{
  margin:1.4rem 0; padding:.9rem 1.1rem;
  font-family:var(--font-mono); font-size:1rem;
  text-align:center; overflow-x:auto;
}
.eq .lbl{ display:block; font-size:.7rem; letter-spacing:.12em; text-transform:uppercase; opacity:.6; margin-bottom:.45rem; }
.eq .frac{ display:inline-flex; flex-direction:column; vertical-align:middle; text-align:center; margin:0 .18em; }
.eq .frac .num{ border-bottom:1.2px solid currentColor; padding:0 .35em .12em; }
.eq .frac .den{ padding:.12em .35em 0; }
.eq .small{ display:block; font-family:inherit; font-size:.72rem; opacity:.65; margin-top:.5rem; }

.note{
  padding:.9rem 1.1rem; margin:1.6rem 0;
  border-left:3px solid color-mix(in srgb, var(--fg) 35%, transparent);
  font-size:.94rem; opacity:.9;
}
.note b{ opacity:1; }

/* ---------- the three-way comparison table ---------- */
.tbl{ width:100%; border-collapse:collapse; margin:1.4rem 0; font-size:.92rem; }
.tbl th, .tbl td{
  text-align:left; padding:.55rem .7rem;
  border-bottom:1px solid color-mix(in srgb, var(--fg) 16%, transparent);
  vertical-align:top;
}
.tbl th{
  font-family:var(--font-mono); font-size:.72rem; letter-spacing:.06em;
  text-transform:uppercase; opacity:.7; font-weight:500;
}
.tbl td:first-child{ font-weight:700; white-space:nowrap; }

/* ---------- closing CTA ---------- */
.cta{ padding:1.5rem 1.6rem; margin:2.6rem 0 0; }
.cta h3{ margin:0 0 .4rem; font-size:1.25rem; }
.cta p{ margin:0 0 1.1rem; }

/* ---------- footnotes ---------- */
.refs{ font-size:.9rem; opacity:.8; }
.refs li{ margin:.3rem 0; }

/* ============================================================
   Persian
   ------------------------------------------------------------
   Only <main> turns around. The site header and the footer keep their
   left-to-right layout in both languages, so the logo, the nav, the
   language switch and the theme button never move between EN and FA.

   Three problems, kept apart below:
     1. type      — Persian needs its own faces, more leading, and none
                    of the tracking tricks the Latin design leans on
     2. direction — everything the Latin layout pins to the left
     3. bidi      — Latin islands inside Persian sentences
   ============================================================ */

html.lang-fa main{ direction:rtl; }

/* The header keeps its place, but the nav has to read the right way round and
   drop the Latin tracking — .08em of letter-spacing breaks the cursive join,
   so "آزمایشگاه" was coming apart into two pieces. */
html.lang-fa .nav{ direction:rtl; }
html.lang-fa .nav a{
  font-family:var(--font-fa-display);
  letter-spacing:0; text-transform:none; font-size:.9rem;
}
html.lang-fa .footer{ font-family:var(--font-fa-text); }
html.lang-fa .footer .mono-label{ font-family:var(--font-mono); }

/* ---------- 1. type ---------- */
:root{
  --font-fa-text:"Shabnam","Vazirmatn","Segoe UI",Tahoma,sans-serif;
  --font-fa-display:"Estedad","Shabnam","Segoe UI",Tahoma,sans-serif;
}
html.lang-fa main{
  font-family:var(--font-fa-text);
  /* Shabnam's x-height runs small next to Space Grotesk, and Persian has no
     capitals to carry a line, so the same px size reads smaller */
  font-size:17.5px;
  /* Persian drops far below the baseline; the Latin 1.65 puts one line's
     descenders into the next line's dots */
  line-height:1.95;
}
html.lang-fa main h1,
html.lang-fa main h2,
html.lang-fa main h3,
html.lang-fa .post-sub,
html.lang-fa .pull{ font-family:var(--font-fa-display); }

/* Latin display faces are tracked tight. Persian must not be. */
html.lang-fa main h1,
html.lang-fa main h2,
html.lang-fa main h3{ letter-spacing:0; }
html.lang-fa .post-hero h1{
  max-width:19ch; line-height:1.35; font-weight:800;
  text-wrap:balance;                /* Persian words are long; even the lines out */
}
html.lang-fa .post h2{ line-height:1.5; font-weight:800; }
html.lang-fa .post h3{ font-weight:700; }

/* A monospace family has no Persian glyphs, so every label styled as "mono"
   was falling back to whatever the system had, at a tracking that breaks the
   cursive join. Persian keeps the page face and drops the tracking; the
   uppercase does nothing for Persian and only shouted the Latin inside it. */
html.lang-fa main .mono-label,
html.lang-fa main .pill,
html.lang-fa main .share-btn,
html.lang-fa main .check-row label,
html.lang-fa main .audio-hint,
html.lang-fa main .verdict,
html.lang-fa main .btn,
html.lang-fa main details.decode > summary,
html.lang-fa main .backlink{
  font-family:var(--font-fa-display);
  letter-spacing:0;
  text-transform:none;
  font-weight:500;
}
/* numbers, units and identifiers stay in the mono face */
html.lang-fa main .secnum,
html.lang-fa main .ctl-val,
html.lang-fa main .ro dd,
html.lang-fa main .eq,
html.lang-fa main .q{ font-family:var(--font-mono); letter-spacing:0; }
/* A readout value is usually a bare quantity, but two carry a note beside it —
   "8 (should be ≫ 1)". The mono face covers the Arabic block without shaping
   it, so the browser never falls through and the note came apart letter by
   letter. The note is its own span, and in Persian it takes the text face. */
html.lang-fa main .ro dd .want{ font-family:var(--font-fa-text); }
html.lang-fa main .ro dt{ font-family:var(--font-fa-text); letter-spacing:0; }

html.lang-fa .post p,
html.lang-fa .post li,
html.lang-fa .post-sub,
html.lang-fa .decode-body p,
html.lang-fa .cta p{ line-height:1.95; }
html.lang-fa figcaption,
html.lang-fa .note,
html.lang-fa .verdict,
html.lang-fa .refs li{ line-height:1.85; }

/* italic is not a Persian distinction — it only slants the face badly */
html.lang-fa main em{ font-style:normal; font-weight:500; }
html.lang-fa main em{ color:color-mix(in srgb, var(--fg) 74%, var(--sig)); }
html.lang-fa main strong,
html.lang-fa main b{ font-weight:700; }

/* ---------- 2. direction ---------- */
html.lang-fa #prog{ transform-origin:100% 50%; }

html.lang-fa .toc ol{ padding-left:0; padding-right:1.2rem; list-style-type:persian; }
html.lang-fa .post ul,
html.lang-fa .post ol{ padding-left:0; padding-right:1.2rem; }
html.lang-fa .pull{
  padding:.2rem 1.3rem .2rem 0;
  border-left:0; border-right:3px solid var(--sig);
}
html.lang-fa .note{
  border-left:0;
  border-right:3px solid color-mix(in srgb, var(--fg) 35%, transparent);
}
html.lang-fa .verdict{
  border-left:0; border-right:3px solid color-mix(in srgb, var(--fg) 35%, transparent);
}
html.lang-fa .verdict.good{ border-right-color:var(--sig); }
html.lang-fa .verdict.bad{ border-right-color:#C8452F; }
html.ink.lang-fa .verdict.bad{ border-right-color:#E8705A; }
/* Readout values are quantities: "14,706 ×", "0.30 Ac", "40 : 1". Under
   plaintext the leading digit is not a strong character, so they inherited the
   paragraph's RTL and the trailing sign jumped to the front. They are islands. */
html.lang-fa .ro dd{ text-align:left; direction:ltr; unicode-bidi:isolate; }
html.lang-fa .tbl th,
html.lang-fa .tbl td{ text-align:right; }
html.lang-fa .share-label{ margin-right:0; margin-left:.15rem; }
html.lang-fa .lede-chart figcaption,
html.lang-fa .eq{ text-align:center; }
/* a slider is a physical axis — left is always less */
html.lang-fa input[type=range].slider{ direction:ltr; }

/* ---------- 3. bidi ---------- */
/* A quantity is an isolated left-to-right island, so the Persian full stop
   after "10 kHz" can never end up inside it. */
.q{
  unicode-bidi:isolate;
  direction:ltr;
  font-variant-numeric:tabular-nums;
  white-space:nowrap;
}

/* Everything the figures write at run time is a mixed string the stylesheet
   never sees: "40 : 1", "0.30 Ac", "1000 kHz", "۳۳٫۳٪". Dropped into an RTL
   box, "40 : 1" comes out as "1 : 40" — the two number runs get laid out right
   to left around the neutral colon. plaintext takes the direction from each
   value's own first strong character, which is right for the Latin ones and
   right for the Persian ones, and cannot go wrong as the figures update. */
html.lang-fa main .pill,
html.lang-fa main .ro dt,
html.lang-fa main .ctl-val,
html.lang-fa main .check-row label,
html.lang-fa main .mono-label,
html.lang-fa main .fig-head,
html.lang-fa main .byline,
html.lang-fa main .eq{ unicode-bidi:plaintext; }

/* ---------- language switch ----------
   Matches .theme-btn next to it: same 34px height, same border and radius, so
   the two controls read as one pair. The active language fills solid, because
   with a tinted style the on and off states were nearly the same colour. */
.lang-switch{
  display:inline-flex; align-items:stretch;
  height:34px; flex:none;
  border:1.5px solid var(--fg);
  border-radius:6px; overflow:hidden;
}
.lang-btn{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:2.3rem;
  font-family:var(--font-mono); font-size:.74rem; letter-spacing:.05em;
  font-weight:600; padding:0 .65rem;
  border:0; background:none; color:var(--fg);
  cursor:pointer; opacity:.55;
  transition:background-color .15s ease, color .15s ease, opacity .15s ease;
}
.lang-btn + .lang-btn{ border-left:1.5px solid var(--fg); }
.lang-btn:hover{ opacity:1; color:var(--sig); }
.lang-btn.on{ opacity:1; background:var(--sig); color:var(--paper); }
.lang-btn:focus-visible{ outline:2px solid var(--sig); outline-offset:2px; }
@media (max-width:560px){ .lang-switch{ order:3; } }

/* ============================================================
   Phones
   ------------------------------------------------------------
   Two separate problems, and they want different answers:
   width (the figures need every pixel of it) and touch (the
   controls need to be big enough to hit).
   ============================================================ */

/* ---- width: claw back the padding the figures were losing ---- */
@media (max-width:640px){
  figure.fig{
    margin:1.6rem 0 2rem;
    padding:.85rem .7rem 1rem;
    border-radius:5px;
  }
  .fig-head{ margin-bottom:.6rem; }
  .fig-head .fig-t{ font-size:.68rem; }        /* the title wraps rather than clips */
  figure.fig figcaption{ font-size:.88rem; line-height:1.6; }
  .fig-split{ gap:.9rem; }
  .ro{ font-size:.78rem; }
  .toc, .cta{ padding:1rem 1.1rem; }
  .eq{ padding:.8rem .6rem; font-size:.92rem; }
  .post h2{ font-size:1.35rem; gap:.5rem; }
  .pull{ font-size:1.05rem; padding-left:1rem; }
}

/* ---- touch: anything you tap gets a 44 px-tall target ---- */
@media (pointer:coarse){
  .pill, .share-btn{
    min-height:38px; padding:.5rem .75rem; font-size:.74rem;
  }
  .chip-row{ gap:.5rem; }
  .check-row label{ min-height:38px; }
  .check-row input{ width:20px; height:20px; }
  details.decode > summary{ padding:.85rem .9rem; }
  /* a 16 px thumb is a small target for a fingertip, and the track it rides
     is thin enough to be hard to find at all */
  input[type=range].slider{ height:38px; }
  input[type=range].slider::-webkit-slider-runnable-track{ height:5px; }
  input[type=range].slider::-moz-range-track{ height:5px; }
  input[type=range].slider::-webkit-slider-thumb{
    width:24px; height:24px; margin-top:-9.5px;
  }
  input[type=range].slider::-moz-range-thumb{ width:24px; height:24px; }
  .ctl{ margin-bottom:1.1rem; }
}
