/* ==========================================================================
   HYDRAULICS TRAINER
   Dark blueprint theme. Mobile first. No external assets, no web fonts.

   1.  Tokens
   2.  Reset and base
   3.  Blueprint sheet background
   4.  App bar
   5.  Buttons and controls
   6.  Panels, sections, type
   7.  Symbol plates (SVG rendering)
   8.  Home screen
   9.  Learn: index grid and flashcard
   10. Quiz
   11. Circuit sheet
   12. Progress and settings
   13. Toast, utilities, motion
   ========================================================================== */

/* 1. TOKENS ================================================================ */

:root {
  /* Specified palette */
  --bg:        #0E2A3D;
  --grid:      #1C4258;
  --text:      #EDEFF2;
  --accent:    #4FC3E8;
  --success:   #57C785;
  --warning:   #F2A93B;
  --flow-p:  #FF6B6B;   /* pressure, the pump side */
  --flow-t:  #4FC3E8;   /* return, on its way to tank */
  --flow-building: #FFE066; /* pressure rising, not fully there yet */
  --flow-falling:  #9B8FD9; /* pressure dropping, not fully dumped yet */
  --flow-building-low:  #FFF3B0; /* rising, still early / low magnitude */
  --flow-building-high: #E8940B; /* rising, nearly there / high magnitude */
  --flow-falling-high:  #7A5FBF; /* dropping, still high magnitude */
  --flow-falling-low:   #C7BEEA; /* dropping, nearly bled off */

  /* Derived working colours (kept inside the specified palette) */
  --panel:     #12354B;
  --panel-2:   #16415A;
  --line:      #1C4258;
  --line-soft: rgba(28, 66, 88, 0.65);
  --muted:     #8AA6BA;
  --muted-2:   #5F819A;
  --accent-wash:  rgba(79, 195, 232, 0.12);
  --success-wash: rgba(87, 199, 133, 0.12);
  --warning-wash: rgba(242, 169, 59, 0.12);

  /* Type */
  --font-ui:   system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, "Roboto Mono", "DejaVu Sans Mono", Menlo, Consolas, monospace;

  /* Metrics */
  --r:      4px;         /* Corner radius: engineering drawings are square-ish */
  --r-lg:   6px;
  --gap:    14px;
  --pad:    16px;
  --bar-h:  56px;
  --tap:    44px;        /* Minimum touch target */
  --dur:    170ms;
  --ease:   cubic-bezier(.22, .61, .36, 1);
}

/* 2. RESET AND BASE ======================================================== */

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
}

html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 16px;
  line-height: 1.5;
  overflow-x: hidden;
  overscroll-behavior-y: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-font-smoothing: antialiased;
}

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }

h1, h2, h3, h4, p, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }

a { color: var(--accent); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* 3. BLUEPRINT SHEET BACKGROUND ============================================ */
/* Fine 22px grid with a heavier 110px grid over it: a drawing sheet, not decoration. */

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right,  var(--line-soft) 1px, transparent 1px),
    linear-gradient(to bottom, var(--line-soft) 1px, transparent 1px),
    linear-gradient(to right,  var(--line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--line) 1px, transparent 1px);
  background-size: 22px 22px, 22px 22px, 110px 110px, 110px 110px;
  opacity: .5;
}

.view {
  position: relative;
  z-index: 1;
  max-width: 560px;
  margin: 0 auto;
  padding: calc(var(--bar-h) + env(safe-area-inset-top) + 12px) var(--pad)
           calc(40px + env(safe-area-inset-bottom));
}

.view:focus { outline: none; }

.noscript {
  position: relative;
  z-index: 2;
  margin: 90px auto;
  max-width: 420px;
  padding: 20px;
  border: 1px solid var(--warning);
  color: var(--warning);
  font-family: var(--font-mono);
  font-size: 13px;
}

/* 4. APP BAR =============================================================== */

.appbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 10px;
  height: calc(var(--bar-h) + env(safe-area-inset-top));
  padding: env(safe-area-inset-top) 12px 0;
  background: rgba(14, 42, 61, 0.92);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}

.appbar__back {
  flex: 0 0 auto;
  width: var(--tap);
  height: var(--tap);
  display: grid;
  place-items: center;
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--r);
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.appbar__back:active { background: var(--panel); }
.appbar.is-root .appbar__back { visibility: hidden; }

