/* ==========================================================================
   The Sip Office — /labs (labs.v2)
   Companion stylesheet to web/styles/style.css. The site file owns every
   shared token and the footer; this file owns the diorama: the two world
   projections of the room, the SVG paint classes, and the page's own
   components (panel, nameplate, wink, legend).

   Palette rule (PRD): style.css :root tokens plus the four status colours
   declared below. Nothing else gets a hex. No SVG filters, no gradients —
   the night glow is three stepped diamonds of the status colour.
   ========================================================================== */

/* --- page-local tokens: the four status colours + font stacks ------------ */
:root {
  --labs-ok: #1e7a3e;
  --labs-warn: #b45309;
  --labs-fail: #ef4444;
  --labs-off: #87867f;
  --labs-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
  --labs-sans: 'Inter', system-ui, -apple-system, sans-serif;
  --labs-serif: Georgia, 'Times New Roman', serif;
}

/* --- the two worlds: the same three-tone object recipe, re-projected -----
   Day is paper; night is the same room with the lights off, so every tone
   below is a mix of the site's own dark tokens rather than new pigment. */
html[data-world="day"] {
  --o-top: var(--bg-white);
  --o-mid: var(--sand);
  /* fallback first, color-mix override second: browsers without color-mix
     (pre-2023) keep the room's bones instead of losing them */
  --o-shadow: #b1b1a8;
  --o-shadow: color-mix(in srgb, var(--dark-surface) 30%, var(--sand));
  --o-line: var(--dark-surface);
  --floor-a: var(--bg);
  --floor-b: var(--sand);
  --wall-far: var(--border);
  --wall-near: var(--bg);
  --wain: var(--sand);
  --wain-line: #cbcac0;
  --wain-line: color-mix(in srgb, var(--dark-surface) 16%, var(--sand));
  --grout: var(--border);
  --drop: rgba(48, 48, 46, 0.13);
  --drop: color-mix(in srgb, var(--dark-surface) 13%, transparent);
  --rim: transparent;
  --paper-hair: rgba(48, 48, 46, 0.2);
  --paper-hair: color-mix(in srgb, var(--dark-surface) 20%, transparent);
}
html[data-world="night"] {
  --o-top: #666560;
  --o-top: color-mix(in srgb, var(--dark-surface) 58%, var(--text-dark-surface));
  --o-mid: var(--dark-surface);
  --o-shadow: var(--dark);
  --o-line: var(--dark);
  --floor-a: var(--dark);
  --floor-b: #20201e;
  --floor-b: color-mix(in srgb, var(--dark-surface) 42%, var(--dark));
  --wall-far: var(--dark);
  --wall-near: #1a1a18;
  --wall-near: color-mix(in srgb, var(--dark-surface) 20%, var(--dark));
  --wain: #21211f;
  --wain: color-mix(in srgb, var(--dark-surface) 46%, var(--dark));
  --wain-line: #282826;
  --wain-line: color-mix(in srgb, var(--dark-surface) 70%, var(--dark));
  --grout: #1c1c1b;
  --grout: color-mix(in srgb, var(--dark-surface) 30%, var(--dark));
  --drop: rgba(20, 20, 19, 0.7);
  --drop: color-mix(in srgb, var(--dark) 70%, transparent);
  --rim: rgba(176, 174, 165, 0.55);
  --rim: color-mix(in srgb, var(--text-dark-surface) 55%, transparent);
  --paper-hair: rgba(176, 174, 165, 0.26);
  --paper-hair: color-mix(in srgb, var(--text-dark-surface) 26%, transparent);
}

/* --- component tokens: the cards re-tone with the world ----------------- */
main.labs {
  --card-bg: var(--bg-white);
  --card-line: var(--dark-surface);
  --card-shadow: 3px 4px 0 rgba(48, 48, 46, 0.14);
  --card-shadow: 3px 4px 0 color-mix(in srgb, var(--dark-surface) 14%, transparent);
  --ink-strong: var(--text-primary);
  --ink-soft: var(--text-secondary);
  --ink-faint: var(--text-tertiary);
  --hair-line: var(--border);
  --accent-ink: var(--accent);
  --btn-line: var(--border-warm);
}
html[data-world="night"] main.labs {
  --card-bg: #1e1e1c;
  --card-bg: color-mix(in srgb, var(--dark-surface) 34%, var(--dark));
  --card-line: #282826;
  --card-line: color-mix(in srgb, var(--dark-surface) 72%, var(--dark));
  --card-shadow: 3px 4px 0 rgba(20, 20, 19, 0.8);
  --card-shadow: 3px 4px 0 color-mix(in srgb, var(--dark) 80%, transparent);
  --ink-strong: var(--bg);
  --ink-soft: var(--text-dark-surface);
  --ink-faint: var(--text-dark-surface);
  --hair-line: color-mix(in srgb, var(--dark-surface) 62%, var(--dark));
  --accent-ink: var(--accent-light);
  --btn-line: var(--card-line);
}

/* --- the site header, logo only ------------------------------------------
   The homepage's own .nav--home, reduced to the logo link: this page is
   unlisted, so there is no CTA and no full nav. style.css owns every rule
   the bar uses; the two lines below only square it with this page, whose
   container is wider than the site's and whose lights go off. */
