/* Tesryn Lab — the all-dark surface, the same one Tesryn Signal uses: void,
   the faint amber plotting grid, mono labels, amber only as an accent.
   Loaded after styles.css, and only on body.lab, so the rest of the site is
   untouched. Classes only: the CSP forbids inline styles. */

/* A card is display:flex, and [hidden] loses to that — every stylesheet here
   carries this line for the same reason. Without it the filters do nothing. */
[hidden]{display:none !important}

body.lab{background:var(--void);color:var(--text)}
body.lab main{
  background-color:var(--void);
  background-image:
    linear-gradient(rgba(255,122,26,.028) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,122,26,.028) 1px,transparent 1px);
  background-size:72px 72px;
}
body.lab main section + section{border-top:1px solid var(--rule)}
body.lab main p{color:var(--muted)}
body.lab main p strong,body.lab main li strong{color:var(--text)}
body.lab main h2,body.lab main h3{color:var(--text)}
body.lab main .section-tag{color:var(--flare)}
body.lab main a{color:var(--flare)}
body.lab main a:hover{color:var(--glow)}
body.lab main .btn-primary{background:var(--grad-hot);color:#0A0B0D}
body.lab main .btn-ghost{border-color:var(--rule);color:var(--text);background:rgba(255,255,255,.03)}
body.lab main .btn-ghost:hover{border-color:var(--flare);color:var(--text)}
body.lab .band{border-top:1px solid var(--rule)}

/* the pinned page menu, on the dark surface */
body.lab .toc{background:rgba(8,9,11,.88);border-bottom:1px solid var(--rule)}
body.lab .toc-label{color:var(--dim)}
body.lab .toc a{color:var(--muted)}
body.lab .toc a:hover{color:var(--text);border-color:var(--rule-lit);background:rgba(255,255,255,.03)}
body.lab .toc a.active{color:var(--flare);border-color:var(--rule-lit);background:rgba(255,122,26,.08)}
.lab-band .lede{max-width:52ch}

/* The way back (the owner, 2026-10-01: "add a back to tesryn link"): Signal's link row opens the Lab in a tab of its
   own, where the browser's Back has nowhere to go, so the page says where Tesryn is itself. */
.lab-back{margin:0 0 1rem}
.lab-back a{display:inline-flex;align-items:center;gap:.45rem;min-height:2.75rem;font:500 .78rem var(--mono);
  letter-spacing:.14em;text-transform:uppercase;color:var(--muted);text-decoration:none}
.lab-back a:hover,.lab-back a:focus-visible{color:var(--text)}

/* ── the shared line art ────────────────────────────────────────────────── */
.glyph{display:block;width:100%;height:auto}
.glyph .g-line{stroke:rgba(237,234,229,.42);stroke-width:2}
.glyph .g-arc{stroke:rgba(255,122,26,.42);stroke-width:1.6}
.glyph .g-arc.a0{stroke:rgba(255,122,26,.58)}
.glyph .g-arc.a1{stroke:rgba(255,122,26,.40)}
.glyph .g-arc.a2{stroke:rgba(255,122,26,.26)}
.glyph .g-arc.a3{stroke:rgba(255,122,26,.16)}
.glyph .g-hot{stroke:var(--flare);stroke-width:2.2}
.glyph .g-ring{stroke:rgba(237,234,229,.18);stroke-width:1.4;stroke-dasharray:4 5}
.glyph .g-dot{fill:var(--glow);stroke:none}
.glyph .g-near{fill:rgba(255,180,84,.75);stroke:none}
.glyph .g-far{fill:rgba(237,234,229,.34);stroke:none}
rect.g-hot,rect.g-line{fill:rgba(255,122,26,.07)}
rect.g-hot{fill:rgba(255,122,26,.16)}
/* The mini animation: the one line that matters draws in, the arcs breathe, the ring turns. Still for anyone who
   asked for less motion, and on paper. */
@media (prefers-reduced-motion:no-preference){
  .glyph .g-hot{stroke-dasharray:240;stroke-dashoffset:240;animation:glyph-draw 1.6s ease-out .2s forwards}
  .glyph .g-arc{animation:glyph-breathe 3.2s ease-in-out infinite}
  .glyph .g-arc.a1{animation-delay:.4s}.glyph .g-arc.a2{animation-delay:.8s}.glyph .g-arc.a3{animation-delay:1.2s}
  .glyph .g-ring{animation:glyph-turn 12s linear infinite}
}
:root[data-motion="reduce"] .glyph .g-hot,:root[data-motion="reduce"] .glyph .g-arc,:root[data-motion="reduce"] .glyph .g-ring{animation:none;stroke-dashoffset:0}
@media print{.glyph .g-hot,.glyph .g-arc,.glyph .g-ring{animation:none;stroke-dashoffset:0}}
@keyframes glyph-draw{to{stroke-dashoffset:0}}
@keyframes glyph-breathe{0%,100%{opacity:.45}50%{opacity:1}}
@keyframes glyph-turn{to{stroke-dashoffset:-90}}

/* ── the hero's three numbers ───────────────────────────────────────────── */
.lab-stats{list-style:none;margin:2.25rem 0 0;padding:0;display:flex;gap:2.75rem;flex-wrap:wrap}
.lab-stats .n{display:block;font-size:2.1rem;font-weight:650;letter-spacing:-.03em;color:var(--text)}
.lab-stats .l{font:500 .72rem var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}

/* ── status pills ───────────────────────────────────────────────────────── */
.pill{display:inline-flex;align-items:center;gap:.45rem;padding:.25rem .7rem;border-radius:999px;
  border:1px solid var(--rule);font:600 .68rem var(--mono);letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted);white-space:nowrap}