.chev {
  width: 9px; height: 9px;
  border-left: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(45deg);
  margin-left: 3px;
}

.appbar__titles { flex: 1 1 auto; min-width: 0; }

.appbar__eyebrow {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted-2);
  line-height: 1;
  margin-bottom: 3px;
}

.appbar__title {
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -.005em;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.appbar__chip {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .1em;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--r);
  padding: 4px 8px;
  background: var(--accent-wash);
}

/* 5. BUTTONS AND CONTROLS ================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--tap);
  padding: 0 18px;
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: var(--r);
  font-size: 15px;
  font-weight: 500;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
.btn:active { transform: translateY(1px); }

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #08202F;
  font-weight: 600;
}
.btn--wide  { width: 100%; }
.btn--warn  { border-color: var(--warning); color: var(--warning); background: transparent; }
.btn[disabled] { opacity: .4; pointer-events: none; }

.btn-row {
  display: flex;
  gap: 10px;
  margin-top: 18px;
}
.btn-row > * { flex: 1 1 0; }

/* Segmented control */
.seg {
  display: flex;
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
}
.seg button {
  flex: 1 1 0;
  min-height: 40px;
  background: transparent;
  border: 0;
  border-right: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .06em;
  color: var(--muted);
}
.seg button:last-child { border-right: 0; }
.seg button.is-on { background: var(--accent-wash); color: var(--accent); }

/* Switch row */
.switch {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  width: 100%;
  min-height: 52px;
  padding: 8px 0;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--line);
  text-align: left;
}
.switch:last-child { border-bottom: 0; }
.switch__label { font-size: 14.5px; }
.switch__sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.switch__box {
  flex: 0 0 auto;
  width: 46px; height: 26px;
  border: 1px solid var(--line);
  border-radius: 13px;
  background: var(--bg);
  position: relative;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.switch__box::after {
  content: "";
  position: absolute;
  top: 3px; left: 3px;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--muted-2);
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease);
}
.switch[aria-checked="true"] .switch__box { border-color: var(--accent); background: var(--accent-wash); }
.switch[aria-checked="true"] .switch__box::after { transform: translateX(20px); background: var(--accent); }

/* 6. PANELS, SECTIONS, TYPE ================================================ */

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--pad);
}
.panel + .panel { margin-top: var(--gap); }

.eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--muted-2);
}

/* Section heading with a rule running to the right edge: drawing-sheet annotation */
.section {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 22px 0 10px;
}
.section__label {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--accent);
  white-space: nowrap;
}
.section__rule {
  flex: 1 1 auto;
  height: 1px;
  background: var(--line);
}

.lede { font-size: 15px; color: var(--text); }
.sub  { font-size: 13px; color: var(--muted); }
.mono { font-family: var(--font-mono); }

.bullets li {
  position: relative;
  padding-left: 18px;
  font-size: 14.5px;
  margin-bottom: 9px;
  color: var(--text);
}
.bullets li:last-child { margin-bottom: 0; }
.bullets li::before {
  content: "";
  position: absolute;
  left: 0; top: 9px;
  width: 7px; height: 7px;
  border: 1px solid var(--accent);
  transform: rotate(45deg);
}

.note {
  border-left: 2px solid var(--warning);
  background: var(--warning-wash);
  padding: 12px 14px;
  border-radius: 0 var(--r) var(--r) 0;
  font-size: 14.5px;
}

/* 7. SYMBOL PLATES ========================================================= */
/* The supplied ISO SVGs are black line art. They are loaded as files and
   inverted in CSS so they read as white line work on the blueprint. Line
   weights differ between source files, so a per-symbol glow (--boost, set by
   app.js from the source stroke width) evens them up optically. */

.plate {
  position: relative;
  display: grid;
  /* An explicit track. With an auto row the symbol's percentage height is
     circular, so the browser drops it, width wins and tall symbols overflow. */
  grid-template-rows: minmax(0, 1fr);
  place-items: center;
  background:
    radial-gradient(circle at 50% 45%, rgba(79,195,232,.07), transparent 62%),
    var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
}