nav.nav--home .nav-inner { max-width: 1180px; }
html[data-world="night"] nav.nav--home {
  background: color-mix(in srgb, var(--dark) 88%, transparent);
  border-bottom-color: var(--dark-surface);
}
html[data-world="night"] nav.nav--home .nav-logo { color: var(--bg); }

/* --- page scaffolding ----------------------------------------------------
   style.css narrows `main` to a 640px prose column and margins every p/li;
   the office needs the wide grid and its own rhythm back. */
main.labs {
  max-width: none;
  margin: 0;
  padding: 0;
  font-family: var(--labs-sans);
  line-height: 1.55;
}
main.labs > .container { max-width: 1180px; padding-top: 28px; padding-bottom: 48px; }
main.labs p, main.labs li { font-size: inherit; color: inherit; margin: 0; }
main.labs h1, main.labs h2, main.labs h3 { font-family: var(--labs-serif); margin: 0; }
main.labs [hidden] { display: none !important; }

html[data-world="night"] body { background: var(--dark); color: var(--text-dark-surface); }
main.labs { overflow-x: clip; }

/* --- masthead ------------------------------------------------------------
   eyebrow + pill, then the h1, then the lede. The snapshot line belongs to
   the legend's small print and lives below it. */
main.labs .masthead { margin-bottom: 20px; }
/* the eyebrow is the site's own .section-label (0.8rem/500/.08em/uppercase/
   accent) — the editorial family's idiom, borrowed verbatim so it inherits
   any future brand tweak. The pill sits beside it, outside the label. */
main.labs .eyebrow {
  display: flex; align-items: baseline; gap: 10px;
}
/* the beta badge: hairline, tertiary, quiet. A stamp, not a shout. */
main.labs .eyebrow .pill {
  font-family: var(--labs-mono);
  font-size: 9px; letter-spacing: .16em; text-transform: none;
  line-height: 1.5; padding: 2px 6px 1px; color: var(--ink-faint);
  border: 1px solid var(--hair-line);
  position: relative; top: -1.5px; /* optical centering against the label */
  transition: color .15s ease, border-color .15s ease;
}
main.labs .eyebrow .pill:hover { color: var(--accent-ink); border-color: var(--accent-ink); }
/* the h1 inherits style.css's `main h1` (2rem Georgia) — the editorial
   family's page-title scale. The diorama is the hero; the headline doesn't
   shout over it. (Night keeps its own ink.) */
html[data-world="night"] main.labs h1 { color: var(--bg); }
/* the lede: the room's one sentence, directly under its title, set exactly
   as the site sets a .section-desc (1.1rem, secondary ink, 1.7) */
main.labs .lede {
  max-width: 62ch; font-size: 1.1rem; line-height: 1.7;
  color: var(--ink-soft); margin: 10px 0 0;
}
/* the snapshot line, in the legend's own small-print voice */
main.labs .asof {
  display: block; margin-top: 8px;
  font-family: var(--labs-mono); font-size: 10.5px; color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
main.labs .asof sup { font-size: .68em; line-height: 0; letter-spacing: .02em; }
main.labs .asof b { color: var(--ink-soft); font-weight: 400; }

main.labs .notice {
  display: none; font-family: var(--labs-mono); font-size: 12px;
  border: 1px dashed var(--ink-faint); color: var(--ink-soft);
  padding: 10px 12px; margin: 0 0 16px; background: var(--bg-white);
}
main.labs .notice.on { display: block; }
html[data-world="night"] main.labs .notice {
  background: var(--card-bg); border-color: var(--text-dark-surface); color: var(--bg);
}

/* --- the room ------------------------------------------------------------ */
main.labs .roomgrid {
  display: grid; grid-template-columns: minmax(0, 1fr) 336px;
  gap: 26px; align-items: start;
}
/* the left column holds the scene and its own small print, so the panel's
   height — which varies with whatever it is showing — can never push the
   legend or the snapshot line around */
main.labs .stagecol { min-width: 0; }
main.labs .stage { position: relative; width: 100%; aspect-ratio: 784 / 540; }
/* only the room is pinned to the stage's box; the sheet sets its own height */
main.labs .stage > svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* the scene is not a focus stop, so a click on the room must not paint a
   rectangle around the whole drawing: the desks, the plaques and the switch
   carry their own indicators */
#scene { outline: none; }

/* --- svg paints by class, so the whole world re-tones on one attribute --- */
#scene .fl-a { fill: var(--floor-a); }
#scene .fl-b { fill: var(--floor-b); }
#scene .grout { stroke: var(--grout); stroke-width: 1; fill: none; }
#scene .wall-far { fill: var(--wall-far); }
#scene .wall-near { fill: var(--wall-near); }
#scene .wain { fill: var(--wain); }
#scene .wain-line { stroke: var(--wain-line); stroke-width: 1; fill: none; }
#scene .hair { stroke: var(--paper-hair); stroke-width: 1; fill: none; }
#scene .o-top { fill: var(--o-top); stroke: var(--rim); stroke-width: 1; }
#scene .o-mid { fill: var(--o-mid); }
#scene .o-shadow { fill: var(--o-shadow); }
#scene .a-top { fill: var(--accent); }
#scene .a-mid { fill: color-mix(in srgb, var(--accent) 74%, var(--dark-surface)); }
#scene .a-shadow { fill: color-mix(in srgb, var(--accent) 52%, var(--dark-surface)); }
#scene .ink {
  fill: none; stroke: var(--o-line); stroke-width: 1.2;
  stroke-linejoin: round; stroke-linecap: round;
}
#scene .ink-f { fill: var(--o-line); stroke: none; }
#scene .drop { fill: var(--drop); }
#scene .glass { fill: color-mix(in srgb, var(--bg-white) 88%, transparent); }
html[data-world="night"] #scene .glass { fill: color-mix(in srgb, var(--text-dark-surface) 22%, transparent); }
#scene .screen { fill: color-mix(in srgb, var(--text-secondary) 20%, var(--bg-white)); }
html[data-world="night"] #scene .screen { fill: color-mix(in srgb, var(--accent-light) 46%, var(--dark-surface)); }
#scene .screen-off { fill: color-mix(in srgb, var(--dark-surface) 28%, var(--bg-white)); }
html[data-world="night"] #scene .screen-off { fill: color-mix(in srgb, var(--dark-surface) 62%, var(--dark)); }
#scene .body { fill: var(--dark-surface); }
#scene .skin { fill: var(--sand); }
#scene .hair-f { fill: var(--text-secondary); }
#scene .rat { fill: var(--text-secondary); }
#scene .mic { fill: var(--dark-surface); }
/* the snake plant: ink outline over the room's own paper tones. Green is not
   in the palette, so the plant is drawn like every other object here. */
