/* =========================================================
   Science Simulations — the apparatus board

   THESIS: The library is a lab shadow board. Every simulation hangs in a
     labelled position; every one not built yet is the painted outline of the
     instrument that belongs there. Refuses the card-grid course catalogue and
     its cream-and-serif opposite — with one instrument built, a shadow board
     is not an empty page, it is the object working exactly as designed.
   OWN-WORLD: Inherited from The Interactive Heart. Painted instrument grey,
     screened condensed caps legends, hanging plates that stand proud, dark
     reading windows holding authored line art, red/blue terminal logic, 3px
     radii, depth one highlight over one shadow line.
   STORY: A teacher with four minutes before the bell scans two labelled
     regions, sees at a glance what exists and what is coming, and takes one
     instrument off the board onto the projector.
   FIRST VIEWPORT: Top rail with the collection's spec plate and three subject
     switches; the working strip stating what this is and what it needs;
     then the BIOLOGY region with the one hung instrument leading it.
   FORM: Lab shadow board, candidate 3 of my grounded structural list.
     Seed key 2fa067fd.

   The tokens below are deliberately duplicated from the simulation's own
   stylesheet rather than shared: each simulation folder has to keep running on
   its own from a memory stick with no network and no build step.
   ========================================================= */

:root{
  /* the case: petrol enamel, the colour lab and test gear was actually painted */
  --fascia:#1b2c48;
  --fascia-hi:#2b4066;
  --fascia-lo:#121f34;
  --fascia-ink:#f2efe6;
  --fascia-ink-2:#a9b8cf;

  /* cream panel inserts bolted into it */
  --panel:#d5d2c4;
  --panel-hi:#e6e3d5;
  --panel-lo:#c6c3b4;
  --panel-edge:#f2efe2;
  --card:#efeade;
  --chassis:#131f33;
  --chassis-dk:#0c1524;

  --ink:#1e201c;
  --ink-2:#46483f;
  --rule:#a9a79c;
  --rule-dk:#8e8c82;

  --screen:#0d1420;
  --screen-ink:#dfe6f0;
  --screen-ink-2:#9fb0c6;

  --oxy:#cf3038;
  --oxy-lit:#ff5f66;
  --deoxy:#2b6ed0;
  --deoxy-lit:#5c9dfb;
  --amber:#6f4708;
  --amber-lit:#e8a63a;
  --lamp-lit:#ffb733;
  --lamp-off:#7e8079;


  /* H&E STAIN — the violet-magenta a biology section actually comes out of a
     microscope stained with haematoxylin and eosin. It is the register the
     instrument uses to POINT: a held stage, a marked answer, a focus ring, a
     callout. It replaces the old amber attention colour, which is now the
     lamp, and it is the subject's own material rather than an accent. */
  --stain:#7b2d6b;
  --stain-lit:#e46bc4;
  --stain-deep:#4a1440;

  /* one display step, so the first thing on screen has some scale to it */
  --fs-display:clamp(1.5rem, 2.6vw, 2.15rem);

  --fs-legend-sm:.64rem;
  --fs-legend:.72rem;
  --fs-legend-lg:.80rem;
  --fs-body-sm:.82rem;
  --fs-body:.90rem;
  --fs-body-lg:.98rem;
  --fs-title:1.08rem;
  --fs-title-lg:1.24rem;
  --fs-data:1rem;
  --fs-data-lg:1.85rem;
  --fs-data-xl:3rem;

  --r:3px;
  --r-well:4px;
  --r-screen:2px;

  --edge-hi:rgba(255,255,255,.38);
  --edge-lo:rgba(0,0,0,.18);
  --lamp-seat:rgba(0,0,0,.48);
  --recess-deep:rgba(0,0,0,.55);

  --proud:inset 0 1px 0 var(--panel-edge), 0 1px 0 rgba(0,0,0,.30);
  --pressed:inset 0 1px 2px rgba(0,0,0,.34);
  --well:inset 0 1px 2px rgba(0,0,0,.28), inset 0 -1px 0 var(--panel-edge);
  --bezel:inset 0 2px 5px var(--recess-deep);
  --flush:inset 0 1px 0 var(--edge-hi);
  --raised:inset 0 1px 0 var(--edge-hi), 0 1px 0 var(--edge-lo);
  --seated:inset 0 1px 2px var(--lamp-seat);

  --font-legend:"Arial Narrow","Roboto Condensed","Liberation Sans Narrow","Nimbus Sans Narrow",Arial,system-ui,sans-serif;
  --font-data:ui-monospace,"Cascadia Mono","Segoe UI Mono",Menlo,Consolas,"DejaVu Sans Mono",monospace;
  --font-read:"Iowan Old Style",Charter,"Bitstream Charter",Georgia,"Times New Roman",serif;

  --focus:#1e201c;
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0; min-height:100%;
  font-family:var(--font-read); font-size:16px;
  color:var(--fascia-ink); background:var(--fascia);
  -webkit-font-smoothing:antialiased;
}

