/* The Lab (lab.html, lab/*.html): Denis's fruit-fly robot, told as episodes. It loads the landing's style.css first,
   so the type (Grandstander + Be Vietnam Pro), the filament colours, the pills, buttons and rounded frames are the
   landing's own; this file only adds the reading layout.
   The reading rules come from docs/lab/RESEARCH-lab-presentation.md (Bartosz Ciechanowski, Distill, Tufte CSS,
   Butterick, Quanta, Our World in Data, Datawrapper, The Pudding, Hackaday, Adafruit): one column of about 67
   characters, body 17→19px, pictures that may run wider with captions kept to the text column, a label on every
   picture saying what it is, charts drawn in HTML so phones can read them, notes in the margin on wide screens,
   and the series shown at the top and bottom of every episode. */

:root{
  --body:clamp(1.0625rem,.99rem + .3vw,1.1875rem);   /* 17px on phones → 19px on desktop */
  --lab-small:.9375rem;
  --lab-label:.75rem;
  --lab-h2:clamp(1.5rem,1.2rem + 1.2vw,2.125rem);
  --lab-space:clamp(28px,3vw,40px);
  --measure:calc(33 * var(--body));                   /* ≈ 67 characters a line */
}

.lab-page{font-size:var(--body);line-height:1.62}
.lab-page .header{justify-content:space-between;padding-inline:0}
.lab-page :is(h1,h2,h3){text-wrap:pretty}
.lab-page .eyebrow{max-width:100%;font-size:var(--lab-label);letter-spacing:.07em;line-height:1.5}
.lab-page main a:not(.episode):not(.button):not(.prev):not(.next){text-decoration-skip-ink:auto}
.lab-tag{display:inline-flex;align-items:center;min-height:44px;padding:0 16px;border-radius:999px;font-size:14px;font-weight:600;background:var(--misty)}
@media(hover:hover) and (pointer:fine){a.lab-tag:hover{background:#cddde7}}

/* ---- the Lab's front page ---- */
.lab-hero{padding-block:clamp(28px,4vw,56px) var(--section)}
.lab-hero .eyebrow{background:var(--orange);border-color:var(--orange)}
.lab-hero h1{margin-top:18px;max-width:16em;font-size:clamp(2.5rem,1.375rem + 4.2vw,4.75rem);line-height:1.06;letter-spacing:-.025em}
@media(max-width:480px){.lab-hero h1{font-size:clamp(2rem,9.4vw,2.5rem)}}
/* the fly in the headline: drawn in the site's ink, Misty Blue wings and Lite Orange eyes; it hovers a little */
.fly-icon{display:inline-block;width:.78em;height:.74em;margin:0 .02em;vertical-align:-.06em;transform:rotate(14deg);animation:fly-hover 3.2s ease-in-out infinite}
@keyframes fly-hover{0%,100%{transform:rotate(14deg) translateY(0)}50%{transform:rotate(8deg) translateY(-.06em)}}
@media (prefers-reduced-motion:reduce){.fly-icon{animation:none}}
.fly-word{font-style:normal;white-space:nowrap}   /* the fly stays with “fly’s” when the line wraps */
.lab-lede{margin-top:clamp(22px,2.4vw,32px);max-width:var(--measure)}
/* three levels under the headline: the lead (the hook, bigger and medium), then the body (the explanation) */
.lab-lede .lead{max-width:28em;font-size:clamp(1.25rem,1.02rem + .75vw,1.5rem);line-height:1.45;font-weight:500;letter-spacing:-.012em}
.lab-lede .body{margin-top:1em;font-size:var(--body);line-height:1.62;color:var(--ink)}
.lab-cover{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(12px,1.6vw,20px);margin-top:clamp(24px,3vw,40px)}   /* from above and from below */
@media(max-width:700px){.lab-cover{grid-template-columns:minmax(0,1fr)}}
.lab-cover .frame{aspect-ratio:3/2;border-radius:var(--r-tile)}
.lab-cover img{width:100%;height:100%;object-fit:cover}
.lab-cover figcaption{max-width:36em}

.episodes-head{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:8px 20px;margin-bottom:clamp(18px,2vw,26px)}
.episodes-head h2{font-size:var(--lab-h2);line-height:1.18}
.episodes-head p{color:var(--muted);font-size:15px}
.episodes{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
.episodes>li{display:flex}
.episodes>li>.episode{flex:1}   /* cards in a row share a height */
@media(max-width:900px){.episodes{grid-template-columns:minmax(0,1fr)}}
.episode{display:grid;grid-template-columns:auto minmax(0,1fr);gap:10px 16px;align-items:start;padding:clamp(20px,2vw,28px);border-radius:var(--r-tile);background:rgba(255,255,255,.62)}
.episode .n{grid-row:span 3;display:grid;place-items:center;width:40px;height:40px;border-radius:50%;background:var(--ink);color:var(--paper);font-family:var(--display);font-weight:800;font-size:18px}
.episode h3{font-size:clamp(20px,1.7vw,24px);font-weight:700;line-height:1.25}
.episode .hook{font-size:16px;line-height:1.55}
.episode .when{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;font-size:14px;color:var(--muted)}
.episode:not(.upcoming) .when{display:grid;grid-template-columns:minmax(0,1fr) auto}
.episode .when .kind{grid-column:1/-1;justify-self:start;margin:0}
.episode .date{white-space:nowrap}
.episode .read{margin-left:auto}
.episode.upcoming{background:transparent;border:1.5px dashed rgba(27,30,38,.22)}
.episode.upcoming .n{background:rgba(27,30,38,.14);color:var(--ink)}
.episode.upcoming .when::after{content:"coming soon";font-size:13px}
a.episode{transition:background .18s,transform .18s}
@media(hover:hover) and (pointer:fine){a.episode:hover{background:#fff;transform:translateY(-2px)}}
a.episode .read{font-size:14px;font-weight:600;text-decoration:underline;text-underline-offset:4px;text-decoration-color:var(--orange);text-decoration-thickness:2px}

.lab-about{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(20px,4vw,64px);align-items:start}
@media(max-width:900px){.lab-about{grid-template-columns:minmax(0,1fr);gap:var(--block)}}
.lab-about{padding-block:var(--section)}
.lab-about h2{font-size:var(--lab-h2);line-height:1.18;margin-bottom:18px}
.lab-about p{max-width:34em}
.lab-about p+p{margin-top:1em}
.lab-about a{text-decoration:underline;text-underline-offset:4px;text-decoration-color:var(--orange);text-decoration-thickness:2px}

/* ---- an episode ---- */
.article{padding-block:clamp(28px,4vw,56px) var(--section);font-size:var(--body);line-height:1.62}
.article>*{margin-inline:auto}   /* one centred reading column; pictures may run wider than the text */
/* Each annotated paragraph reserves its note’s height; wide figures need no float-clearing trick. */
.article-head,.prose,.article-end,.honest,.credits,.series,.course{max-width:var(--measure)}
.article-head .eyebrow{display:block;width:fit-content;padding:0;border:0;border-radius:0;background:none;color:var(--muted);text-wrap:pretty}
.article-head h1{margin-top:18px;max-width:14em;font-size:clamp(2.25rem,1.5rem + 3.2vw,4rem);line-height:1.08;letter-spacing:-.025em}
.dek{margin-top:clamp(14px,1.6vw,22px);max-width:26em;font-size:clamp(1.1875rem,1.02rem + .75vw,1.5rem);line-height:1.45;font-weight:500}
.byline{margin-top:20px;font-size:var(--lab-small);color:var(--muted)}
/* what kind of episode this is: simulation only, real hardware, or both */
.status{margin-top:8px;font-size:var(--lab-small);line-height:1.55;color:var(--muted)}
.status .kind{margin-right:.4em}
.prose{margin-top:var(--lab-space)}
.prose>*+*{margin-top:1em}
.prose h2{margin-top:var(--block);font-size:var(--lab-h2);line-height:1.18}
.prose h2:first-child{margin-top:0}
.prose li p+p{margin-top:.8em}
.prose h2+*{margin-top:.7em}
.prose ul{padding-left:1.2em}
.prose li+li{margin-top:1em}
.prose li::marker{color:var(--orange)}
.prose strong{font-weight:600}
.prose a:not(.button):not(.text-button){text-decoration:underline;text-underline-offset:4px;text-decoration-color:var(--orange);text-decoration-thickness:2px}
/* the lesson box carries a label, like the honesty box */
.prose .lesson{margin-block:var(--lab-space);padding:20px 24px;border-radius:var(--r-tile);background:var(--peach);font-weight:500}
.prose .lesson::before{content:"Lesson";display:block;margin-bottom:2px;font-size:.75rem;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
/* a quote someone actually sent: Grandstander, with who and when underneath (the pages have no italic font) */
.saying{margin:var(--lab-space) 0;padding-left:20px;border-left:3px solid var(--orange)}
.saying p{font-family:var(--display);font-weight:700;font-size:clamp(1.375rem,1.1rem + 1.1vw,1.875rem);line-height:1.3}
.saying footer{margin-top:12px;line-height:1.6;font-size:.75rem;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}

/* Notes sit after their paragraph on narrow screens. At 1240px the 627px reading column,
   32px gap and 208px note fit with at least 65px to the viewport edge. The grid row reserves
   the taller of the paragraph and note, so following prose, figures and the bench cannot collide. */
.annotated{display:grid;grid-template-columns:minmax(0,1fr);gap:16px}
.note{margin:0;padding:16px 20px;border-radius:var(--r-photo);background:var(--misty);font-size:var(--lab-small);line-height:1.55;color:var(--ink);font-weight:400}
.note b{display:block;margin-bottom:5px;font-size:var(--lab-label);font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
@media(min-width:1240px){
  .annotated{width:calc(100% + 15rem);grid-template-columns:minmax(0,1fr) 13rem;gap:2rem;align-items:start}
  .note{padding:4px 0 4px 16px;border-left:2px solid var(--orange);border-radius:0;background:none;color:var(--muted)}
}

/* pictures: text width by default, a middle width for charts and landscapes, a wide one for renders and pairs */
.fig{width:min(var(--measure),100%);margin-block:var(--lab-space)}
.fig.mid{width:min(50rem,100%)}
.fig.wide{width:min(64rem,100%)}
.fig.narrow{width:min(26rem,100%)}
.fig img{width:100%;height:auto;border-radius:var(--r-photo);background:#e4e4df}
.fig.dark img{background:#0b1220}
/* captions: short, muted, never wider than the text, and lined up with the text column under wider pictures */
figcaption{max-width:var(--measure);margin-top:14px;font-size:var(--lab-small);line-height:1.55;color:var(--muted)}
.fig:is(.mid,.wide) figcaption{margin-left:max(0px,(100% - var(--measure)) / 2)}
/* what the picture is, before anything else: real, simulation, render, chart */
.kind{display:inline-block;max-width:100%;margin:0 .5em .25em 0;padding:2px 9px;border-radius:999px;font-size:.75rem;font-weight:600;line-height:1.5;letter-spacing:.06em;text-transform:uppercase;color:var(--ink);vertical-align:.08em}
.kind.real{background:var(--peach)}
.kind.sim{background:var(--misty)}
.kind.render{background:var(--ocean)}
.kind.data{background:#fff;box-shadow:inset 0 0 0 1.5px var(--line)}
.source{display:block;margin-top:8px;font-size:.875rem;line-height:1.55}
figcaption>.kind{display:table;width:fit-content;margin:0 0 8px}
figcaption>.kind.data{display:block}
.source a{text-decoration:underline;text-underline-offset:3px}
figcaption a{text-decoration:underline;text-underline-offset:3px;text-decoration-color:rgba(242,97,31,.6)}
.pair{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(24px,2.4vw,32px);align-items:start;width:min(64rem,100%);margin-block:var(--lab-space)}
.pair .fig{width:100%;margin:0}
.pair figcaption{margin-left:0}
.pair-photos img{aspect-ratio:4/3;object-fit:contain;background:#edece7}
@media(max-width:640px){.pair{grid-template-columns:minmax(0,1fr)}}

/* clips: plain <video>, muted, with controls; a portrait phone clip stays phone-sized */
.clip video{display:block;width:100%;height:auto;border-radius:var(--r-photo);background:#111}
.clip.portrait{width:min(18rem,100%);margin-inline:auto}
.lead-clip{display:grid;grid-template-columns:minmax(0,18rem) minmax(0,1fr);gap:clamp(28px,4vw,56px);align-items:center;max-width:50rem;margin-top:var(--lab-space)}
.lead-clip .clip{margin-block:0}
.lead-clip .prose{margin-top:0}
@media(max-width:760px){.lead-clip{grid-template-columns:minmax(0,1fr)}}

/* charts in HTML: a title that states the finding, then bars with text you can read on a phone */
.chart{width:min(var(--measure),100%);font-size:var(--lab-small);margin-block:var(--lab-space);padding:clamp(16px,2vw,24px);border-radius:var(--r-tile);background:#fff;border:1.5px solid var(--line)}
.chart-title{font-family:var(--font);font-size:clamp(1.0625rem,1rem + .3vw,1.25rem);font-weight:600;line-height:1.35}
.chart .scale{margin-top:8px;font-size:.875rem;line-height:1.55;color:var(--muted)}
.chart figcaption{margin-top:14px}
.bars{display:grid;gap:10px;margin-top:14px}
.bars h4{margin:12px 0 2px;font-size:.75rem;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.bar-row{display:grid;grid-template-columns:minmax(7em,10em) minmax(0,1fr) 4.5em;gap:12px;align-items:center;font-size:.9375rem;line-height:1.45}
@media(max-width:600px){
  .bar-row{grid-template-columns:minmax(0,1fr) auto;gap:8px 12px}
  .bar-row .bar-track{grid-column:1/-1;grid-row:2}
  .bar-row b{grid-column:2;grid-row:1}
  .bars{gap:18px}
}
.bar-track{position:relative;height:14px;border-radius:99px;background:rgba(27,30,38,.08)}
.bar-track i{position:absolute;top:0;bottom:0;left:0;border-radius:99px;background:var(--orange)}
.bar-track i.ink{background:var(--ink)}
.bar-track.centre::before{content:"";position:absolute;left:50%;top:-4px;bottom:-4px;width:1.5px;background:rgba(27,30,38,.35)}
.bar-track.centre i.left{left:auto;right:50%}
.bar-track.centre i.right{left:50%;background:var(--ink)}
.bar-row b{font-weight:600;text-align:right;font-variant-numeric:tabular-nums}
/* which map covers which part of the fly (episode 1) */
.maps{display:grid;grid-template-columns:minmax(6.5em,9em) repeat(5,minmax(0,1fr));gap:6px;margin-top:14px;font-size:.875rem;align-items:center}
.maps .h{font-weight:600;text-align:center;color:var(--muted);font-size:.8125rem}
.maps .row{font-weight:600;line-height:1.25}
.maps .row small{display:block;font-size:.8125rem;font-weight:400;color:var(--muted)}
.maps i{height:26px;border-radius:6px;background:rgba(27,30,38,.07)}
.maps i.on{background:#2f6fb5}
.maps i.all{background:#2e7d5b}
@media(max-width:480px){.maps{grid-template-columns:minmax(6em,7em) repeat(5,minmax(0,1fr));gap:6px 4px;font-size:.875rem}.maps .h{font-size:.75rem;writing-mode:vertical-rl;transform:rotate(180deg);justify-self:center;height:4.6em}}

/* "What the wiring decides": the lab's honest-label rule, on every episode */
.honest{margin-top:0;padding:clamp(20px,2.4vw,30px);border-radius:var(--r-tile);background:var(--misty)}
.honest h2{font-size:clamp(22px,1.8vw,26px);line-height:1.25}
.honest dd{font-size:clamp(16px,1.35vw,18px);line-height:1.6}
.honest dl{display:grid;grid-template-columns:minmax(0,1fr);gap:20px;margin:24px 0 0}
.honest dt{font-size:12px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.honest dd{margin:2px 0 0}
.credits{margin-top:24px;font-size:var(--lab-small);line-height:1.6;color:var(--muted)}
.credits b{display:block;margin-bottom:8px;font-weight:600;color:var(--ink)}
.article-end{margin-top:var(--section)}
.article-end .course{margin-top:var(--lab-space)}
.article-end .series{margin-top:var(--lab-space);padding-top:var(--lab-space);border-top:1px solid var(--line)}
.credits a,.honest a{text-decoration:underline;text-underline-offset:3px;text-decoration-color:rgba(242,97,31,.6)}

/* the course queue: Vibe Hardware, Voice to Bench */
.course{margin-top:clamp(36px,4vw,56px);padding:clamp(20px,2.6vw,32px);border-radius:var(--r-tile);background:var(--peach)}
.course .eyebrow{width:fit-content;margin:0;padding:0;border:0;border-radius:0;background:none;color:var(--muted)}
.course h2{margin-top:12px;font-size:var(--lab-h2);line-height:1.18}
.course h2 .accent{color:var(--orange-deep)}
.course p{max-width:34em}
.course-copy{margin-top:20px;font-size:clamp(16px,1.35vw,18px);line-height:1.6}
.course-copy p+p{margin-top:.8em}
.course-copy .course-hook{font-weight:500}
.queue{display:flex;flex-wrap:wrap;gap:12px;margin-top:24px}
.queue label{flex-basis:100%;font-size:var(--lab-small);line-height:1.55;font-weight:500}
.queue input[name=contact]{flex:1 1 14em;min-width:0;min-height:52px;padding:0 20px;border:1.5px solid var(--ink);border-radius:999px;background:#fff;color:var(--ink);caret-color:var(--orange);font:inherit;font-size:1rem}   /* by name, not type: it lost its style when the field became type=email */
.queue input[name=contact]::placeholder{color:var(--muted)}
.queue input[name=contact]:focus-visible{outline:2.5px solid var(--ink);outline-offset:2px}
.queue .button{min-height:52px}
.queue .trap{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.queue-msg{flex-basis:100%;font-size:var(--lab-small)}
.queue-msg:empty{display:none}
@media(max-width:600px){.queue input[name=contact],.queue .button{flex-basis:100%;width:100%}.queue .button{justify-content:space-between}}
.queue-msg.bad{color:var(--orange-deep)}
.queue-msg.good{display:flex;align-items:center;gap:10px;font-weight:600;color:#1f7a3a}
.queue-msg.good::before{content:"";flex:none;width:26px;height:26px;border-radius:50%;background:#1f7a3a url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 12.5l4 4 8-9' fill='none' stroke='white' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/18px no-repeat}
.lab-hero .course{margin-top:clamp(24px,3vw,36px);max-width:44rem}

/* the series: where this episode sits, the ones either side, and a strip of all ten */
.series{margin-top:clamp(36px,4vw,56px)}
.series .pn{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
@media(max-width:640px){.series .pn{grid-template-columns:minmax(0,1fr)}}
.series .pn a,.series .pn span.none{display:block;padding:clamp(16px,2vw,22px);border-radius:var(--r-tile);background:var(--ink);color:var(--paper)}
.series .pn span.none{background:transparent;border:1.5px dashed rgba(27,30,38,.22);color:var(--muted)}
.series .pn a.next{text-align:left}
.series .label{display:block;font-size:.75rem;font-weight:600;letter-spacing:.08em;text-transform:uppercase;opacity:.72}
.series .pn b{display:block;margin-top:10px;font-family:var(--display);font-weight:800;font-size:clamp(1.125rem,1rem + .6vw,1.5rem);line-height:1.2}
.series .pn .hook{display:block;margin-top:12px;font-size:var(--lab-small);line-height:1.55;opacity:.85}
.series .pn :focus-visible{outline-color:var(--orange)}
@media(hover:hover) and (pointer:fine){.series .pn a{transition:transform .18s}.series .pn a:hover{transform:translateY(-2px)}}
.strip{display:grid;grid-template-columns:repeat(10,minmax(44px,1fr));gap:8px;margin-top:24px;padding:0;list-style:none}
.strip li:last-child{grid-column:1/-1;justify-self:start}
@media(max-width:600px){.strip{grid-template-columns:repeat(5,minmax(44px,1fr))}}
.strip li>*{display:grid;place-items:center;width:44px;height:44px;border-radius:50%;font-family:var(--display);font-weight:800;font-size:15px}
.strip a{background:var(--ink);color:var(--paper)}
.strip [aria-current]{background:var(--orange);color:var(--ink)}
.strip .upcoming{border:1.5px dashed rgba(27,30,38,.25);color:var(--muted)}
.strip .all{width:auto;padding:0 14px;border-radius:999px;background:var(--misty);color:var(--ink);font-family:var(--font);font-weight:600;font-size:14px}

.lab-foot{padding-block:24px 32px;border-top:1px solid var(--line);font-size:var(--lab-small);color:var(--muted)}
.lab-foot .wrap{display:flex;flex-wrap:wrap;gap:8px 24px;justify-content:space-between;align-items:center}
.lab-foot a{display:inline-flex;align-items:center;min-height:44px;text-decoration:underline;text-underline-offset:4px}
/* Clone the touch padding onto every wrapped fragment of an inline source link.
   Inline padding enlarges the hit area without changing the paragraph's line spacing. */
:is(.prose,.lab-about,.credits,.honest,figcaption) a{padding-block:13px;box-decoration-break:clone;-webkit-box-decoration-break:clone}

/* a YouTube video behind a cover: nothing loads from YouTube until someone presses play (lab.js) */
.yt{position:relative;display:block;width:100%;aspect-ratio:16/9;padding:0;border:0;border-radius:var(--r-photo);overflow:hidden;background:#111;cursor:pointer}
.yt img{width:100%;height:100%;object-fit:cover;border-radius:0}
.yt-play{position:absolute;left:50%;top:50%;width:68px;height:48px;margin:-24px 0 0 -34px;border-radius:14px;background:var(--orange)}
.yt-play::after{content:"";position:absolute;left:27px;top:14px;border-style:solid;border-width:10px 0 10px 17px;border-color:transparent transparent transparent var(--ink)}
.yt:hover .yt-play,.yt:focus-visible .yt-play{background:var(--orange-deep)}
.yt-frame{display:block;width:100%;aspect-ratio:16/9;border:0;border-radius:var(--r-photo)}

/* "On the bench": the stack from brain to leg, each part with a drawn icon (tools/build-lab.py) */
.stack{width:min(64rem,100%);margin-block:var(--block)}
.stack h2{font-size:var(--lab-h2);line-height:1.18}
.stack-sub{margin-top:6px;color:var(--muted);font-size:.9375rem}
.stack-list{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-top:16px;padding:0;list-style:none;counter-reset:part}
.stack-list li{position:relative;display:grid;grid-template-columns:48px minmax(0,1fr);gap:2px 14px;align-content:start;padding:16px;border-radius:var(--r-tile);background:#fff;border:1.5px solid var(--line);counter-increment:part}
.stack-list li::after{content:counter(part);position:absolute;top:10px;right:14px;font-family:var(--display);font-weight:800;font-size:14px;color:rgba(27,30,38,.25)}
.stack-icon{grid-row:span 2;width:48px;height:48px;fill:none;stroke:var(--ink);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.stack-icon .o{fill:var(--orange);stroke:var(--ink)}
.stack-icon .f{fill:var(--ink);stroke:none}
.stack-icon .stroke-o{stroke:var(--orange);stroke-width:2.6}
.stack-list b{font-size:16px;font-weight:600;line-height:1.4;padding-right:14px}
.stack-list li:first-child{grid-column:1/-1}
.stack-list li:first-child span{max-width:40em}
@media(max-width:1000px){.stack-list{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:600px){.stack-list{grid-template-columns:minmax(0,1fr)}}
.stack-list span{font-size:var(--lab-small);line-height:1.55;color:#3d4049}
.lab-stack{padding-bottom:var(--section)}
.lab-stack .stack{margin-block:0;width:auto}

/* pictures open full screen (lab.js; the dialog itself is styled in style.css, dialog.lightbox) */
main figure img[data-zoomable]{cursor:zoom-in}
main figure img[data-zoomable]:focus-visible{outline:2.5px solid var(--orange);outline-offset:3px}

/* the course card on the Lab's front page: the full width, text on the left, the form on the right */
.lab-course{padding-top:var(--section)}
.lab-course .course{max-width:none;margin-top:0;display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);column-gap:clamp(32px,5vw,80px);align-items:start}
.lab-course .course>:not(form){grid-column:1}
.lab-course .course form{grid-column:2;grid-row:1 / span 3;align-self:center;margin-top:0}
@media(max-width:1000px){.lab-course .course{grid-template-columns:minmax(0,1fr)}.lab-course .course form{grid-column:1;grid-row:auto;margin-top:16px}}

/* Data graphics: HTML labels keep their size while only the trace area scales.
   The original rasters remain in an optional detail view, with actual-size zoom. */
.chart-detail{margin-top:20px;padding-top:8px;border-top:1px solid var(--line)}
.chart-detail summary{min-height:44px;padding:12px 0;cursor:pointer;font-size:var(--lab-small);font-weight:500;line-height:1.5}
.chart-detail img{width:100%;height:auto;background:#fff;border-radius:8px}
.detail-hint{margin-top:10px;font-size:14px;line-height:1.5;color:var(--muted)}
.signal-legend{display:flex;flex-wrap:wrap;gap:8px 18px;margin-top:16px;font-size:14px}
.signal-legend span::before{content:"";display:inline-block;width:20px;height:3px;margin-right:6px;vertical-align:middle;background:var(--ink)}
.signal-legend .knee::before{background:var(--orange-deep)}
.signal-legend .feeding::before{height:12px;background:var(--peach);border:1px solid #c99d82}
.signal-panel{margin-top:24px}
.signal-panel h4{margin:0 0 12px;font-family:var(--font);font-size:15px;font-weight:600;line-height:1.4}
.trace{display:grid;grid-template-columns:38px minmax(0,1fr);gap:6px}
.trace-y{position:relative;height:140px;font-size:12px;font-variant-numeric:tabular-nums;color:var(--muted)}
.trace-y span{position:absolute;right:0;transform:translateY(-50%)}
.trace-plot{min-width:0}
.trace svg{display:block;width:100%;height:140px;overflow:hidden;border:1px solid var(--line)}
.trace .grid-line{stroke:var(--line);stroke-width:1;vector-effect:non-scaling-stroke}
.trace .trace-line{fill:none;stroke:var(--ink);stroke-width:1.2;vector-effect:non-scaling-stroke}
.trace .trace-line.knee{stroke:var(--orange-deep)}
.trace .feeding-band{fill:var(--peach)}
.trace-x{display:flex;justify-content:space-between;gap:8px;margin-top:6px;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.trace-time{margin-top:5px;text-align:center;font-size:13px;color:var(--muted)}

/* The picture viewer also has an actual-size mode for the original scientific charts. */
.lab-page dialog.lightbox .zoom-mode{position:fixed;z-index:3;top:20px;left:20px;min-width:44px;min-height:44px;padding:10px 16px;border:1px solid var(--paper);border-radius:999px;background:var(--ink);color:var(--paper);font-size:15px}
.lab-page dialog.lightbox[open].actual-size{display:block;padding:84px 20px 24px;overflow:auto}
.lab-page dialog.lightbox.actual-size figure{width:max-content;max-width:none;margin:0 auto}
.lab-page dialog.lightbox.actual-size img{width:auto;max-width:none;max-height:none}
.lab-page dialog.lightbox.actual-size figcaption{max-width:min(36em,calc(100vw - 40px))}

/* "The strings" (episode 4): what the wiring decides and what we wrote, as two panels you can't read as one list.
   Each heading is underlined by a highlighter stroke, and each line has a small drawn icon in the bench icons' style. */
.strings{display:grid;gap:14px;margin:18px 0 22px}
@media (min-width:700px){.strings{grid-template-columns:1fr 1fr;align-items:start}}
.string-group{padding:18px 18px 16px;border-radius:var(--r-tile)}
.string-group.wiring{background:var(--ocean)}
.string-group.hand{background:var(--peach)}
.string-group h3{font:800 1.25rem/1.25 var(--display);margin:0 0 12px}
.marker{background:linear-gradient(transparent 58%,var(--hl) 58%, var(--hl) 92%,transparent 92%);padding:0 .15em;margin:0 -.15em;-webkit-box-decoration-break:clone;box-decoration-break:clone}
.wiring .marker{--hl:rgba(31,122,58,.28)}
.hand .marker{--hl:rgba(242,97,31,.45)}
.string-group ul{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.string-group li{display:grid;grid-template-columns:26px 1fr;gap:10px;align-items:start;margin:0;font-size:.95em;line-height:1.5}
.string-group li::before{content:none}
.string-icon{width:26px;height:26px;margin-top:1px;fill:none;stroke:var(--ink);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.string-icon .o{fill:var(--orange);stroke:var(--ink);stroke-width:1.4}
.string-icon .so{stroke:var(--orange);stroke-width:2.2}

/* episode 5: two body drawings in the "strings" panels (a spider-style robot, a fly) */
.bodies .string-group p{margin:10px 0 0;font-size:.95em;line-height:1.5}
.body-sketch{display:block;width:100%;max-width:260px;height:auto;margin:4px auto 0;fill:none;stroke:var(--ink);stroke-width:3;stroke-linecap:round;stroke-linejoin:round}
.body-sketch .o{fill:var(--orange);stroke:var(--ink);stroke-width:2}
.body-sketch .thorax{fill:rgba(31,122,58,.18)}
.body-sketch .dim{stroke-width:2;opacity:.6}
/* a real sequence, numbered in orange (episode 5's six-step plan) */
.prose ol.plan{list-style:none;margin:14px 0 18px;padding:0;counter-reset:step;display:grid;gap:8px}
.prose ol.plan li{counter-increment:step;display:grid;grid-template-columns:30px 1fr;gap:10px;align-items:baseline;margin:0}
.prose ol.plan li::before{content:counter(step);display:inline-grid;place-items:center;width:26px;height:26px;border-radius:50%;background:var(--orange);color:var(--ink);font:800 .9rem/1 var(--display);transform:translateY(-1px)}

/* episode 6: "two flies", a drawn flow in two lanes; on a phone each lane stacks top to bottom */
.two-flies .lane{display:flex;align-items:center;flex-wrap:wrap;gap:10px;padding:14px 16px;border-radius:var(--r-tile);background:var(--misty)}
.two-flies .lane+.lane{margin-top:10px;background:var(--peach)}
.two-flies .node{padding:8px 14px;border-radius:999px;background:#fff;font-weight:600;font-size:.95em;line-height:1.3}
.two-flies .node.real{background:var(--ink);color:var(--paper)}
.two-flies .arrow{width:28px;height:2px;background:var(--ink);position:relative;flex:none}
.two-flies .arrow::after{content:"";position:absolute;right:-1px;top:-4px;border:5px solid transparent;border-left:7px solid var(--ink);border-right:0}
@media(max-width:520px){.two-flies .lane{flex-direction:column;align-items:flex-start}.two-flies .arrow{width:2px;height:18px;margin-left:22px}.two-flies .arrow::after{right:-4px;top:auto;bottom:-2px;border:5px solid transparent;border-top:7px solid var(--ink);border-bottom:0}}
/* episode 6: the AI's same-wires drawing, redrawn so every label reads on a phone */
.same-wires svg{display:block;width:100%;max-width:520px;height:auto;margin:0 auto;padding:10px 0;background:#fff;border-radius:var(--r-photo);box-shadow:inset 0 0 0 1.5px var(--line)}
.same-wires .plus{stroke:#c0392b;stroke-width:5;stroke-linecap:round}
.same-wires .minus{stroke:var(--ink);stroke-width:5;stroke-linecap:round}
.same-wires .box{fill:#fff;stroke-width:3}
.same-wires .hip{stroke:#2f6db5}.same-wires .knee{stroke:#2c7a55}
.same-wires text{font-family:var(--font);fill:var(--ink)}
.same-wires .rail-l{font-size:15px;font-weight:700;fill:#c0392b}
.same-wires .box-t{font-size:17px;font-weight:700;text-anchor:middle}
.same-wires .box-s{font-size:13px;text-anchor:middle;fill:var(--muted)}
.same-wires .ai-said{margin:14px 0 0;font:700 1.1rem/1.4 var(--display);text-align:center;color:#2c7a55}

.same-wires .rail-m{fill:var(--ink);font-size:20px}

/* episode 7: label vs bench in the two panels (claim peach, fact green) */
.string-group.claim{background:var(--peach)}
.string-group.fact{background:var(--ocean)}
.claim .marker{--hl:rgba(242,97,31,.45)}
.fact .marker{--hl:rgba(31,122,58,.28)}
/* episode 7: said first, then measured */
.predict table{width:100%;margin-top:14px;border-collapse:collapse;font-size:.9375rem;line-height:1.4;font-variant-numeric:tabular-nums}
.predict :is(th,td){padding:10px 8px;text-align:left;vertical-align:top;border-top:1px solid var(--line)}
.predict thead th{border-top:0;padding-top:0;font-size:.75rem;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.predict tbody th{font-weight:500}
.predict td{white-space:nowrap;font-weight:600}
.predict .who{display:block;font-size:.8125rem;font-weight:400;color:var(--muted)}
.predict .miss{--hl:rgba(242,97,31,.45)}
@media(max-width:480px){.predict :is(th,td){padding:9px 5px}}
/* episode 7: the display's dead stroke, and a pulse train drawn to scale */
.segments svg,.pulse svg{display:block;width:100%;max-width:520px;height:auto;margin:0 auto;padding:10px 0;background:#fff;border-radius:var(--r-photo);box-shadow:inset 0 0 0 1.5px var(--line)}
.segments path{fill:none;stroke-width:9;stroke-linecap:round}
.segments .on{stroke:var(--ink)}
.segments .off{stroke:var(--ink);opacity:.07}
.segments .dead{stroke:var(--orange);stroke-width:2.5;stroke-dasharray:4 4}
.segments text,.pulse text{font-family:var(--font);fill:var(--ink)}
.segments .seg-l{font-size:14px;font-weight:600;text-anchor:middle}
.pulse .axis{stroke:var(--line);stroke-width:1.5}
.pulse .wave{fill:none;stroke:var(--ink);stroke-width:2.5;stroke-linejoin:round}
.pulse .avg{stroke:var(--orange);stroke-width:2.5;stroke-dasharray:6 5}
.pulse .span{fill:none;stroke:var(--muted);stroke-width:1.5}
.pulse .p-l{font-size:13px}
.pulse .p-avg{font-size:13px;font-weight:700;fill:var(--orange-deep)}