#scene .blade {
  fill: var(--o-top); stroke: var(--o-line); stroke-width: 1;
  stroke-linejoin: round;
}
#scene .blade.b-mid { fill: var(--o-mid); }
/* closed eyes: a horizontal eyelid, drawn with the same ink as the dot eyes */
#scene .eye-lid {
  fill: none; stroke: var(--o-line); stroke-width: 1.2;
  stroke-linecap: round;
}

/* the rug: projected from the floor tone, so it dims with the room instead
   of glowing paper-white once the lights go off */
#scene .rugline {
  fill: color-mix(in srgb, var(--text-tertiary) 15%, var(--floor-a));
  stroke: color-mix(in srgb, var(--text-tertiary) 42%, var(--floor-a));
  stroke-width: 1.6;
}
/* the rug's inscription: barely there, in the site's own serif, and set into
   the floor plane by the matrix labs.js gives it. It is aria-hidden — a
   thing you find, not a thing you are told. */
#scene .rug-word {
  font-family: var(--labs-serif); font-size: 9px;
  fill: var(--text-tertiary); opacity: .42;
}
html[data-world="night"] #scene .rug-word { fill: var(--text-dark-surface); opacity: .36; }

/* --- wall art ------------------------------------------------------------ */
#scene .frame { fill: var(--o-line); }
#scene .mat { fill: var(--wain); }
#scene .clockface { fill: var(--wain); stroke: var(--o-line); stroke-width: 1.6; }
/* the calendar day: big, and skewed into the wall plane with its month */
#scene .numeral { font-family: var(--labs-mono); font-weight: 700; fill: var(--accent); }
#scene .numeral-sub {
  font-family: var(--labs-mono); font-weight: 400; font-size: 8px;
  letter-spacing: .1em; fill: var(--text-secondary);
}
html[data-world="night"] #scene .numeral-sub { fill: var(--text-dark-surface); }
/* the wall's own small print, under the clock: the city the office clock
   keeps. Quieter than the months, and set into the same plane. */
#scene .wall-lbl {
  font-family: var(--labs-mono); font-size: 6.5px; letter-spacing: .16em;
  fill: var(--text-tertiary);
}
html[data-world="night"] #scene .wall-lbl { fill: var(--text-dark-surface); }

/* --- the plaques lift when held ------------------------------------------
   Hover or keyboard focus: the frame takes the accent and the whole plaque
   rises a hair, the way a picture comes off a wall when you look at it. */
#scene .plaque { transition: transform .15s ease; }
#scene .plaque .frame { transition: fill .15s ease; }
#scene .plaque:hover, #scene .plaque:focus-visible { transform: translateY(-1.5px); }
#scene .plaque:hover .frame, #scene .plaque:focus-visible .frame {
  fill: var(--accent-ink);
}