.pill::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;flex:none}
.pill-live{color:#6FE39B;border-color:rgba(111,227,155,.35)}
.pill-pilot{color:var(--glow);border-color:var(--rule-lit)}
.pill-prototype{color:var(--flare);border-color:var(--rule-lit)}
.pill-research{color:#8FB8FF;border-color:rgba(143,184,255,.3)}
.pill-internal{color:var(--muted)}

/* ── the catalogue ──────────────────────────────────────────────────────── */
.lab-head{display:flex;justify-content:space-between;align-items:baseline;gap:1.5rem;flex-wrap:wrap}
.lab-chips{display:flex;gap:.45rem;flex-wrap:wrap}
.lab-chip{font:500 .78rem var(--sans);color:var(--muted);background:transparent;cursor:pointer;
  white-space:nowrap;
  border:1px solid var(--rule);border-radius:999px;padding:.34rem .8rem;
  transition:color .16s ease,border-color .16s ease,background .16s ease}
.lab-chip:hover{color:var(--text);border-color:var(--rule-lit)}
.lab-chip.is-on{color:#0A0B0D;background:var(--grad-hot);border-color:transparent;font-weight:650}

/* Three across, level along the bottom, and a last row with fewer in it sits centred rather
   than hanging off the left. */
.lab-grid{display:flex;flex-wrap:wrap;justify-content:center;gap:.9rem;margin-top:1.5rem}
.lab-grid > .lab-card{flex:0 1 calc((100% - 1.8rem) / 3)}
/* the catalogue sits under the four tiles, so it is four wide */
.lab-grid[data-lab-grid] > .lab-card{flex-basis:calc((100% - 2.7rem) / 4)}
@media (max-width:1000px){
  .lab-grid > .lab-card{flex-basis:calc((100% - .9rem) / 2)}
  .lab-grid[data-lab-grid] > .lab-card{flex-basis:calc((100% - .9rem) / 2)}
}
@media (max-width:560px){ .lab-grid > .lab-card,.lab-grid[data-lab-grid] > .lab-card{flex-basis:100%} }
.lab-card{position:relative;display:flex;flex-direction:column;gap:.25rem;overflow:hidden;
  border:1px solid var(--rule);border-radius:14px;padding:1.1rem 1.2rem;background:var(--panel);
  text-decoration:none;color:var(--text);
  transition:border-color .18s ease,transform .18s ease,box-shadow .2s ease,background .18s ease}
.lab-card:hover{border-color:var(--rule-lit);background:var(--panel-2);transform:translateY(-3px);
  box-shadow:0 18px 44px -26px rgba(255,122,26,.9)}
.lab-card::before{content:"";position:absolute;inset:0 0 auto 0;height:1px;
  background:var(--grad-rule);opacity:0;transition:opacity .2s ease}
.lab-card:hover::before{opacity:1}
.lab-art{display:block;padding:.1rem 0 .7rem;max-width:6.5rem}
.lab-card:hover .g-hot{stroke:var(--glow)}
.lab-card:hover .g-dot{fill:#FFF0DC}
.lab-meta{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;margin-bottom:.35rem}
.lab-sector{font:500 .68rem var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}
.lab-card h3{margin:0;font-size:1.12rem;color:var(--text)}
.lab-card p{margin:.2rem 0 .8rem;color:var(--muted);font-size:.92rem;line-height:1.5}
.lab-for{margin-top:auto;display:flex;justify-content:space-between;align-items:baseline;gap:.75rem;
  padding-top:.7rem;border-top:1px solid var(--rule);
  font:500 .68rem var(--mono);letter-spacing:.04em;color:var(--dim);line-height:1.4}
.lab-go{color:var(--flare);font-size:1rem;transition:transform .18s ease}
.lab-card:hover .lab-go{transform:translateX(4px)}
.lab-empty{color:var(--dim);margin-top:2rem}

/* ── a product page ─────────────────────────────────────────────────────── */
.lab-line{display:flex;align-items:center;gap:.85rem;flex-wrap:wrap;margin:0 0 2rem;
  font-size:.86rem;color:var(--muted)}
.lab-line .sep{color:var(--rule-lit)}
.lab-intro{display:grid;grid-template-columns:1.6fr 1fr;gap:3rem;align-items:center}
.lab-summary{font-size:1.16rem;line-height:1.65;color:var(--muted);max-width:60ch}
.lab-figure{border:1px solid var(--rule);border-radius:14px;background:var(--panel);padding:2rem}
.lab-figure .glyph{max-width:20rem;margin:0 auto}

body.lab .card-dark{background:var(--panel);border-color:var(--rule)}
body.lab .card-dark:hover{border-color:var(--rule-lit);background:var(--panel-2)}
body.lab .card-dark p{color:var(--muted)}
.lab-n{font:600 .7rem var(--mono);letter-spacing:.16em;color:var(--flare);display:block;margin-bottom:.8rem}

.lab-rules{display:grid;grid-template-columns:1.3fr 1fr;gap:3rem;align-items:start}
.lab-held{list-style:none;margin:0;padding:0;display:grid;gap:.9rem}
.lab-held li{position:relative;padding-left:1.7rem;color:var(--muted);line-height:1.6}
.lab-held li::before{content:"";position:absolute;left:0;top:.62em;width:10px;height:1px;
  background:var(--flare);box-shadow:0 0 8px rgba(255,122,26,.8)}
.note-dark{border:1px solid var(--rule-lit);border-radius:12px;padding:1.4rem;background:var(--panel);
  border-left:3px solid var(--flare)}
.note-dark p{margin:0;color:var(--muted)}

.lab-near{display:flex;gap:1rem;flex-wrap:wrap;margin-top:2.5rem;padding-top:1.5rem;
  border-top:1px solid var(--rule)}
.lab-near a{display:flex;flex-direction:column;gap:.2rem;flex:1 1 12rem;text-decoration:none;
  border:1px solid var(--rule);border-radius:12px;padding:.9rem 1.1rem;color:var(--text);
  transition:border-color .18s ease,background .18s ease}
.lab-near a:hover{border-color:var(--rule-lit);background:var(--panel)}
.lab-near span{font:500 .68rem var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}

@media (max-width:860px){
  .lab-intro,.lab-rules{grid-template-columns:1fr;gap:2rem}
  .lab-stats{gap:1.75rem}
}
@media (prefers-reduced-motion:reduce){
  .lab-card,.lab-go,.lab-chip,.lab-near a{transition:none}
  .lab-card:hover{transform:none}
}
/* The same, for the person's own choice (design/prefs.js writes data-motion on <html>). */
:root[data-motion="reduce"] .lab-card, :root[data-motion="reduce"] .lab-go, :root[data-motion="reduce"] .lab-chip, :root[data-motion="reduce"] .lab-near a{transition:none}
:root[data-motion="reduce"] .lab-card:hover{transform:none}



/* ── not built yet: said the same way everywhere it appears ─────────────── */
.pill-soon{color:var(--glow);border-color:var(--rule-lit)}
.pill-pending{color:var(--dim);border-color:var(--rule)}
.pill-soon::before,.pill-pending::before{background:transparent;border:1px solid currentColor}
.lab-card-soon{background:transparent;border-style:dashed}
.lab-card-soon .lab-art{opacity:.72}
.lab-card-soon:hover{background:var(--panel)}
.lab-grid-soon{margin-top:2rem}
.lab-flag{margin:0 0 1.6rem;padding:.9rem 1.1rem;max-width:52ch;border-radius:10px;
  border:1px dashed var(--rule-lit);background:rgba(255,122,26,.05);color:var(--muted);font-size:.95rem}
.lab-flag strong{color:var(--glow)}

/* ── the moment a product earns its keep ────────────────────────────────── */
.lab-moment{margin:1.6rem 0 0;padding-left:1.1rem;border-left:2px solid var(--flare);
  color:var(--text);font-size:1.02rem;line-height:1.6;max-width:58ch}
.lab-moment span{display:block;font:600 .68rem var(--mono);letter-spacing:.16em;
  text-transform:uppercase;color:var(--flare);margin-bottom:.45rem}

/* ── if none of these is your problem ───────────────────────────────────── */
.lab-fits .fine{margin-top:1.6rem;color:var(--dim);font-size:.88rem;max-width:56ch}
.lab-chip small{margin-left:.4rem;font-size:.72em;opacity:.7;font-variant-numeric:tabular-nums}
.lab-more{margin-top:1.75rem}

/* ── the estimate page's "closest thing we've built" ────────────────────── */
.lab-est{background:var(--void);color:var(--text);border-top:1px solid var(--rule);
  background-image:
    linear-gradient(rgba(255,122,26,.028) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,122,26,.028) 1px,transparent 1px);
  background-size:72px 72px}
.lab-est h2{color:var(--text)}
.lab-est p{color:var(--muted)}
.lab-est .section-tag{color:var(--flare)}
.lab-est .after-grid{color:var(--dim)}
.lab-est a{color:var(--flare)}
.lab-est a:hover{color:var(--glow)}
.lab-grid-est{margin-top:2rem}

/* ══ the map ═══════════════════════════════════════════════════════════════
   The grouped list is the content; the picture is drawn on top from the same
   file. One colour, like everything else here: depth comes from size, weight
   and how lit a thing is, never from a second hue. */
.lab-map-sec{position:relative}
.lab-map-list{display:grid;gap:2.25rem;grid-template-columns:minmax(0,1fr);margin-top:2.25rem}
@media (min-width:42rem){ .lab-map-list{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (min-width:66rem){ .lab-map-list{grid-template-columns:repeat(3,minmax(0,1fr))} }
.map-group h3{margin:0 0 .3rem;font-size:1.05rem}
.map-blurb{margin:0 0 1rem;color:var(--dim);font-size:.92rem}
.map-skills{margin:0;display:grid;gap:.9rem}
.map-skills dt{display:flex;align-items:baseline;justify-content:space-between;gap:.75rem;
  font-weight:620;color:var(--text);border-top:1px solid var(--rule);padding-top:.65rem}
.map-skills dt span{font:600 .68rem var(--mono);color:var(--flare);flex:none}
.map-skills dt.is-lit{color:var(--glow)}
.map-skills dd{margin:.35rem 0 0}
.map-skills dd p{margin:0 0 .3rem;font-size:.92rem;color:var(--muted)}
.map-proof{color:var(--dim) !important;font-size:.85rem !important}
.map-fold{margin-top:2rem;border-top:1px solid var(--rule);padding-top:1rem}
.map-fold > summary{cursor:pointer;color:var(--muted);font:500 .8rem var(--mono);letter-spacing:.14em;
  text-transform:uppercase;list-style:none}
.map-fold > summary::-webkit-details-marker{display:none}
.map-fold > summary::before{content:"+ ";color:var(--flare)}
.map-fold[open] > summary::before{content:"– "}
.map-fold > summary:hover{color:var(--text)}

/* The frame hides nothing: the only things wider than it, the chips' row and (on a phone) one section's picture, each
   scroll inside themselves, so a chip past the edge is scrolled to, never cut off. The bar's tint keeps to the
   rounded corners by its own radius. */
.lab-graph{margin-top:2.25rem;border:1px solid var(--rule);border-radius:16px;background:var(--panel)}
.lab-graph-bar{display:grid;gap:.75rem;padding:.8rem 1rem;border-bottom:1px solid var(--rule);
  border-radius:15px 15px 0 0;background:rgba(255,255,255,.015)}
.lab-graph-bar:empty,.lab-graph-bar:has(> .lab-graph-legend:empty){display:none}
/* one line, always: it scrolls sideways rather than wrapping under itself */
.lab-graph-legend{display:flex;gap:.4rem;flex-wrap:nowrap;overflow-x:auto;min-width:0;
  padding-bottom:.15rem;scrollbar-width:none;-ms-overflow-style:none;
  -webkit-mask-image:linear-gradient(90deg,#000 96%,transparent);
          mask-image:linear-gradient(90deg,#000 96%,transparent)}
.lab-graph-legend::-webkit-scrollbar{display:none}
.lab-graph-legend .lab-chip{flex:none}
.lab-graph-legend:empty{display:none}          /* a product page has no sections bar */
/* one row: what you can do on the left, the way back on the right, both on the same line */
/* "The whole map" leads the row, with a hairline between it and the sections */
.graph-key-all{position:relative;margin-right:.55rem;font-weight:600}
.graph-key-all::after{content:"";position:absolute;right:-.3rem;top:15%;bottom:15%;
  width:1px;background:var(--rule)}
.graph-key-all.is-on{color:#0A0B0D;background:var(--grad-hot);border-color:transparent}
.graph-key-all.is-on::after{background:transparent}
.lab-graph-stage{padding:.6rem .4rem}
.lab-graph-read{margin:0;max-width:none;padding:.75rem 1rem;border-top:1px solid var(--rule);color:var(--muted);
  font-size:.88rem;min-height:2.9rem}
.graph{display:block;width:100%;height:auto}

/* the sections, as chips that open one */
.graph-key{display:inline-flex;align-items:center;gap:.5rem}
.graph-key small{font:600 .66rem var(--mono);color:var(--flare);opacity:.85}
.graph-key.is-on{color:#0A0B0D;background:var(--grad-hot);border-color:transparent;font-weight:650}
.graph-key.is-on small{color:#0A0B0D;opacity:.7}

/* lines: the spokes hold the shape, the crossings are the interesting part */
.graph-link{fill:none;stroke:var(--flare)}
.graph-link.k-spoke{stroke:rgba(255,122,26,.30);stroke-width:1.2}
.graph-link.k-cross{stroke:rgba(255,180,84,.16)}
.graph-link.k-proof{stroke:rgba(255,122,26,.26);stroke-width:1.1}

/* nodes: the middle is solid, a section is filled, a skill is a ring, a product is hollow */
.graph-node{cursor:pointer}
.graph-node .nd{stroke:#08090B;stroke-width:1.5}
.graph-node.n-hub .nd{fill:var(--flare);stroke:none}
.graph-node.n-group .nd{fill:rgba(255,122,26,.85);stroke:#08090B;stroke-width:2}
.graph-node.n-skill .nd{fill:rgba(255,122,26,.18);stroke:var(--flare);stroke-width:2}
.graph-node.n-product .nd{fill:#0E1014;stroke:rgba(237,234,229,.5);stroke-width:1.6}
.graph-node.n-soon .nd{stroke-dasharray:3 3}
.graph-node .nd-halo{fill:none;stroke:rgba(255,122,26,.35);stroke-width:1}
.graph-node.n-hub .nd-halo{stroke:rgba(255,180,84,.5)}

.nl-plate{fill:#101217;opacity:.82}
.graph-node.n-quiet .nl-plate{opacity:0}
.graph-node.n-quiet:hover .nl-plate,.graph-node.n-quiet:focus-visible .nl-plate,
.graph-node.n-quiet.is-hot .nl-plate,.graph-node.n-quiet.is-near .nl-plate{opacity:.82}
.graph-node .nl{fill:var(--text);font:620 13px var(--sans);paint-order:stroke;
  stroke:#101217;stroke-width:3px;stroke-linejoin:round}
.graph-node.n-product .nl{fill:var(--muted);font:500 11px var(--sans)}
.graph-node .ns{fill:var(--dim);font:500 10.5px var(--mono);letter-spacing:.04em;paint-order:stroke;
  stroke:#101217;stroke-width:3.5px;stroke-linejoin:round}
/* A node the keyboard has reached shows a ring, not only a brighter edge: on the hub and a group the edge is
   the shape's own and the change doesn't read as focus (ui-check: "no outline or ring"). */
.graph-node:focus-visible{outline:2px solid #FFF0DC;outline-offset:3px;border-radius:4px}
.graph-node:focus-visible .nd{stroke:#FFF0DC;stroke-width:3}
.graph-node.n-quiet .nl{opacity:0}
.graph-node.n-quiet:hover .nl,.graph-node.n-quiet:focus-visible .nl,
.graph-node.n-quiet.is-hot .nl,.graph-node.n-quiet.is-near .nl{opacity:1}

/* opening a section: the map stands down, that section takes the floor. One fade each way,
   nothing moving, nothing to chase. */
.graph .graph-nodes,.graph .graph-links,.graph .graph-sparks{transition:opacity .22s ease}
.graph.is-open > .graph-nodes,.graph.is-open > .graph-links,.graph.is-open > .graph-sparks{
  opacity:0;pointer-events:none}
.graph-extra .graph-node,.graph-extra .graph-link,.graph-extra .graph-spark{animation:lab-in .3s ease both}
@keyframes lab-in{from{opacity:0}}
/* Opening a section adds, it does not take away: the rest of the map keeps its colour and its
   crossings, and the section you opened is simply ringed. */
.graph-node.is-shown .nd{stroke:var(--glow);stroke-width:3}
.graph-node.is-shown .nd-halo{stroke:var(--glow);opacity:.75}
.graph-node.is-shown .nl{fill:var(--glow)}
@media (prefers-reduced-motion:reduce){ .graph-extra .graph-node,.graph-extra .graph-link,
  .graph-extra .graph-spark{animation:none} }
/* The same, for the person's own choice (design/prefs.js writes data-motion on <html>). */
:root[data-motion="reduce"] .graph-extra .graph-node, :root[data-motion="reduce"] .graph-extra .graph-link, :root[data-motion="reduce"] .graph-extra .graph-spark{animation:none} 


/* following one thing: everything else steps back */
.graph.is-focused .graph-node{opacity:.45}
.graph.is-focused .graph-node.is-near,.graph.is-focused .graph-node.is-hot{opacity:1}
.graph.is-focused .graph-link{opacity:.18}
.graph.is-focused .graph-link.is-near{opacity:1;stroke:var(--glow);stroke-width:2}
.graph-node.is-hot .nl{fill:var(--glow)}
.graph-node.is-hot .nd{stroke:var(--glow)}
.graph-node.n-hub.is-hot .nd,.graph-node.n-group.is-hot .nd{fill:var(--glow)}

@media (max-width:760px){
  .lab-graph-hint [data-graph-hint]{display:none}   /* the words go, the way back stays */
  .lab-graph-read{min-height:3.6rem}
  /* the whole map fits; one section is wider than a phone, so the stage pans */
  .lab-graph-stage{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .lab-graph.is-inside .graph{min-width:680px}
  .graph-node .nl{font-size:14px}
  .graph-node.n-product .nl{font-size:12px}
}

/* ── print: dark on screen, plain on paper ─────────────────────────────── */
@media print{
  body.lab,body.lab main,body.lab .hero,body.lab .band{background:#fff !important;color:#000}
  body.lab main p,body.lab .lab-summary,body.lab .map-skills dd p{color:#222}
  body.lab .hero h1{color:#000;-webkit-text-fill-color:#000}
  .lab-graph,.lab-chips,.lab-band .actions,.lab-fits .actions,.totop{display:none !important}
  .map-fold,.map-fold[open]{border:0}
  .map-fold > summary{display:none}
  .lab-card{break-inside:avoid;border-color:#ccc;background:#fff;color:#000}
}

/* what a product proves we can do */
.lab-skills-lead{margin:1.6rem 0 .6rem;font:600 .68rem var(--mono);letter-spacing:.16em;
  text-transform:uppercase;color:var(--dim)}
.lab-skills{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:.4rem}
.lab-skills a{display:inline-block;text-decoration:none;border-radius:999px;padding:.3rem .75rem;
  font-size:.82rem;color:var(--text) !important;border:1px solid var(--rule);
  background:rgba(255,255,255,.02);transition:border-color .16s ease,background .16s ease}
.lab-skills a::before{content:"";display:inline-block;width:7px;height:7px;margin-right:.5rem;
  border-radius:50%;border:1.5px solid var(--flare);vertical-align:middle}
.lab-skills a:hover{border-color:var(--flare);background:rgba(255,122,26,.08)}

/* a product's own corner of the map, in words underneath the picture */
.lab-near-list{display:grid;gap:1rem;margin-top:2rem}
.lab-near-line{margin:0;max-width:72ch}
.lab-near-line strong{color:var(--text)}
.lab-near-line span{color:var(--muted);display:block;font-size:.92rem}
.lab-near-who{color:var(--dim) !important;font-size:.86rem !important}
.lab-graph-one{margin-top:2rem}

/* ── the current ───────────────────────────────────────────────────────────
   A short bright segment travels each line, under the nodes. It is one CSS
   animation on a normalised path (pathLength=100), eight staggered starts, and
   nothing at all in JavaScript. Off screen the whole layer is paused, and it
   never runs for someone who asked for less motion. */
.graph-spark{fill:none;stroke:var(--glow);stroke-width:2;stroke-linecap:round;
  stroke-dasharray:4 46;stroke-dashoffset:50;opacity:.62;
  animation:lab-current 9s linear infinite}
.graph-spark.s1{animation-delay:-1.6s}
.graph-spark.s2{animation-delay:-3.2s}
.graph-spark.s3{animation-delay:-4.9s}
.graph-spark.s4{animation-delay:-6.5s}
.graph-spark.s5{animation-delay:-8.1s}
.graph-spark.s6{animation-delay:-9.7s}
.graph-spark.s7{animation-delay:-11.4s}
@keyframes lab-current{to{stroke-dashoffset:0}}   /* one dash length per turn: 50 of 100 */

/* nothing moves while the map is off screen */
.lab-graph.is-still .graph-spark{animation-play-state:paused}

.graph.is-focused .graph-spark{opacity:.08}
.graph.is-focused .graph-spark.is-near{opacity:.9;stroke-width:2.2}

/* a node that does nothing when chosen doesn't pretend otherwise */
.graph-node.n-flat{cursor:default}

@media (prefers-reduced-motion:reduce){
  .graph-spark{animation:none;opacity:.3;stroke-dasharray:none;stroke-dashoffset:0;stroke-width:1}
}
/* The same, for the person's own choice (design/prefs.js writes data-motion on <html>). */
:root[data-motion="reduce"] .graph-spark{animation:none;opacity:.3;stroke-dasharray:none;stroke-dashoffset:0;stroke-width:1}



/* ── the catalogue's menu: choose a kind of work, then see that work ─────── */
/* Two, then four: the owner asked for four on top and four under, never a stray last one (04 §7.3). */
.lab-menu{display:grid;gap:.6rem;grid-template-columns:repeat(2,minmax(0,1fr));
  margin:2rem 0 1.25rem}
@media (min-width:52rem){ .lab-menu{grid-template-columns:repeat(4,minmax(0,1fr))} }
/* the first choice is always one line of four */
.lab-menu-4{grid-template-columns:repeat(4,minmax(0,1fr));align-items:stretch}
@media (max-width:900px){ .lab-menu-4{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:520px){ .lab-menu-4{grid-template-columns:1fr} }
.lab-tile{position:relative;overflow:hidden;display:grid;gap:.15rem;text-align:left;cursor:pointer;
  padding:.85rem 1rem;border:1px solid var(--rule);border-radius:12px;background:var(--panel);
  color:var(--text);font:inherit;
  transition:border-color .16s ease,background .16s ease,transform .16s ease}
.lab-tile:hover{border-color:var(--rule-lit);background:var(--panel-2);transform:translateY(-2px)}
.lab-tile::before{content:"";position:absolute;inset:0 0 auto 0;height:1px;
  background:var(--grad-rule);opacity:0;transition:opacity .2s ease}
.lab-tile:hover::before,.lab-tile.is-on::before{opacity:1}
.lab-tile-n{font:600 .68rem var(--mono);letter-spacing:.14em;color:var(--flare)}
.lab-tile-name{font-weight:620;letter-spacing:-.01em}
/* the examples are read in full: a tile grows a line rather than cut a sentence off */
.lab-tile-eg{font-size:.82rem;color:var(--dim);line-height:1.35}
.lab-tile.is-on{border-color:var(--flare);background:rgba(255,122,26,.08)}
.lab-tile.is-on .lab-tile-n{color:var(--glow)}
.lab-tile-all{border-style:dashed}
.lab-picked{margin:0 0 .25rem;color:var(--dim);font:500 .8rem var(--mono);letter-spacing:.06em}
@media (prefers-reduced-motion:reduce){ .lab-tile{transition:none} .lab-tile:hover{transform:none} }
/* The same, for the person's own choice (design/prefs.js writes data-motion on <html>). */
:root[data-motion="reduce"] .lab-tile{transition:none}
:root[data-motion="reduce"] .lab-tile:hover{transform:none} 


/* ── on the bench: small, and showing the actual three ──────────────────── */
.lab-bench{list-style:none;margin:1.75rem 0 0;padding:0;display:grid;gap:.6rem;
  grid-template-columns:minmax(0,1fr)}
@media (min-width:36rem){ .lab-bench{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (min-width:56rem){ .lab-bench{grid-template-columns:repeat(3,minmax(0,1fr))} }
/* each card fills its row, so a row of three is level along the bottom; the card is the column's width, never its
   longest line's */
.bench-item{display:grid;grid-template-columns:minmax(0,1fr)}
.bench-item a{display:flex;align-items:center;gap:.9rem;text-decoration:none;color:var(--text);
  border:1px dashed var(--rule);border-radius:12px;padding:.75rem .9rem;background:transparent;
  transition:border-color .16s ease,background .16s ease}
.bench-item a:hover{border-color:var(--rule-lit);background:var(--panel)}
.bench-art{flex:none;width:3.4rem;opacity:.7}
.bench-body{display:grid;gap:.15rem;min-width:0}
.bench-body strong{font-size:.98rem;letter-spacing:-.01em}
.bench-body .pill{justify-self:start;padding:.12rem .55rem;font-size:.6rem}
/* small, but whole: the line and who it's for wrap rather than trail off */
.bench-line{color:var(--muted);font-size:.85rem;line-height:1.4}
.bench-for{color:var(--dim);font:500 .7rem/1.4 var(--mono)}

/* the second level of the menu: smaller than the first, so the order reads */
.lab-menu-2{grid-template-columns:repeat(2,minmax(0,1fr));margin:.25rem 0 1.25rem}
@media (min-width:52rem){ .lab-menu-2{grid-template-columns:repeat(4,minmax(0,1fr))} }
.lab-tile-sm{padding:.6rem .8rem;background:transparent}
.lab-tile-sm .lab-tile-name{font-size:.92rem;font-weight:580}
.lab-tile-sm .lab-tile-eg{font-size:.76rem}

/* ── a card on a phone: no illustration, just the thing itself ──────────── */
/* The words' column is the card's width less the picture's (minmax(0,1fr)), never the width of its longest line, and
   a status pill wraps; the spacing is min(Xrem, Yvw), Yvw being Xrem at 320 px, so it doesn't grow with enlarged text
   on the narrowest screens. At the default text size nothing moves. */
@media (max-width:640px){
  .lab-card{display:grid;grid-template-columns:min(2.6rem,13vw) minmax(0,1fr);column-gap:min(.85rem,4.25vw);
    align-items:start;padding:min(1rem,5vw) min(1.1rem,5.5vw)}
  .lab-art{grid-row:1 / span 2;max-width:2.6rem;padding:.2rem 0 0;opacity:.85}
  .lab-meta{margin-bottom:.2rem}
  .lab-card h3,.lab-card p,.lab-for{grid-column:2}
  .lab-card p{margin-bottom:.6rem}
  .lab-for{white-space:normal;line-height:1.35}
  .lab-card .pill{white-space:normal}
}
/* A phone holding fewer than 20 characters of the person's text size (they have enlarged it): the pictures step
   aside, so the words have the whole card, and a status pill wraps. */
@media (max-width:19.99em){
  .lab-card{grid-template-columns:minmax(0,1fr)}
  .lab-art,.bench-art{display:none}
  .lab-card h3,.lab-card p,.lab-for{grid-column:1}
  .bench-item a{padding:.75rem min(.9rem,4.5vw)}
  .pill{white-space:normal}
}