.tab,.region-legend,.plate-no,.plate-name,.station-open,
.outline-no,.outline-name,.outline-tag,.plate-spec dt,
.board-note,.foot-plate,.brand-text strong,.brand-text small,.strip-text h1{
  font-family:var(--font-legend);
}
.tab-no,.plate-no,.outline-no{
  font-family:var(--font-data);
  font-variant-numeric:tabular-nums;
}

:where(button,[href],[tabindex]):focus-visible{
  outline:3px solid var(--focus); outline-offset:2px;
}
.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
.skip-link{
  position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--ink); color:var(--panel); padding:10px 16px;
  font-family:var(--font-legend); font-weight:700;
  text-transform:uppercase; letter-spacing:.07em;
}
.skip-link:focus{left:0}
.noscript-note{
  margin:0; padding:13px 20px; text-align:center;
  background:var(--amber-lit); color:var(--ink);
  font-family:var(--font-legend); font-weight:700; letter-spacing:.04em;
}

/* =========================================================
   TOP RAIL — the same rail the instruments carry
   ========================================================= */
/* the rail is the same casting as the sheet below it */
.topbar{
  display:flex; align-items:stretch; gap:18px; flex-wrap:wrap;
  max-width:1540px; margin:0 auto;
  padding:12px 20px;
  background:var(--fascia);
  border-bottom:1px solid var(--chassis-dk);
  box-shadow:inset 0 1px 0 var(--fascia-hi), 0 1px 0 rgba(0,0,0,.30);
  position:sticky; top:0; z-index:40;
}

/* SUBJECT MARKS — a stained cell for biology, a ring for chemistry, drawn in
   the same monoline grammar as everything else in a reading window. They are
   wayfinding, not decoration: they name which subject a region or a plate
   belongs to, so a teacher scanning the board sorts it without reading. */
.mark{flex:0 0 auto; width:19px; height:19px; display:block}
.mark circle,.mark path{fill:none; stroke:currentColor; stroke-width:1.5;
  stroke-linecap:round; stroke-linejoin:round}
.mark .fill{fill:currentColor; stroke:none}
.region-legend .mark{color:var(--stain-lit)}
.plate-no .mark{color:var(--stain)}

.brand{
  display:flex; align-items:center; gap:11px; min-width:0;
  background:var(--panel); color:var(--ink); border:1px solid var(--chassis-dk);
  border-radius:var(--r); box-shadow:var(--well);
  padding:7px 13px 7px 11px;
}
.brand-mark{
  flex:0 0 auto; width:16px; height:16px; border-radius:50%;
  background:var(--lamp-off); border:1px solid var(--chassis-dk);
  box-shadow:var(--seated);
}
.brand-mark.lit{
  border-color:#8a5f14;
  animation:lamp-pulse 1.6s ease-in-out infinite;
}
/* a lub-dub, then a rest — the same rhythm the Interactive Heart's own
   identity lamp keeps time to, carried here rather than left steady */
@keyframes lamp-pulse{
  0%,100%{background:var(--lamp-off); box-shadow:var(--seated)}
  8%,20%{background:var(--lamp-lit); box-shadow:inset 0 1px 1px rgba(255,255,255,.45), 0 0 4px var(--lamp-lit)}
  30%{background:var(--lamp-off); box-shadow:var(--seated)}
  38%,50%{background:var(--lamp-lit); box-shadow:inset 0 1px 1px rgba(255,255,255,.45), 0 0 4px var(--lamp-lit)}
  60%{background:var(--lamp-off); box-shadow:var(--seated)}
}
.brand-text{display:flex; flex-direction:column; line-height:1.15; min-width:0}
.brand-text strong{
  font-size:var(--fs-body-lg); font-weight:700;
  text-transform:uppercase; letter-spacing:.09em; color:var(--ink);
}
.brand-text small{
  font-size:var(--fs-legend-sm); font-weight:700;
  text-transform:uppercase; letter-spacing:.10em; color:var(--ink-2);
}