/* Corner ticks: drawing frame */
.plate::before, .plate::after {
  content: "";
  position: absolute;
  width: 12px; height: 12px;
  border: 1px solid var(--line);
  pointer-events: none;
}
.plate::before { top: 6px;    left: 6px;    border-right: 0; border-bottom: 0; }
.plate::after  { bottom: 6px; right: 6px;   border-left: 0;  border-top: 0; }

.sym {
  display: block;
  object-fit: contain;
  filter:
    invert(1) brightness(.955)
    drop-shadow(0 0 var(--boost, 0px) #fff)
    drop-shadow(0 0 var(--boost, 0px) #fff);
}

/* Inside a plate the symbol is sized from its own aspect ratio, never
   stretched to the box. Both dimensions are auto and both are capped, which
   is the one fitting rule that needs nothing resolved from the parent.
   The caps below are each plate's height less its padding.
   Circuit nodes set their own width and height and are not matched here. */
.plate .sym {
  width: auto;
  height: auto;
  max-width: 100%;
}
.tile__plate .sym      { max-height: 72px; }
.flash__plate .sym     { max-height: 176px; }
.q__plate .sym         { max-height: 148px; }
.compare__plate .sym   { max-height: 68px; }
.miss-item__plate .sym { max-height: 38px; }
.weak-row__plate .sym  { max-height: 34px; }

/* Composed valve ----------------------------------------------------------
   Body, actuation tiles and ports are separate elements laid out from the
   measured geometry. Everything inside is positioned as a percentage of the
   stage, so one size on .valve scales the whole assembly. */
.valve { position: relative; overflow: hidden; }
.valve__slide {
  position: absolute;
  inset: 0;
  transition: transform 300ms var(--ease);
}
.valve .sym {
  position: absolute;
  max-width: none;
  max-height: none;
  object-fit: fill;
}
.valve__act.is-mirrored { transform: scaleX(-1); }

/* The ports belong to the housing, so they sit outside the sliding group */
.valve__ports { position: absolute; inset: 0; pointer-events: none; }
.vport { width: 100%; height: 100%; overflow: visible; }
/* Flow colours. Red for pressure and blue for return is the convention on a
   workshop wall chart, tuned here so both stay legible on the dark sheet.
   A dead port is dimmed rather than recoloured: it is carrying nothing. */
.vport__line {
  stroke-width: 3;
  vector-effect: non-scaling-stroke;
}
.vport__line.is-pressure { stroke: var(--flow-p); }
.vport__line.is-return   { stroke: var(--flow-t); }
.vport__line.is-blocked  { stroke: var(--muted); opacity: .55; }

.vport__arrow { fill: var(--text); opacity: 0; }
.vport__ports, .valve__ports { pointer-events: none; }
.valve__ports.is-flowing .vport__arrow.is-down {
  animation: vflow-down 1.5s linear infinite;
}
.valve__ports.is-flowing .vport__arrow.is-up {
  animation: vflow-up 1.5s linear infinite;
}
@keyframes vflow-down {
  0%   { transform: translateY(0);    opacity: 0; }
  18%  { opacity: 1; }
  82%  { opacity: 1; }
  100% { transform: translateY(24px); opacity: 0; }
}
@keyframes vflow-up {
  0%   { transform: translateY(0);     opacity: 0; }
  18%  { opacity: 1; }
  82%  { opacity: 1; }
  100% { transform: translateY(-24px); opacity: 0; }
}

/* Circuit-sheet pressure states: a wire's role sets its colour, the same
   four values a flashcard's own port stubs use, plus two in-between ones
   for "not fully there yet" states. Flow direction is shown the same way
   the flashcards already show it — a small white arrow travelling the
   line, fading in and out, looping — just generalised from a fixed 24px
   stub to an arbitrary bent path via CSS offset-path, since a circuit wire
   can be any length or shape a stub never has to be. */
.wire.is-pressure { background: var(--flow-p); }
.wire.is-return   { background: var(--flow-t); }
.wire.is-building { background: var(--flow-building); }
.wire.is-falling  { background: var(--flow-falling); }
.wire.is-building_low  { background: var(--flow-building-low); }
.wire.is-building_high { background: var(--flow-building-high); }
.wire.is-falling_high  { background: var(--flow-falling-high); }
.wire.is-falling_low   { background: var(--flow-falling-low); }
.wire.is-blocked, .wire.is-off { background: var(--muted); opacity: .55; }
.wire-flow-arrow {
  position: absolute; left: 0; top: 0; width: 0; height: 0;
  clip-path: polygon(0 0, 0 100%, 100% 50%);
  background: var(--text); width: 9px; height: 8px;
  opacity: 0; pointer-events: none;
}
.wire-flow-arrow.is-flowing {
  animation-name: wire-flow;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  animation-duration: var(--wire-flow-duration, 2s);
}
@keyframes wire-flow {
  0%   { offset-distance: 0%;   opacity: 0; }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { offset-distance: 100%; opacity: 0; }
}
.state-stepper { display: flex; flex-wrap: wrap; gap: 6px; }
.state-note { opacity: .8; font-size: .9em; }
.wire-bar-label {
  position: absolute; color: var(--text); font-family: ui-monospace, monospace;
  font-size: 11px; background: rgba(8,32,46,0.85); padding: 1px 4px; border-radius: 3px;
  pointer-events: none; white-space: nowrap;
}

.vport__tag {
  fill: var(--text);
  font-family: var(--font-mono);
  font-size: 21px;
  font-weight: 600;
  letter-spacing: .04em;
}

/* Legend, so the two colours are never a guess */
.vflow-key {
  display: flex;
  gap: 16px;
  margin: 0 0 10px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: .06em;
  color: var(--muted);
}
.vflow-key span { display: flex; align-items: center; gap: 6px; }
.vflow-key i {
  width: 14px; height: 0;
  border-top: 3px solid currentColor;
  display: block;
}
.vflow-key .is-p { color: var(--flow-p); }
.vflow-key .is-t { color: var(--flow-t); }
.vflow-key .is-x { color: var(--muted); opacity: .7; }
/* The stage lets the port letters show; the clip box inside it hides the
   spool as it slides past the edges */
.valve { overflow: visible; }
.valve__clip { position: absolute; inset: 0; overflow: hidden; }
.valve__plate { overflow: hidden; }

/* Valve position selector -------------------------------------------------- */
.vstate { margin: -4px 0 16px; }
.vstate__hint {
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--muted);
  margin: 0 0 10px;
}
.vstate__btns { display: flex; gap: 6px; margin-bottom: 10px; }
.vstate__btn {
  flex: 1 1 0;
  padding: 9px 6px;
  font-size: 12px;
  line-height: 1.25;
  min-height: 42px;
}
.vstate__btn.is-on {
  border-color: var(--accent);
  color: var(--accent);
  background: rgba(79, 195, 232, .10);
}
.vstate__read {
  border-left: 2px solid var(--accent);
  padding: 9px 12px;
  background: rgba(255, 255, 255, .025);
  border-radius: 0 var(--r) var(--r) 0;
}
.vstate__flow {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .02em;
  color: var(--accent);
}
.vstate__effect { margin: 4px 0 0; font-size: 13.5px; color: var(--text); }

.plate__code {
  position: absolute;
  right: 8px; top: 7px;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .12em;
  color: var(--muted-2);
}

/* 8. HOME ================================================================== */

.hero {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 18px var(--pad) 16px;
}

.hero__row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
}