/* --- plumbobs: status colour, two hard frames, off shift does not bob ---- */
#scene .pbcl.s-working { color: var(--labs-ok); }
#scene .pbcl.s-warn { color: var(--labs-warn); }
#scene .pbcl.s-fail { color: var(--labs-fail); }
#scene .pbcl.s-idle, #scene .pbcl.s-off { color: var(--labs-off); }
#scene .pb-main { fill: currentColor; }
#scene .pb-face { fill: color-mix(in srgb, currentColor 58%, var(--bg-white)); }
html[data-world="night"] #scene .pb-face { fill: color-mix(in srgb, currentColor 46%, var(--dark-surface)); }
#scene .pb-halo polygon { fill: currentColor; }
#scene .pb-halo .h1 { opacity: .05; }
#scene .pb-halo .h2 { opacity: .085; }
#scene .pb-halo .h3 { opacity: .13; }
#scene .pb-halo { opacity: 0; }
html[data-glow="burst"] #scene .pb-halo { opacity: 1; }
#scene .pb-wrap { transform-box: fill-box; transform-origin: 50% 50%; }
#scene .bobs .pb-wrap { animation: pbob 1.5s steps(1, end) infinite; animation-delay: calc(var(--i) * .17s); }
@keyframes pbob {
  0%, 49.99% { transform: translateY(0); }
  50%, 100% { transform: translateY(-3.2px); }
}
/* the bench rats' wheel turns while that desk is at work — the same flag that
   bobs the plumbob — ten steps a revolution, so the turn stays in the pixel
   idiom. A rat at ease leaves its wheel still. */
#scene .wheel-spin { transform-box: fill-box; transform-origin: 50% 50%; }
#scene .desk.bobs .wheel-spin { animation: wheelturn 2s steps(10, end) infinite; }
@keyframes wheelturn {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
#scene .halo { opacity: 0; }
html[data-glow="burst"] #scene .halo { opacity: 1; animation: halo 3.6s ease-in-out infinite; }
@keyframes halo { 0%, 100% { opacity: .45; } 50% { opacity: .85; } }
html[data-glow="lamp"] #scene .halo.lamp { opacity: 1; }
#scene .winbeam { fill: color-mix(in srgb, var(--bg-white) 62%, transparent); }
html[data-world="night"] #scene .winbeam { fill: color-mix(in srgb, var(--text-dark-surface) 16%, transparent); }

/* --- the hover chevron, and the one clickable footprint per desk ---------
   Only polygon.hit answers the pointer: a desk's own props and villager are
   pointer-transparent, and the hit area is the front half of the footprint
   diamond, so nothing standing behind a desk is ever covered. Selection is
   carried by the same polygon (plus the plumbob), never by a second class
   on the group. The ring itself is an open chevron of two strokes — the two
   viewer-facing edges of the footprint, offset outward — so a held desk is
   marked on the floor without a closed box being drawn around it. */
#scene .ring {
  fill: none; stroke: var(--accent); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; opacity: 0;
}
#scene .desk:hover .ring, #scene .desk:focus-visible .ring { opacity: 1; }
/* a held desk keeps its chevron after the pointer moves on */
#scene .hit.sel ~ .ring { opacity: 1; }
#scene .desk { pointer-events: none; }
#scene .hit { fill: transparent; pointer-events: auto; }
#scene .desk:hover .hit, #scene .desk:focus-visible .hit {
  fill: color-mix(in srgb, var(--accent) 8%, transparent);
}
#scene .hit.sel { fill: color-mix(in srgb, var(--accent) 15%, transparent); }

/* --- the light switch, labelled by a drawn bulb -------------------------- */
#scene .ctrl { cursor: pointer; outline: none; }
#scene .ctrl .plate { fill: var(--sand); stroke: var(--o-line); stroke-width: 1.2; }
#scene .ctrl .lever { fill: var(--accent); }
#scene .ctrl:focus-visible .plate { stroke: var(--accent); stroke-width: 2.2; }
/* held — by pointer or by keyboard — the plate brightens and the bulb's rays
   come up out of their idle whisper */
#scene #lights .plate { transition: fill .15s ease; }
#scene #lights:hover .plate, #scene #lights:focus-visible .plate {
  fill: color-mix(in srgb, var(--bg-white) 65%, var(--sand));
}
#scene .bulb-glass {
  fill: color-mix(in srgb, var(--bg-white) 82%, transparent);
  stroke: var(--o-line); stroke-width: 1.1;
}
#scene .bulb-fil { fill: none; stroke: var(--accent); stroke-width: 1.1; stroke-linecap: round; }
#scene .bulb-base { fill: none; stroke: var(--o-line); stroke-width: 1.1; stroke-linecap: round; }
#scene .bulb-ray {
  stroke: var(--accent); stroke-width: 1; stroke-linecap: round;
  opacity: .22; transition: opacity .15s ease;
}
#scene #lights:hover .bulb-ray, #scene #lights:focus-visible .bulb-ray { opacity: 1; }

#scene .clock-hand { stroke: var(--text-primary); stroke-linecap: round; }
html[data-world="night"] #scene .clock-hand { stroke: var(--text-dark-surface); }
#scene .onaire { font-family: var(--labs-mono); font-weight: 700; font-size: 7px; letter-spacing: .12em; }
#scene .sign-box { fill: var(--accent); }
#scene .sign-txt { fill: var(--bg-white); }