.tabs{display:flex; gap:5px; flex:1; flex-wrap:wrap; justify-content:center; align-items:center}
.tab{
  appearance:none; cursor:pointer; display:flex; align-items:center; gap:8px;
  min-height:42px; padding:9px 13px 9px 10px;
  background:var(--panel); color:var(--ink-2);
  border:1px solid var(--rule-dk); border-radius:var(--r);
  font-size:var(--fs-legend-lg); font-weight:700;
  text-transform:uppercase; letter-spacing:.07em;
  box-shadow:var(--flush);
  transition:background .12s, color .12s, box-shadow .12s;
}
.tab-no{
  flex:0 0 auto; width:17px; height:17px; border-radius:50%;
  display:grid; place-items:center;
  background:var(--chassis-dk); color:var(--panel-edge);
  border:1px solid #2b2a26; box-shadow:var(--seated);
  font-size:var(--fs-legend-sm); font-weight:700; line-height:1;
}
.tab:hover{background:var(--panel-hi); color:var(--ink)}
.tab:active{box-shadow:var(--pressed)}
.tab.is-active{
  background:var(--panel-hi); color:var(--ink);
  border-color:var(--chassis); box-shadow:var(--proud);
}
.tab.is-active .tab-no{
  background:var(--lamp-lit); color:#2e1c02;
  box-shadow:inset 0 1px 1px rgba(255,255,255,.45), 0 0 4px var(--lamp-lit);
}

/* =========================================================
   THE SHEET
   ========================================================= */
.sheet{max-width:1500px; margin:0 auto; padding:20px}

/* ---- the working strip ---- */
.strip{
  display:grid; grid-template-columns:minmax(0,1fr) auto;
  gap:24px 32px; align-items:end;
  padding:0 2px 18px; margin-bottom:20px;
  border-bottom:1px solid var(--chassis-dk);
  box-shadow:0 1px 0 var(--fascia-hi);
}
.strip-text{min-width:0}
/* a full sentence, so it is set as one — caps are for legends and plate names */
/* the board's opening line, at real display scale */
.strip-text h1{
  margin:0 0 10px; font-family:var(--font-legend);
  font-size:var(--fs-display); font-weight:700;
  letter-spacing:.005em; line-height:1.08; color:var(--fascia-ink);
}
.strip-text p{
  margin:0; font-size:var(--fs-body); line-height:1.65;
  color:var(--fascia-ink-2); max-width:68ch;
}

/* The collection's rating plate. Deliberately not three big-number tiles:
   that stat row is the most recognisable dashboard tell there is, and it made
   "Built 1" the largest thing a teacher read. */
.strip-plate{
  display:flex; flex-wrap:wrap; gap:6px 22px; margin:0;
  padding:10px 13px;
  background:var(--panel); border:1px solid var(--chassis-dk);
  border-radius:var(--r); box-shadow:var(--well);
  font-family:var(--font-legend); font-size:var(--fs-legend-sm); font-weight:700;
  text-transform:uppercase; letter-spacing:.1em; color:var(--ink-2);
}
.strip-plate b{font-family:var(--font-data); color:var(--ink); font-weight:700}

/* =========================================================
   THE BENCH
   One authored drawing, not a texture: the actual furniture of a school
   biology lab, with the pig carrying its heart marked in stain so the band
   says where the specimen in BIO/01 comes from.
   ========================================================= */
.bench{margin:0 0 22px}
.bench-art{display:block; width:100%; height:auto; max-height:210px}
.bench-art .ink path,
.bench-art .ink circle,
.bench-art .ink ellipse{
  fill:none; stroke:var(--fascia-ink-2); stroke-width:2.2;
  stroke-linecap:round; stroke-linejoin:round;
  vector-effect:non-scaling-stroke; opacity:.75;
}
/* these need to outrank the blanket rule above, which is two classes plus an
   element — so they carry three classes rather than relying on order */
.bench-art .ink .fill{fill:var(--fascia-ink-2); stroke:none; opacity:.75}
/* anything biological is stained, the way a section on a slide is */
.bench-art .ink .stain{stroke:var(--stain-lit); opacity:.95}
.bench-art .ink .stain-fill{fill:var(--stain-lit); stroke:none; opacity:.95}
.bench-art .ink .bench-line{stroke:var(--fascia-ink-2); opacity:.5}

/* the pig is drawn in the same monoline grammar as the apparatus either side
   of it; only its heart is stained */
.bench-art .ink .pig .stain-fill{fill:var(--stain-lit); stroke:none; opacity:1}