.hero__level {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .18em;
  color: var(--muted);
  text-transform: uppercase;
}
.hero__name {
  font-size: 19px;
  font-weight: 600;
  margin-top: 3px;
}
.hero__sub {
  margin: 12px 0 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--muted);
}
.hero__pct {
  font-family: var(--font-mono);
  font-size: 34px;
  font-weight: 500;
  line-height: 1;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.hero__pct small { font-size: 15px; color: var(--muted); margin-left: 2px; }

/* Segmented completion bar: 4 tracked areas, visibly separate */
.meter {
  display: flex;
  gap: 3px;
  margin-top: 14px;
}
.meter__seg {
  flex: 1 1 0;
  height: 6px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 2px;
  overflow: hidden;
}
.meter__fill {
  display: block;
  height: 100%;
  background: var(--accent);
  transition: width 420ms var(--ease);
}
.meter__fill.is-done { background: var(--success); }

.meter-key {
  display: flex;
  gap: 3px;
  margin-top: 7px;
}
.meter-key span {
  flex: 1 1 0;
  font-family: var(--font-mono);
  font-size: 8.5px;
  letter-spacing: .1em;
  color: var(--muted-2);
  text-transform: uppercase;
  text-align: center;
}

.menu { margin-top: 20px; }

.menu-item {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  min-height: 68px;
  padding: 12px 14px;
  margin-bottom: 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-left: 2px solid var(--line);
  border-radius: var(--r);
  text-align: left;
  transition: border-left-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.menu-item:active { background: var(--panel-2); }
.menu-item.is-live { border-left-color: var(--accent); }
.menu-item.is-locked { opacity: .55; }

.menu-item__code {
  flex: 0 0 auto;
  width: 38px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .08em;
  color: var(--accent);
}
.menu-item__body { flex: 1 1 auto; min-width: 0; }
.menu-item__title { display: block; font-size: 15.5px; font-weight: 600; }
.menu-item__sub { display: block; font-size: 12.5px; line-height: 1.45; color: var(--muted); margin-top: 3px; }
.menu-item__meta {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* 9. LEARN ================================================================= */

.filters {
  display: flex;
  gap: 7px;
  overflow-x: auto;
  padding-bottom: 4px;
  margin: 0 calc(var(--pad) * -1) 14px;
  padding-left: var(--pad);
  padding-right: var(--pad);
  scrollbar-width: none;
}
.filters::-webkit-scrollbar { display: none; }
.chip {
  flex: 0 0 auto;
  min-height: 34px;
  padding: 0 13px;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 17px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}
.chip.is-on { border-color: var(--accent); color: var(--accent); background: var(--accent-wash); }

.grid-symbols {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
@media (min-width: 460px) {
  .grid-symbols { grid-template-columns: repeat(3, 1fr); }
}

.tile {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  text-align: left;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.tile:active { background: var(--panel-2); }
.tile.is-seen { border-color: rgba(87,199,133,.45); }
.tile__plate { height: 96px; padding: 12px; }
.tile__name { font-size: 12.5px; line-height: 1.3; }
/* Learn: search and grouping ---------------------------------------------- */
.search { margin-bottom: 10px; }
.search__input {
  width: 100%;
  padding: 11px 13px;
  font: inherit;
  font-size: 14px;
  color: var(--text);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  -webkit-appearance: none;
}
.search__input::placeholder { color: var(--muted); }
.search__input:focus { outline: none; border-color: var(--accent); }

/* Spot the symbol: the options are drawings rather than words --------------- */
.tile__cat {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted-2);
}

/* Flashcard */
.flash__plate {
  height: 236px;
  padding: 30px;
  margin-bottom: 16px;
}
.flash__cat {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--accent);
}
.flash__name {
  font-size: 22px;
  font-weight: 600;
  line-height: 1.2;
  margin-top: 6px;
  letter-spacing: -.01em;
}

.pager {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 22px;
}
.pager__count {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.pager .btn { flex: 1 1 0; }

.compare {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 4px;
  scrollbar-width: none;
}
.compare::-webkit-scrollbar { display: none; }
.compare__item {
  flex: 0 0 108px;
  padding: 8px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  text-align: left;
}
.compare__plate { height: 84px; padding: 8px; margin-bottom: 6px; }
.compare__name { font-size: 11px; line-height: 1.25; color: var(--muted); }

/* 10. QUIZ ================================================================= */

.qbar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
}
.qbar__track {
  flex: 1 1 auto;
  height: 4px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 2px;
  overflow: hidden;
}
.qbar__fill {
  display: block;
  height: 100%;
  background: var(--accent);
  transition: width 300ms var(--ease);
}
.qbar__count {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.q__plate { height: 196px; padding: 24px; margin-bottom: 14px; }
.q__ask {
  font-size: 15px;
  font-weight: 600;
  margin-bottom: 14px;
  line-height: 1.35;
}

.opts { display: grid; gap: 9px; }

.opt {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: var(--tap);
  padding: 11px 13px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  text-align: left;
  font-size: 14.5px;
  line-height: 1.35;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.opt__key {
  flex: 0 0 auto;
  width: 22px; height: 22px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 2px;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--muted);
}
.opt.is-correct { border-color: var(--success); background: var(--success-wash); }
.opt.is-correct .opt__key { border-color: var(--success); color: var(--success); }
.opt.is-wrong { border-color: var(--warning); background: var(--warning-wash); }
.opt.is-wrong .opt__key { border-color: var(--warning); color: var(--warning); }
.opts.is-locked .opt { pointer-events: none; }

/* Spot the symbol: the options are drawings rather than words. These rules
   come after .opt deliberately, because they override its flex layout. */
.opts--pics {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.opt--pic {
  display: block;
  padding: 8px;
  min-height: 0;
}
.opt--pic .opt__key { margin-bottom: 7px; }
.pick__plate { height: 112px; padding: 10px; }
.pick__plate .sym { max-height: 92px; }
.opt--pic.is-correct .pick__plate { border-color: var(--success); }
.opt--pic.is-wrong .pick__plate { border-color: var(--warning); }

/* The question sits under the drawings here: the symbols are what the
   learner is reading, so they come first. */
.q__ask--after { margin-top: 16px; }

.verdict {
  margin-top: 16px;
  padding: 13px 14px;
  border: 1px solid var(--line);
  border-left-width: 2px;
  border-radius: 0 var(--r) var(--r) 0;
  font-size: 14px;
}
.verdict.is-ok   { border-left-color: var(--success); background: var(--success-wash); }
.verdict.is-bad  { border-left-color: var(--warning); background: var(--warning-wash); }
.verdict__head {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
  margin-bottom: 6px;
}
.verdict.is-ok  .verdict__head { color: var(--success); }
.verdict.is-bad .verdict__head { color: var(--warning); }

/* Result screen */
.score {
  text-align: center;
  padding: 26px 16px 22px;
}
.score__pct {
  font-family: var(--font-mono);
  font-size: 62px;
  line-height: 1;
  font-weight: 500;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.score__pct.is-pass { color: var(--success); }
.score__sub { font-size: 14px; color: var(--muted); margin-top: 8px; }

.miss-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 8px 10px;
  margin-bottom: 8px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  text-align: left;
}
.miss-item__plate { flex: 0 0 54px; height: 46px; padding: 4px; }
.miss-item__name { font-size: 13.5px; }

/* 11. CIRCUIT SHEET ======================================================== */

.sheet {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background:
    linear-gradient(to right,  var(--line-soft) 1px, transparent 1px) 0 0 / 22px 22px,
    linear-gradient(to bottom, var(--line-soft) 1px, transparent 1px) 0 0 / 22px 22px,
    var(--bg);
  overflow: hidden;
}

.sheet__frame {
  position: relative;
  overflow: hidden;
}

.stage {
  position: relative;
  transform-origin: top left;
}

/* Flow lines: plain divs so nothing is drawn in script that pretends to be a symbol */
.wire {
  position: absolute;
  background: var(--accent);
  opacity: .85;
}
.wire--pilot { background: var(--muted); opacity: .7; }
/* Junction dots read as the difference between a tee and a crossover, so they
   have to be unmistakable at the size a circuit is drawn on a phone. */
.dot {
  position: absolute;
  width: 11px; height: 11px;
  margin: -5.5px 0 0 -5.5px;
  border-radius: 50%;
  background: var(--accent);
}

/* A composed valve on a circuit sheet. Sized by the circuit, not by the
   fitting pass, so it must not be measured like a flashcard plate. */
.node__valve { position: absolute; top: 50%; left: 50%; overflow: visible; }
.node__valve .valve__clip { overflow: visible; }

.node {
  position: absolute;
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r);
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.node__img { position: absolute; top: 50%; left: 50%; }
.node.is-hit    { border-color: var(--success); background: var(--success-wash); }
.node.is-miss   { border-color: var(--warning); background: var(--warning-wash); }
.node.is-solved { border-color: rgba(87,199,133,.45); }

/* The stage is scaled with one transform, so the tag counter-scales itself
   with --inv (set by fitSheet) to stay legible on a phone. */
.node__tag {
  position: absolute;
  left: 50%;
  bottom: -13px;
  transform-origin: 50% 0;
  transform: translateX(-50%) scale(var(--inv, 1));
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .06em;
  color: var(--accent);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}
.sheet.is-labelled .node__tag { opacity: 1; }

/* Title block: bottom-right corner of an engineering drawing */
.titleblock {
  display: grid;
  grid-template-columns: 1fr auto auto;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-2);
}
.titleblock > div {
  padding: 7px 10px;
  border-right: 1px solid var(--line);
}
.titleblock > div:last-child { border-right: 0; color: var(--accent); }

.task {
  margin-top: 14px;
  padding: 14px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
}
.task__no {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .18em;
  color: var(--muted-2);
  text-transform: uppercase;
}
.task__ask { font-size: 15px; font-weight: 600; margin-top: 5px; line-height: 1.35; }
.task__fb  { font-size: 14px; margin-top: 10px; }
.task__fb.is-ok  { color: var(--success); }
.task__fb.is-bad { color: var(--warning); }

/* 12. PROGRESS AND SETTINGS ================================================ */

.stat {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 0;
  border-bottom: 1px solid var(--line);
}
.stat:last-child { border-bottom: 0; }
.stat__body { flex: 1 1 auto; min-width: 0; }
.stat__name { font-size: 14.5px; }
.stat__sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.stat__val {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 16px;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.stat__val.is-done { color: var(--success); }

.gate {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
  font-size: 14px;
}
.gate__box {
  flex: 0 0 auto;
  width: 18px; height: 18px;
  border: 1px solid var(--muted-2);
  border-radius: 2px;
  position: relative;
}
.gate.is-met .gate__box { border-color: var(--success); background: var(--success-wash); }
.gate.is-met .gate__box::after {
  content: "";
  position: absolute;
  left: 5px; top: 1px;
  width: 5px; height: 10px;
  border-right: 2px solid var(--success);
  border-bottom: 2px solid var(--success);
  transform: rotate(42deg);
}

.weak-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 0;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--line);
  text-align: left;
}
.weak-row__plate { flex: 0 0 46px; height: 40px; padding: 3px; }
.weak-row__name { flex: 1 1 auto; font-size: 13.5px; }
.weak-row__val {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--warning);
  font-variant-numeric: tabular-nums;
}

.empty {
  padding: 26px 16px;
  text-align: center;
  color: var(--muted);
  font-size: 14px;
  border: 1px dashed var(--line);
  border-radius: var(--r);
}

/* 13. TOAST, UTILITIES, MOTION ============================================= */

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(24px + env(safe-area-inset-bottom));
  transform: translate(-50%, 16px);
  z-index: 40;
  max-width: 88vw;
  padding: 11px 16px;
  background: var(--panel-2);
  border: 1px solid var(--accent);
  border-radius: var(--r);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--text);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.toast.is-on { opacity: 1; transform: translate(-50%, 0); }

.screen { animation: rise 200ms var(--ease) both; }
@keyframes rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

.shake { animation: shake 240ms var(--ease); }
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}