/* --- nameplate: one floating overlay, parked on free floor --------------- */
main.labs .platebox {
  position: absolute; top: 78.5%; width: 196px; margin-left: -98px;
  pointer-events: none; opacity: 0; transform: translateY(4px);
  transition: opacity .16s ease, transform .16s ease;
  background: var(--card-bg); border: 1px solid var(--card-line);
  box-shadow: var(--card-shadow); padding: 7px 9px 8px;
  z-index: 3;   /* above the wink, below the panel */
}
main.labs .platebox.on { opacity: 1; transform: translateY(0); }
main.labs .pb-name { font-family: var(--labs-serif); font-size: 14px; line-height: 1.15; color: var(--ink-strong); }
main.labs .pb-word {
  font-family: var(--labs-mono); font-size: 9.5px; letter-spacing: .14em;
  text-transform: uppercase;
}
main.labs .pb-word i {
  display: inline-block; width: 7px; height: 7px;
  transform: rotate(45deg); margin-right: 5px;
}
main.labs .pb-mood { font-family: var(--labs-mono); font-size: 10.5px; line-height: 1.4; color: var(--ink-soft); margin-top: 4px; }
main.labs .pb-ev {
  font-family: var(--labs-mono); font-size: 9.5px; color: var(--ink-faint);
  margin-top: 5px; border-top: 1px solid var(--hair-line); padding-top: 4px;
}
main.labs .pb-ev em { font-style: normal; }

/* --- the polyglot's wink: hover/focus only, and never on top -------------
   Left and top are set by labs.js, so the bubble can hang over the
   Polyglot's head and be clamped to the stage. */
main.labs .wink {
  position: absolute; z-index: 1; pointer-events: none;
  opacity: 0; transition: opacity .2s ease;
  font-size: 12px; line-height: 1.3; color: var(--ink-strong); background: var(--card-bg);
  border: 1px solid var(--card-line); padding: 4px 9px 5px; max-width: 210px;
}
main.labs .wink.on { opacity: 1; }
main.labs .wink .wink-fx { display: block; }
/* the gloss: a caption line under the foreign text, in the page's mono */
main.labs .wink .wink-en {
  display: block; margin-top: 3px;
  font-family: var(--labs-mono); font-size: 9px; letter-spacing: .02em;
  color: var(--ink-faint);
}

/* --- side panel ---------------------------------------------------------- */
main.labs .panel {
  position: relative; z-index: 6;
  border: 1px solid var(--card-line); background: var(--card-bg);
  padding: 16px 16px 18px; color: var(--ink-soft);
  opacity: .62; transition: opacity .18s ease;
}
main.labs .panel.on { opacity: 1; }
main.labs .panel-kicker {
  font-family: var(--labs-mono); font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--accent-ink);
}
main.labs .panel h2 {
  font-weight: 500; font-size: 23px; line-height: 1.1;
  margin: 5px 0 6px; color: var(--ink-strong);
}
/* the invitation: prose, so it reads at the site's own intro size (.faq-intro) */
main.labs .panel .blurb { font-size: .95rem; line-height: 1.55; color: var(--ink-soft); margin-bottom: 10px; }
main.labs .panel .mood {
  font-family: var(--labs-mono); font-size: 11.5px; color: var(--ink-strong);
  border-left: 2px solid var(--accent-ink); padding-left: 9px; margin-bottom: 14px;
}
main.labs .panel h3 {
  font-family: var(--labs-mono); font-size: 9.5px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink-faint); margin: 14px 0 6px;
}
main.labs table.stats { width: 100%; border-collapse: collapse; font-family: var(--labs-mono); font-size: 11px; }
main.labs table.stats th {
  text-align: left; font-weight: 400; color: var(--ink-soft);
  padding: 3px 0; border-top: 1px solid var(--hair-line);
}
main.labs table.stats td {
  text-align: right; color: var(--ink-strong); padding: 3px 0;
  border-top: 1px solid var(--hair-line); font-variant-numeric: tabular-nums;
}
main.labs .spark { display: block; width: 100%; height: auto; }
main.labs .spark .axis { stroke: var(--hair-line); stroke-width: 1; }
main.labs .spark .line {
  fill: none; stroke: color-mix(in srgb, var(--text-tertiary) 55%, transparent);
  stroke-width: 2; stroke-linejoin: round; stroke-linecap: round;
}
main.labs .spark .dot { stroke: var(--card-bg); stroke-width: 2; }
main.labs .spark .lbl { font-family: var(--labs-mono); font-size: 8px; fill: var(--ink-soft); }
main.labs .twin { list-style: none; padding: 0; font-family: var(--labs-mono); font-size: 10px; color: var(--ink-soft); }
main.labs .twin li {
  display: flex; align-items: center; gap: 7px; padding: 2px 0;
  border-top: 1px solid var(--hair-line);
}
main.labs .twin i { width: 7px; height: 7px; border-radius: 50%; flex: none; }
main.labs .twin i.catchmark { border-radius: 0; transform: rotate(45deg); }
main.labs .runs { list-style: none; padding: 0; font-family: var(--labs-mono); font-size: 10px; color: var(--ink-soft); }
main.labs .runs li {
  display: flex; gap: 7px; align-items: center; padding: 2px 0;
  border-top: 1px solid var(--hair-line);
}
main.labs .runs i { width: 7px; height: 7px; transform: rotate(45deg); flex: none; }
main.labs .v-ok, main.labs .v-clean, main.labs .v-empty { background: var(--labs-ok); }
main.labs .v-warn, main.labs .v-failover, main.labs .v-timeout, main.labs .v-false-alarm { background: var(--labs-warn); }
main.labs .v-fail { background: var(--labs-fail); }
main.labs .v-catch { background: var(--accent); }
main.labs .v-off { background: var(--labs-off); }
main.labs .spark .v-ok, main.labs .spark .v-clean, main.labs .spark .v-empty { fill: var(--labs-ok); }
main.labs .spark .v-warn, main.labs .spark .v-failover,
main.labs .spark .v-timeout, main.labs .spark .v-false-alarm { fill: var(--labs-warn); }
main.labs .spark .v-fail { fill: var(--labs-fail); }
main.labs .spark .v-catch { fill: var(--accent); }
main.labs .spark .v-off { fill: var(--labs-off); }
/* --- buttons: the site's .btn-secondary, scaled down ---------------------
   style.css's quiet button is a white ground, one warm hairline, a 12px
   corner, and a hover that deepens the line and adds its ring. The room
   needs it far smaller, so the family is kept — ground, line, corner, ring,
   and the same text in both — while the homepage's 14px/28px padding is
   not. */