@media (max-width:700px){
  /* on a phone the bench crops to the biology half rather than shrinking
     every object past legibility */
  .bench-art{max-height:140px}
  .bench{overflow:hidden}
  .bench-art{width:180%; margin-left:-46%}
}

/* =========================================================
   THE BOARD
   ========================================================= */
.board{display:flex; flex-direction:column; gap:26px}

.region[hidden]{display:none}
.region-legend{
  display:flex; align-items:center; gap:12px;
  margin:0 0 13px;
  font-size:var(--fs-legend); font-weight:700;
  text-transform:uppercase; letter-spacing:.14em; color:var(--fascia-ink);
}
/* the region's own screened rule across the enamel */
.region-legend::after{
  content:""; flex:1; height:1px; background:var(--chassis-dk);
  box-shadow:0 1px 0 var(--fascia-hi);
}

/* a fixed-pitch grid of positions: an instrument and its empty outline
   occupy exactly the same footprint, which is the point of a shadow board */
.positions{
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(255px, 1fr));
  gap:14px;
  align-items:stretch;
}

.station{position:relative; min-height:322px; border-radius:var(--r)}

/* the small tab each plate hangs from — two hairlines, not texture */
.hanger{
  position:absolute; top:-7px; left:50%; width:44px; height:7px;
  transform:translateX(-50%);
  background:var(--panel-lo);
  border:1px solid var(--rule-dk); border-bottom:0;
  border-radius:2px 2px 0 0;
}
.hanger::after{
  content:""; position:absolute; inset:2px 6px auto; height:1px;
  background:var(--chassis);
}

/* ---------- a hung instrument ---------- */
.station.is-hung{
  display:flex; flex-direction:column;
  background:var(--card); color:var(--ink);
  border:1px solid var(--chassis-dk);
  box-shadow:var(--raised);
  transition:box-shadow .12s, transform .12s;
}
.station.is-hung:hover{box-shadow:var(--proud); transform:translateY(-1px)}
.station.is-hung:focus-within{box-shadow:var(--proud)}

/* the instrument's face, behind glass, exactly like the app's reading window */
.station-window{
  display:block; position:relative; margin:8px 8px 0;
  background:var(--screen);
  border:5px solid var(--chassis-dk); border-radius:var(--r-screen);
  box-shadow:var(--bezel);
  text-decoration:none;
}
.station-window::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(223,230,240,.10);
}
.station-window svg{display:block; width:100%; height:auto}
/* line art in the panel's own grammar: monoline, screened, no fills */
.station-window .ln path,.station-window .ln circle{
  fill:none; stroke:var(--screen-ink-2); stroke-width:2.2;
  stroke-linecap:round; stroke-linejoin:round;
}
.station-window .ln .thin{stroke-width:1.5; opacity:.75}

.station-plate{display:flex; flex-direction:column; flex:1; padding:12px 13px 13px}
.plate-no{
  display:flex; align-items:center; gap:7px;
  margin:0 0 6px; padding-bottom:6px; border-bottom:1px solid var(--rule);
  font-size:var(--fs-legend-sm); font-weight:700;
  letter-spacing:.11em; color:var(--ink-2);
}
.plate-name{
  margin:0 0 3px; font-size:var(--fs-title); font-weight:700;
  text-transform:uppercase; letter-spacing:.045em; line-height:1.18; color:var(--ink);
}
.plate-sub{
  margin:0 0 11px; font-family:var(--font-read); font-style:italic;
  font-size:var(--fs-body-sm); line-height:1.45; color:var(--ink-2);
}

/* the spec table: a real plate lists its ratings */
.plate-spec{margin:0 0 13px; display:flex; flex-direction:column; gap:5px}
.plate-spec > div{display:flex; gap:10px; align-items:baseline}
.plate-spec dt{
  flex:0 0 78px; font-size:var(--fs-legend-sm); font-weight:700;
  text-transform:uppercase; letter-spacing:.09em; color:var(--ink-2);
}
.plate-spec dd{
  margin:0; flex:1; font-family:var(--font-read);
  font-size:var(--fs-body-sm); line-height:1.45; color:var(--ink);
}

/* taking it off the board */
.station-open{
  margin-top:auto; display:flex; align-items:center; justify-content:center; gap:9px;
  min-height:42px; padding:11px 14px;
  background:var(--panel-hi); color:var(--ink);
  border:1px solid var(--chassis); border-radius:var(--r);
  box-shadow:var(--proud); text-decoration:none;
  font-family:var(--font-legend); font-size:var(--fs-legend-lg); font-weight:700;
  text-transform:uppercase; letter-spacing:.09em;
  transition:background .12s, box-shadow .12s;
}
.station-open:hover{background:var(--panel-edge)}
.station-open:active{box-shadow:var(--pressed)}
.open-lamp{
  flex:0 0 auto; width:9px; height:9px; border-radius:50%;
  background:var(--lamp-lit); border:1px solid #8a5f14;
  box-shadow:0 0 4px var(--lamp-lit);
}