.hr { height: 1px; background: var(--line); margin: 20px 0; }
.mt { margin-top: 16px; }
.vh {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
}
body.no-motion *, body.no-motion *::before, body.no-motion *::after {
  animation-duration: 1ms !important;
  transition-duration: 1ms !important;
}

/* 14. NAVIGATION ============================================================
   One menu button in the appbar opens everything secondary. The level screen
   carries the level's own work, so adding a feature does not mean adding
   another permanent control to the chrome.
   ========================================================================== */

/* Menu button, shown only where the back button is not */
.appbar__menu {
  flex: 0 0 auto;
  width: var(--tap); height: var(--tap);
  display: none;
  place-items: center;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  cursor: pointer;
}
.appbar.is-root .appbar__menu { display: grid; }
.appbar.is-root .appbar__back { display: none; }
.burger, .burger::before, .burger::after {
  display: block;
  width: 16px; height: 1.5px;
  background: var(--accent);
  border-radius: 1px;
}
.burger { position: relative; }
.burger::before, .burger::after { content: ""; position: absolute; left: 0; }
.burger::before { top: -5px; }
.burger::after  { top: 5px; }

/* Drawer ------------------------------------------------------------------ */
.drawer { position: fixed; inset: 0; z-index: 60; }
.drawer__scrim {
  position: absolute; inset: 0;
  background: rgba(4, 16, 24, .62);
  animation: fade var(--dur) var(--ease);
}
.drawer__panel {
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: min(84vw, 320px);
  overflow-y: auto;
  background: var(--panel);
  border-right: 1px solid var(--line);
  padding: 18px 14px calc(18px + env(safe-area-inset-bottom));
  animation: slide-in 220ms var(--ease);
}
@keyframes slide-in { from { transform: translateX(-100%); } to { transform: none; } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

.drawer__brand { margin: 0 0 2px; font-size: 15px; font-weight: 600; }
.drawer__sub {
  margin: 0 0 16px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .08em;
  color: var(--muted);
}
.drawer__item {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 12px 12px;
  margin-bottom: 6px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--text);
  text-align: left;
  font-size: 14.5px;
  cursor: pointer;
}
.drawer__item.is-on { border-color: var(--accent); color: var(--accent); }
.drawer__code {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .08em;
  color: var(--muted);
  width: 26px;
}
.drawer__item.is-on .drawer__code { color: var(--accent); }