main.labs .viewbar .vbtn,
main.labs .closebtn {
  font-family: var(--labs-mono); font-size: 10.5px; letter-spacing: .1em;
  background: var(--card-bg); border: 1px solid var(--btn-line);
  border-radius: 12px; color: var(--ink-soft); cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease;
}
main.labs .viewbar .vbtn:hover,
main.labs .closebtn:hover {
  border-color: var(--ring); box-shadow: 0 0 0 1px var(--ring);
}
main.labs .viewbar .vbtn:focus-visible,
main.labs .closebtn:focus-visible {
  outline: 2px solid var(--accent-ink); outline-offset: 2px;
}
main.labs .panel .hint { font-family: var(--labs-mono); font-size: 10px; color: var(--ink-faint); margin-top: 12px; }

/* --- legend -------------------------------------------------------------- */
main.labs .legend {
  display: flex; flex-wrap: wrap; gap: 8px 22px; align-items: baseline;
  margin-top: 18px; font-family: var(--labs-mono); font-size: 10.5px;
  color: var(--ink-soft);
}
main.labs .legend span.k { display: inline-flex; align-items: center; gap: 7px; }
main.labs .legend i { width: 9px; height: 9px; transform: rotate(45deg); flex: none; }

/* ==========================================================================
   THE SECOND VIEW — the elevations sheet
   The Blueprint's Zone A, re-projected onto this page's tokens. The room
   owns the wall; the sheet owns nothing but its bays. Same palette rule as
   the rest of the file: the site tokens, the four status colours, and
   colour-mix between them. Night is not a second drawing — the same
   linework re-tones, the stamps keep their reserved colours.
   ========================================================================== */

/* --- the view control: one pair of buttons, mono, title case ------------- */
main.labs .viewbar {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 16px; font-family: var(--labs-mono); font-size: 10.5px;
  color: var(--ink-faint);
}
main.labs .viewbar .vbtn { padding: 4px 12px; }
main.labs .viewbar .vbtn[aria-pressed="true"] {
  border-color: var(--accent-ink); color: var(--accent-ink);
}
main.labs .closebtn { padding: 6px 12px; margin-top: 16px; }

/* --- the sheet's own tokens: the world, re-projected onto flat paper ----- */
main.labs .sheet {
  /* paper world: ink on paper, a heavier press for the structure */
  --sv-ink: var(--text-primary);
  --sv-struct: var(--dark-surface);
  --sv-faint: var(--text-tertiary);
  --sv-paper: var(--bg-white);
  --sv-solid: var(--sand);
  --sv-bay: var(--bg-white);
  --sv-bay-hi: var(--bg);
  --sv-gap: var(--dark-surface);
  /* the stamps keep their reserved colours, in both worlds */
  --stamp-ok: var(--labs-ok);
  --stamp-warn: var(--labs-warn);
  --stamp-fail: var(--labs-fail);
  --stamp-off: var(--labs-off);
}
html[data-world="night"] main.labs .sheet {
  /* ink world: the same lines, light on the dark sheet */
  --sv-ink: var(--text-dark-surface);
  --sv-struct: color-mix(in srgb, var(--text-dark-surface) 46%, var(--dark));
  --sv-faint: color-mix(in srgb, var(--text-dark-surface) 40%, var(--dark));
  --sv-paper: var(--dark-surface);
  --sv-solid: color-mix(in srgb, var(--dark-surface) 58%, var(--dark));
  --sv-bay: color-mix(in srgb, var(--dark-surface) 34%, var(--dark));
  --sv-bay-hi: color-mix(in srgb, var(--dark-surface) 50%, var(--dark));
  --sv-gap: var(--dark);
  --stamp-ok: color-mix(in srgb, var(--labs-ok) 46%, var(--bg));
  --stamp-warn: color-mix(in srgb, var(--labs-warn) 46%, var(--bg));
  --stamp-fail: color-mix(in srgb, var(--labs-fail) 46%, var(--bg));
  --stamp-off: color-mix(in srgb, var(--labs-off) 60%, var(--bg));
}