/* ---------- a painted outline: the position is empty ----------
   Not an empty box. A shadow board paints the silhouette of the tool that
   belongs here, and keeps the hook, so the absence is legible as a specific
   missing instrument rather than as a gap in a grid. */
.station.is-outline{
  display:flex; flex-direction:column; justify-content:center; align-items:center;
  gap:5px; padding:18px 16px 16px; text-align:center;
  background:transparent;
  border:1px dashed var(--fascia-hi);
  box-shadow:none;
}
.station.is-outline .hanger{background:transparent; border-style:dashed; border-color:var(--fascia-hi)}
.station.is-outline .hanger::after{display:none}

/* the silhouette itself: painted on the board, not lit in a window */
.outline-art{
  display:block; width:min(58%, 132px); height:auto; margin:0 auto 6px;
}
.outline-art path,.outline-art circle,.outline-art ellipse{
  fill:none; stroke:var(--fascia-ink-2); stroke-width:2.4; opacity:.62;
  stroke-linecap:round; stroke-linejoin:round;
  vector-effect:non-scaling-stroke;
}
.station.is-outline .outline-no{
  margin:0; font-size:var(--fs-legend-sm); font-weight:700;
  letter-spacing:.11em; color:var(--fascia-ink-2);
}
.station.is-outline .outline-name{
  margin:0; font-size:var(--fs-body); font-weight:700;
  text-transform:uppercase; letter-spacing:.05em; line-height:1.25; color:var(--fascia-ink);
  max-width:18ch;
}
.station.is-outline .outline-tag{
  margin:4px 0 0; padding:3px 9px;
  font-size:var(--fs-legend-sm); font-weight:700;
  text-transform:uppercase; letter-spacing:.09em; color:var(--fascia-ink-2);
  border:1px dashed var(--fascia-hi);
}

.board-note{
  margin:4px 0 0; font-size:var(--fs-legend); font-weight:700;
  text-transform:uppercase; letter-spacing:.08em; color:var(--fascia-ink-2);
}

/* =========================================================
   FOOT — a riveted plate at the bottom of the chassis
   ========================================================= */
.foot{padding:0 20px 26px; max-width:1500px; margin:0 auto}
.foot-plate{
  display:flex; flex-wrap:wrap; gap:8px 26px; margin:0;
  padding:12px 14px;
  background:var(--panel); border:1px solid var(--chassis-dk);
  border-radius:var(--r); box-shadow:var(--well);
  font-size:var(--fs-legend-sm); font-weight:700;
  text-transform:uppercase; letter-spacing:.1em; color:var(--ink-2);
}
.foot-plate span:first-child{color:var(--ink)}
.foot-note{
  margin:10px 2px 0; max-width:70ch;
  font-family:var(--font-read); font-size:var(--fs-body-sm);
  line-height:1.6; color:var(--fascia-ink-2);
}

/* =========================================================
   RESPONSIVE
   ========================================================= */
@media (max-width:900px){
  .strip{grid-template-columns:1fr; align-items:start; gap:16px}
  .tabs{
    order:3; flex:1 0 100%; justify-content:flex-start; gap:4px;
    overflow-x:auto; flex-wrap:nowrap; padding-bottom:2px; scrollbar-width:thin;
  }
  .tabs .tab{flex:0 0 auto; padding:9px 11px 9px 9px}
}
@media (max-width:560px){
  .topbar{padding:10px 12px; gap:9px}
  .brand-text small{display:none}
  .sheet{padding:14px}
  .foot{padding:0 14px 20px}
  .positions{grid-template-columns:1fr}
  .station{min-height:0}
  .station.is-outline{min-height:130px}
}

@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  *{animation-duration:.01ms !important; transition-duration:.01ms !important;
    scroll-behavior:auto !important}
  /* the generic rule above would otherwise leave an "infinite" pulse running
     at a near-zero duration, which reads as a rapid strobe rather than no
     motion at all — worse for a photosensitive reader than the original */
  .brand-mark.lit{animation:none !important; background:var(--lamp-lit);
    box-shadow:inset 0 1px 1px rgba(255,255,255,.45), 0 0 4px var(--lamp-lit)}
}