/* 15. CATEGORY INDEX AND FLOATING PAGER =====================================
   ========================================================================== */

.cat-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-bottom: 4px;
}
.cat {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.cat:active { transform: scale(.985); }
.cat--wide { grid-column: 1 / -1; }

/* One drawing in a square tile, several across a full width one */
.cat__art { display: flex; gap: 8px; }
.cat__art > * { flex: 1 1 0; min-width: 0; }
.cat__plate { height: 88px; padding: 8px; }
.cat__plate .sym { max-height: 72px; }

.cat__name { font-size: 14px; font-weight: 600; line-height: 1.25; }
.cat__count {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .07em;
  color: var(--muted);
}

/* The pager stays on screen instead of waiting at the end of a long card */
.pager--float {
  position: fixed;
  left: 0; right: 0;
  bottom: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
  background: linear-gradient(to top,
    var(--bg) 55%,
    color-mix(in srgb, var(--bg) 80%, transparent));
  border-top: 1px solid var(--line);
}
.pager--float .btn { flex: 1 1 0; }
.pager--float .pager__count {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .06em;
  color: var(--muted);
}
/* the card has to clear it */
.screen--card { padding-bottom: 74px; }

/* Drawer level rows */
.drawer__label {
  margin: 16px 0 8px;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .1em;
  color: var(--muted);
}
.drawer__item--level { gap: 9px; }
.drawer__name { flex: 1 1 auto; }
.drawer__meta {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: .06em;
  color: var(--muted);
}
.drawer__item.is-locked { opacity: .5; cursor: default; }

/* Diagnostics -------------------------------------------------------------- */
.appbar__diag {
  display: none;
  flex: 0 0 auto;
  width: 30px; height: 30px;
  margin-left: 6px;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 12px;
  cursor: pointer;
}
.appbar.has-diag .appbar__diag { display: flex; }

.diag {
  position: fixed;
  inset: 12px;
  z-index: 80;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  background: var(--panel);
  border: 1px solid var(--accent);
  border-radius: var(--r);
}
.diag__title { margin: 0; font-size: 14px; font-weight: 600; }
.diag__text {
  flex: 1 1 auto;
  width: 100%;
  resize: none;
  padding: 10px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.5;
}

/* Reading order balloons ---------------------------------------------------- */
.valve__marks { position: absolute; inset: 0; pointer-events: none; }
.vmark__dot {
  fill: var(--bg);
  stroke: var(--accent);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
}
.vmark__n {
  fill: var(--accent);
  font-family: var(--font-mono);
  font-size: 15px;
  font-weight: 600;
}

.vmarks { margin: 0 0 14px; }
.vmarks__row {
  display: flex;
  align-items: baseline;
  gap: 9px;
  padding: 7px 0;
  border-bottom: 1px solid var(--line);
}
.vmarks__n {
  flex: 0 0 20px;
  height: 20px;
  display: grid;
  place-items: center;
  border: 1px solid var(--accent);
  border-radius: 50%;
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 10.5px;
}
.vmarks__name { flex: 0 0 auto; font-size: 14px; font-weight: 600; }
.vmarks__what { flex: 1 1 auto; font-size: 12.5px; color: var(--muted); }
.vmarks__note {
  margin: 9px 0 0;
  font-size: 12px;
  color: var(--muted);
}

/* The level screen is meant to fit without scrolling, so its list is tighter
   than a list the learner arrives at after already scrolling. */
.menu--tight .menu-item {
  min-height: 56px;
  padding: 9px 13px;
  margin-bottom: 7px;
  gap: 12px;
}
.menu--tight .menu-item__title { font-size: 14.5px; }
.menu--tight .menu-item__sub { font-size: 11.5px; margin-top: 1px; }
.hero { padding: 15px var(--pad) 14px; }