main.labs .sheet { display: none; }
main.labs[data-view="elev"] .sheet { display: block; }
/* the room is the office view alone: its scene, its switch, its wink and
   its nameplate stand down while the sheet is up */
main.labs[data-view="elev"] #scene { display: none; }
main.labs[data-view="elev"] .stage { aspect-ratio: auto; }
main.labs[data-view="elev"] .platebox,
main.labs[data-view="elev"] .wink { display: none; }

/* --- the sheet itself ---------------------------------------------------- */
main.labs .sheet-h {
  display: flex; align-items: center; gap: 12px;
  font-family: var(--labs-mono); font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink-faint); margin: 0 0 12px;
}
main.labs .sheet-h i {
  flex: 1 1 40px; min-width: 24px; height: 1px; background: var(--sv-gap);
}
main.labs .sheet-grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px; background: var(--sv-gap); border: 1px solid var(--sv-gap);
}

/* --- a bay --------------------------------------------------------------- */
main.labs .bay {
  background: var(--sv-bay); padding: 10px 11px 12px;
  display: flex; flex-direction: column; cursor: pointer;
  border-left: 2px solid transparent;
  transition: background-color .16s ease;
}
main.labs .bay:hover, main.labs .bay:focus-visible { background: var(--sv-bay-hi); }
/* the active rule, the way the Blueprint's schedule entry carries "open" */
main.labs .bay[data-open="true"] {
  background: var(--sv-bay-hi); border-left-color: var(--accent);
}
main.labs .bay:focus-visible {
  outline: none; box-shadow: inset 0 0 0 1px var(--accent);
}
main.labs .bay-top {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 8px; min-height: 22px;
}
main.labs .bay-no {
  font-family: var(--labs-mono); font-size: 10px; letter-spacing: .1em;
  color: var(--ink-faint); padding-top: 2px;
}
main.labs .bay[data-open="true"] .bay-no { color: var(--accent); }

/* the stamp: outlined mono, rotated, its word always spelled out */
main.labs .bay .stamp {
  font-family: var(--labs-mono); font-size: 8.5px; font-weight: 700;
  letter-spacing: .13em; line-height: 1; padding: 3px 4px 2px;
  border: 1px solid currentColor; transform: rotate(-4deg);
  white-space: nowrap;
}
main.labs .bay .stamp-ok { color: var(--stamp-ok); }
main.labs .bay .stamp-warn { color: var(--stamp-warn); }
main.labs .bay .stamp-fail { color: var(--stamp-fail); }
main.labs .bay .stamp-off { color: var(--stamp-off); }

/* --- the drawing: the sheet's four line weights -------------------------- */
main.labs .bay .draw { width: 100%; height: auto; display: block; margin-top: 4px; }
main.labs .bay .draw .hl {
  fill: none; stroke: var(--sv-ink); stroke-width: 1;
  stroke-linecap: round; stroke-linejoin: round;
}
main.labs .bay .draw .st {
  fill: none; stroke: var(--sv-struct); stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
main.labs .bay .draw .hd {
  fill: none; stroke: var(--sv-faint); stroke-width: 1;
  stroke-linecap: round; stroke-dasharray: 3 3;
}
main.labs .bay .draw .fp {
  fill: var(--sv-paper); stroke: var(--sv-ink); stroke-width: 1;
  stroke-linejoin: round;
}
main.labs .bay .draw .fs {
  fill: var(--sv-solid); stroke: var(--sv-ink); stroke-width: 1;
  stroke-linejoin: round;
}
main.labs .bay .draw .bgrid { fill: none; stroke: var(--sv-faint); stroke-width: .5; opacity: .3; }
main.labs .bay .draw .blbl {
  font-family: var(--labs-mono); font-size: 7px; letter-spacing: .14em;
  fill: var(--sv-ink);
}

/* --- the dimension line: the real number, between two ticked rules ------- */
main.labs .bay .dim {
  display: flex; align-items: center; gap: 7px; height: 14px; margin-top: 2px;
}
main.labs .bay .dim .dim-rule {
  position: relative; flex: 1 1 auto; height: 1px; background: var(--sv-faint);
}
main.labs .bay .dim .dim-rule::before,
main.labs .bay .dim .dim-rule::after {
  content: ""; position: absolute; top: -3px; width: 1px; height: 7px;
  background: var(--sv-faint);
}
main.labs .bay .dim .dim-rule::before { left: 0; }
main.labs .bay .dim .dim-rule::after { right: 0; }
main.labs .bay .dim .dim-v {
  font-family: var(--labs-mono); font-size: 9px; letter-spacing: .05em;
  color: var(--ink-soft); white-space: nowrap; font-variant-numeric: tabular-nums;
}

main.labs .bay-name {
  font-family: var(--labs-mono); font-size: 11px; font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase; margin: 7px 0 0;
  color: var(--ink-strong);
}
main.labs .bay-sub {
  font-family: var(--labs-mono); font-size: 9px; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-faint); margin: 3px 0 0;
}

/* --- the no-JS status list ------------------------------------------------ */
main.labs .noslist { font-family: var(--labs-mono); font-size: 11.5px; max-width: 62ch; }
main.labs .noslist h2 { font-family: var(--labs-serif); font-size: 18px; margin-bottom: 8px; }
main.labs .noslist ul { list-style: none; padding: 0; margin: 0; }
main.labs .noslist li { padding: 5px 0; border-top: 1px solid var(--hair-line); color: var(--ink-soft); }
main.labs .noslist li:first-child { border-top: 0; }
main.labs .noslist a { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 3px; }

/* --- the site footer, re-weighted for the ink world ---------------------- */
html[data-world="night"] footer { border-top-color: var(--dark-surface); }
html[data-world="night"] footer p,
html[data-world="night"] footer a { color: var(--text-dark-surface); }
html[data-world="night"] footer a:hover { color: var(--accent-light); }

/* --- a11y ----------------------------------------------------------------- */
#scene .desk, #scene .ctrl { cursor: pointer; }
/* the ring is the focus indicator, so the browser's rectangle stays off
   (it wraps the whole group's box, plumbob and all) */
#scene .desk:focus, #scene .ctrl:focus,
#scene .desk:focus-visible, #scene .ctrl:focus-visible { outline: none; }
#scene .desk:focus-visible .ring { opacity: 1; stroke-width: 3; }
#scene .desk:focus-visible .hit { fill: color-mix(in srgb, var(--accent) 12%, transparent); }
.sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  main.labs *, #scene * { animation: none !important; transition: none !important; }
  html[data-glow] #scene .pb-halo, html[data-glow] #scene .halo { opacity: 0 !important; }
  /* the plaque still answers hover and focus, but it does not move */
  #scene .plaque:hover, #scene .plaque:focus-visible { transform: none; }
  /* the case board too: it holds its place, and the frame still takes the
     accent — fill is not motion, so focus stays visible */
  #scene [data-board]:hover, #scene [data-board]:focus-visible { transform: none; }
  #scene [data-board] .a-top { transform: none !important; }
  main.labs .platebox, main.labs .wink { transition: none; }
  main.labs .bay { transition: none; }
}

/* --- the case board: held, it answers like the plaques do -----------------
   the frame takes the accent and the board lifts a hair; the notes stir
   around their pins (the pins hold still — they are what the paper hangs
   from), one voice per note, and all of it stills under reduced motion,
   where the frame's fill alone carries the answer */
#scene [data-board] { transition: transform .15s ease; }
#scene [data-board] .frame { transition: fill .15s ease; }
#scene [data-board]:hover, #scene [data-board]:focus-visible { transform: translateY(-1.5px); }
#scene [data-board]:hover .frame, #scene [data-board]:focus-visible .frame {
  fill: var(--accent-ink);
}
#scene [data-board] .a-top {
  transform-box: fill-box; transform-origin: center;
  transition: transform .18s ease;
}
/* the board's own word ("quiet", "+2"): one size down from the wall's
   other small print, and re-inked with the room at night */
#scene .cb-lbl {
  font-family: var(--labs-mono); font-size: 5.5px; letter-spacing: .14em;
  fill: var(--text-tertiary);
}
html[data-world="night"] #scene .cb-lbl { fill: var(--text-dark-surface); }
#scene [data-board]:hover .cb-note-1, #scene [data-board]:focus-visible .cb-note-1 {
  transform: rotate(-2.4deg) translate(-0.5px, -1.5px);
}
#scene [data-board]:hover .cb-note-2, #scene [data-board]:focus-visible .cb-note-2 {
  transform: rotate(1.8deg) translateY(-1px);
  transition-delay: .03s;
}
#scene [data-board]:hover .cb-note-3, #scene [data-board]:focus-visible .cb-note-3 {
  transform: rotate(-1.6deg) translateY(-1.8px);
  transition-delay: .06s;
}
#scene [data-board]:hover .cb-note-4, #scene [data-board]:focus-visible .cb-note-4 {
  transform: rotate(2.2deg) translateY(-0.8px);
  transition-delay: .09s;
}

/* --- small screens -------------------------------------------------------- */
@media (max-width: 980px) {
  main.labs .roomgrid { grid-template-columns: minmax(0, 1fr); }
  main.labs .panel { max-width: 640px; }
}
/* the sheet drops to two bays a row before the room does anything */
@media (max-width: 900px) {
  main.labs .sheet-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 480px) {
  main.labs > .container { padding-top: 20px; padding-bottom: 36px; }
  main.labs .asof { margin-top: 6px; }
  main.labs .platebox { width: 164px; margin-left: -82px; top: 64%; }
  main.labs .wink { font-size: 10px; max-width: 128px; padding: 3px 7px; }
  main.labs .wink .wink-en { font-size: 8px; margin-top: 2px; }
  main.labs .panel { padding: 14px 12px 16px; }
  main.labs .bay { padding: 9px 9px 11px; }
  main.labs .bay .stamp { font-size: 8px; }
  main.labs .bay-name { font-size: 10px; letter-spacing: .07em; }
}
