/* ============================================================================
   SeeFOP - WINDOWS 95
   A CFOP workbench dressed as a mid-90s application: teal desktop, a maximised
   silver window with a navy title bar, raised/sunken bevels, a beveled Start
   taskbar with a live clock. The GAN-style cube is the document inside.
   ----------------------------------------------------------------------------
   PRESERVED (consumed by JS / Three.js / SVG diagrams - do not rename):
     --s-U..--s-L, --plastic ............ cube + groove colours (diagrams, thumbnails)
     --signal ........................... 3D arrow colour (read by app.js arrowColor())
     --arrow-x .......................... tooltip arrow position (set by JS)
     --i ................................ chapter stagger index (set by JS)
     .scene/.cube-rotator/.cube/.layer-group/.cubie/.cubie-face/.sticker/.s-*
        .................................. CSS-3D skeleton for renderStatic thumbnails
   ============================================================================ */

/* ---------- vendored type: Pixelated MS Sans Serif (offline, file://) ---------- */
@font-face { font-family: "Pixelated MS Sans Serif"; font-style: normal; font-weight: 400; font-display: swap; src: url("vendor/fonts/ms-sans-serif.woff2") format("woff2"); }
@font-face { font-family: "Pixelated MS Sans Serif"; font-style: normal; font-weight: 500; font-display: swap; src: url("vendor/fonts/ms-sans-serif.woff2") format("woff2"); }
@font-face { font-family: "Pixelated MS Sans Serif"; font-style: normal; font-weight: 600; font-display: swap; src: url("vendor/fonts/ms-sans-serif-bold.woff2") format("woff2"); }
@font-face { font-family: "Pixelated MS Sans Serif"; font-style: normal; font-weight: 700; font-display: swap; src: url("vendor/fonts/ms-sans-serif-bold.woff2") format("woff2"); }
@font-face { font-family: "Pixelated MS Sans Serif"; font-style: normal; font-weight: 800; font-display: swap; src: url("vendor/fonts/ms-sans-serif-bold.woff2") format("woff2"); }

/* CJK + Devanagari fallbacks for ja / ko / hi - the pixel font has no glyphs there. Prepended onto the
   font stack only for those scripts (i18n.js sets <html data-script>), so other locales keep the Win95 look. */
@font-face { font-family: "Noto Sans JP"; font-style: normal; font-weight: 400; font-display: swap; src: url("vendor/fonts/noto-sans-jp-400.woff2") format("woff2"); }
@font-face { font-family: "Noto Sans KR"; font-style: normal; font-weight: 400; font-display: swap; src: url("vendor/fonts/noto-sans-kr-400.woff2") format("woff2"); }
@font-face { font-family: "Noto Sans Devanagari"; font-style: normal; font-weight: 400; font-display: swap; src: url("vendor/fonts/noto-sans-devanagari-400.woff2") format("woff2"); }
@font-face { font-family: "Noto Sans SC"; font-style: normal; font-weight: 400; font-display: swap; src: url("vendor/fonts/noto-sans-sc-400.woff2") format("woff2"); }
html[data-script="jp"]   { --font-ui: "Noto Sans JP", "Pixelated MS Sans Serif", system-ui, sans-serif; --font-mono: "Noto Sans JP", "Pixelated MS Sans Serif", monospace; }
html[data-script="kr"]   { --font-ui: "Noto Sans KR", "Pixelated MS Sans Serif", system-ui, sans-serif; --font-mono: "Noto Sans KR", "Pixelated MS Sans Serif", monospace; }
html[data-script="deva"] { --font-ui: "Noto Sans Devanagari", "Pixelated MS Sans Serif", system-ui, sans-serif; --font-mono: "Noto Sans Devanagari", "Pixelated MS Sans Serif", monospace; }
html[data-script="zh"]   { --font-ui: "Noto Sans SC", "Pixelated MS Sans Serif", system-ui, sans-serif; --font-mono: "Noto Sans SC", "Pixelated MS Sans Serif", monospace; }

:root {
  /* cube + groove - READ BY JS (diagrams.js SVGs + renderStatic thumbnails). KEEP.
     These are the pre-JS defaults; applyPalette() overwrites them at startup. Match the default palette. */
  --s-U: #f2d216;  --s-D: #f7f7f2;  --s-F: #2bb673;
  --s-B: #2d8fd5;  --s-R: #ef8f2a;  --s-L: #e44d42;
  --plastic: #20222b;

  /* type - one bitmap system font, like the real thing */
  --font-ui:   "Pixelated MS Sans Serif", "MS Sans Serif", Tahoma, Geneva, system-ui, sans-serif;
  --font-mono: "Pixelated MS Sans Serif", "MS Sans Serif", Tahoma, Geneva, system-ui, sans-serif;

  /* Win95 system palette */
  --ground:   #008080;          /* the teal desktop */
  --paper:    #c0c0c0;          /* silver - window + control face */
  --paper-2:  #c0c0c0;          /* silver panels (editable areas go white explicitly) */
  --stage-bg: #c0c0c0;          /* cube client area */
  --field:    #ffffff;          /* white sunken fields / lists */
  /* cube backdrop: a soft lit "studio" pool so the cube does not float on flat grey */
  --stage-1:  #d3dbe4;  --stage-2: #aab4c2;  --stage-3: #7c8694;
  --stage-vig: rgba(16, 22, 40, .22);
  /* the win95 cube viewport: a flat teal desktop field (dithered live by the WebGL post pass) */
  --vp-1: #008080;  --vp-2: #008080;

  --ink:    #000000;            /* black text */
  --ink-2:  #000000;            /* keep readable black on silver */
  --ink-3:  #404040;            /* dim labels */

  /* "borders" are mostly bevels; these are the flat dividers / single hairlines */
  --line:   #808080;
  --line-2: #000000;

  /* navy is the accent: title bars, selection highlight, 3D arrows */
  --signal:      #000080;
  --signal-ink:  #000080;
  --signal-soft: #d4d8f0;       /* faint selected wash */

  --good:     #008000;          /* DOS green */
  --good-dot: #04b404;

  --outline:  #2b3a55;          /* muted ink-navy for the cube's dashed slot/cross guides (read by cube3d) */

  /* legacy aliases consumed by inline styles (help-modal keycaps) */
  --accent-soft: #dfdfdf;
  --accent-text: #000000;

  --grid:       transparent;    /* no engineering grid */
  --grid-major: transparent;

  --scrim: rgba(0, 0, 64, .28);

  --r-lg: 0; --r-md: 0; --r-sm: 0;   /* sharp corners everywhere */

  /* the bevels that make the look (4-layer inset technique) */
  --bevel-out:  inset -1px -1px #0a0a0a, inset 1px 1px #ffffff, inset -2px -2px #808080, inset 2px 2px #dfdfdf;   /* raised control */
  --bevel-in:   inset -1px -1px #ffffff, inset 1px 1px #808080, inset -2px -2px #dfdfdf, inset 2px 2px #0a0a0a;   /* pressed control */
  --bevel-win:  inset -1px -1px #0a0a0a, inset 1px 1px #dfdfdf, inset -2px -2px #808080, inset 2px 2px #ffffff;   /* raised window/panel */
  --bevel-field: inset -1px -1px #ffffff, inset 1px 1px #808080, inset -2px -2px #dfdfdf, inset 2px 2px #0a0a0a;  /* sunken white field */
  --title-grad: linear-gradient(90deg, #000080 0%, #1084d0 100%);

  --shadow: none; --shadow-soft: none; --canvas-shadow: none;
}

/* dark theme: a midnight desktop + a deep-slate cube backdrop. Windows stay silver. */
:root[data-theme="dark"] {
  --ground:   #1a1a2e;
  --scrim:    rgba(0, 0, 0, .5);
  --good:     #04b404;
  --outline:  #9fb3d6;          /* lighter steel-blue guides for the dark cube backdrop */
  --stage-1:  #4c5564;  --stage-2: #353d49;  --stage-3: #1f242d;
  --stage-vig: rgba(0, 0, 0, .42);
  --vp-1: #008080;  --vp-2: #008080;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font-ui);
  font-size: 11px;
  color: var(--ink);
  background: var(--ground);
  height: 100vh; height: 100dvh; overflow: hidden;
  display: flex; flex-direction: column;
  -webkit-font-smoothing: none;
  transition: background-color .2s ease;
}

/* subtle assembly on load */
@keyframes rise { from { opacity: 0; } to { opacity: 1; } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

/* ---------- title bar (the app's caption) ---------- */
.appbar {
  flex: 0 0 30px; display: flex; align-items: center; gap: 8px;
  padding: 0 3px 0 5px; margin: 3px 3px 0;
  background: var(--title-grad); color: #fff;
  animation: rise .25s ease both;
  position: relative; z-index: 8;   /* lift above the workspace so the language dropdown isn't clipped (modals are z-9) */
}
.brand {
  display: flex; align-items: baseline; gap: 7px;
  font-weight: 700; font-size: 13px; letter-spacing: 0; text-transform: none; color: #fff;
}
.brand-mark { font-size: 15px; color: #fff; transform: none; }
.brand-tag { font-size: 11px; letter-spacing: 0; font-weight: 400; color: #cfd6f7; }
.brand-tag::before { content: "- "; }
.appbar-status { display: flex; align-items: center; gap: 12px; margin-left: auto; padding-right: 4px; }
.status {
  display: inline-flex; align-items: center; gap: 6px;
  font-weight: 400; font-size: 11px; letter-spacing: 0; text-transform: none;
  color: #e6e8ff; padding: 0; background: transparent; box-shadow: none;
}
.status::before { content: ""; width: 7px; height: 7px; border-radius: 0; background: #c0c0c0; box-shadow: var(--bevel-field); }
.status[data-state="solved"]   { color: #b6f0b6; box-shadow: none; background: transparent; }
.status[data-state="solved"]::before   { background: var(--good-dot); }
.status[data-state="scrambled"] { color: #ffe08a; background: transparent; box-shadow: none; }
.status[data-state="scrambled"]::before { background: #ffcf3a; }
.movecount { font-size: 11px; color: #dfe2ff; font-weight: 400; font-variant-numeric: tabular-nums; letter-spacing: 0; }

/* caption buttons on the title bar (method / theme / help) */
.appbar .iconbtn,
.method-btn {
  height: 22px; min-width: 22px; border: none; background: #c0c0c0; color: #000;
  box-shadow: var(--bevel-out); border-radius: 0; cursor: pointer;
  font-family: var(--font-ui); display: inline-grid; place-items: center; transition: none;
}
.appbar .iconbtn { width: 22px; font-size: 13px; padding: 0; }
.method-btn { padding: 0 9px; font-weight: 700; font-size: 11px; letter-spacing: 0; text-transform: none; }
.appbar .iconbtn:hover, .method-btn:hover { background: #c0c0c0; color: #000; }
.appbar .iconbtn:active, .method-btn:active { box-shadow: var(--bevel-in); }
/* appbar language picker - a custom Win95 combobox (native <select> can't show flags or be themed).
   The font stack carries all scripts so CJK/Devanagari native names render even under a Latin locale. */
.lang-dd { position: relative; flex: 0 0 auto; }
.lang-dd-btn, .lang-dd-item {
  font-family: "Pixelated MS Sans Serif", "Noto Sans SC", "Noto Sans JP", "Noto Sans KR", "Noto Sans Devanagari", "MS Sans Serif", system-ui, sans-serif;
  font-size: 11px; letter-spacing: 0; text-transform: none; color: #000;
  display: flex; align-items: center; gap: 6px; cursor: pointer; border: none; border-radius: 0;
}
.lang-dd-btn { height: 22px; padding: 0 5px; background: #c0c0c0; box-shadow: var(--bevel-out); max-width: 150px; }
.lang-dd-btn.open, .lang-dd-btn:active { box-shadow: var(--bevel-in); }
.lang-dd-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lang-dd-caret { margin-left: auto; font-size: 8px; line-height: 1; padding-left: 4px; }
.lang-flag { width: 16px; height: 12px; object-fit: cover; box-shadow: 0 0 0 1px #808080; flex: 0 0 auto; display: block; }
.lang-dd-list {
  position: absolute; top: calc(100% + 2px); right: 0; z-index: 1000; min-width: 100%;
  background: var(--field); box-shadow: var(--bevel-out); padding: 2px; max-height: 340px; overflow-y: auto;
}
.lang-dd-item { width: 100%; padding: 3px 10px 3px 4px; background: transparent; text-align: left; white-space: nowrap; }
.lang-dd-item:hover, .lang-dd-item.sel { background: var(--signal); color: #fff; }

/* ---------- workspace: the window client area ---------- */
.workspace { flex: 1 1 auto; min-height: 0; display: flex; gap: 6px; padding: 6px; margin: 0 3px 3px; background: var(--paper); }
.stage {
  flex: 1 1 auto; min-width: 0; position: relative;
  display: flex; align-items: center; justify-content: center;
  border-radius: 0;
  /* flat win95 field; the WebGL post pass paints the dithered teal over this fallback */
  background: var(--vp-2);
  border: none; overflow: hidden;
  animation: rise .3s ease both;
}
.stage::before { content: none; }
/* the sunken client bevel, drawn ON TOP of the opaque cube canvas so the win95 frame survives */
.stage::after { content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none; box-shadow: var(--bevel-field); }
.cube-host { position: absolute; inset: 0; z-index: 1; }
.cube-host canvas { filter: none; }
.cube-arrows { position: absolute; inset: 0; pointer-events: none; z-index: 5; }
/* Bottom-of-viewport overlay: a Win95 status field (which step the solver is on) stacked ABOVE the
   nav-tip hint. A flex column anchored to the bottom edge, so the two stack with a real gap and can
   NEVER overlap no matter how the hint wraps. (The status replaces the old tick progress bar, which
   sat on top of the hint.) When the status is hidden, only the hint remains, sitting at bottom:8px. */
.cube-footer {
  position: absolute; left: 0; right: 0; bottom: 8px; z-index: 6;
  display: flex; flex-direction: column; align-items: center; gap: 6px; pointer-events: none;
}
/* Win95 status field: names the step the solver is currently on, e.g. "F2L pair · 3 / 7" ("Solved" at
   the end). Only shown during solve playback; hidden otherwise (so it leaves the flex flow entirely). */
.cube-status {
  display: inline-flex; align-items: center; gap: 6px; pointer-events: none;
  max-width: calc(100% - 24px); white-space: nowrap;
  padding: 2px 8px; background: var(--paper); box-shadow: var(--bevel-out);
  font-family: var(--font-ui); font-size: 11px; font-weight: 400; letter-spacing: 0; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.cube-status[hidden] { display: none; }
.cube-status::before {
  content: ""; flex: 0 0 auto; width: 7px; height: 7px; border-radius: 0;
  background: var(--signal); box-shadow: var(--bevel-field);
}
.cube-status.done::before { background: var(--good-dot); }
.stage-hint {
  margin: 0; text-align: center; max-width: calc(100% - 16px);
  font-family: var(--font-ui); font-size: 10px; letter-spacing: 0; text-transform: none;
  color: rgba(255,255,255,.74); text-shadow: 0 1px 1px rgba(0,0,0,.45); font-weight: 400; pointer-events: none;
}

/* ===== AutoCAD-style ViewCube (a real Three.js mesh in .vc-canvas) ===== */
.viewcube { position: absolute; top: 10px; left: 10px; z-index: 7; width: 120px; height: 120px;
  opacity: .6; transition: opacity .18s ease; touch-action: none; }
.viewcube:hover, .viewcube.grabbing { opacity: 1; }
.viewcube.grabbing { cursor: grabbing; }
.vc-host { position: absolute; inset: 0; cursor: grab; }
.vc-canvas { display: block; width: 120px; height: 120px; }
.vc-home {
  position: absolute; top: 0; left: 0; z-index: 1; width: 22px; height: 22px; padding: 0;
  cursor: pointer; display: grid; place-items: center; border-radius: 0;
  color: #000; background: #c0c0c0; border: none; box-shadow: var(--bevel-out); transition: none;
}
.vc-home:hover { background: #c0c0c0; color: #000; }
.vc-home:active { box-shadow: var(--bevel-in); }

/* ---------- sidebar: a docked control panel ---------- */
.sidebar {
  flex: 0 0 358px; min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: 8px;
  background: var(--paper); border-radius: 0; box-shadow: var(--bevel-win);
  padding: 8px; border: none;
  animation: rise .3s ease both;
}
.sidebar > #mode { width: 100%; }
/* always-on scrollbar (overflow:scroll, no scrollbar-gutter): the bar never pops in/out and there is no
   ugly reserved-empty gap. A full-height nested scroller (grid/inspector/trainer) owns the bar instead,
   so the outer .sidebar-body bar is suppressed via :has() to avoid a double scrollbar. */
.sidebar-body { flex: 1 1 auto; min-height: 0; overflow-y: scroll; overflow-x: hidden; display: flex; flex-direction: column; }
.sidebar-body:has(> .case-grid), .sidebar-body:has(> .inspector), .sidebar-body:has(> .pair-trainer) { overflow-y: hidden; padding-right: 0; }

/* Win95 chunky scrollbars (global: every scrollable surface) */
::-webkit-scrollbar { width: 17px; height: 17px; }
::-webkit-scrollbar-track {
  background-color: #c0c0c0;
  background-image: linear-gradient(45deg, #ffffff 25%, transparent 25%, transparent 75%, #ffffff 75%), linear-gradient(45deg, #ffffff 25%, transparent 25%, transparent 75%, #ffffff 75%);
  background-size: 2px 2px; background-position: 0 0, 1px 1px;
}
::-webkit-scrollbar-thumb { background: #c0c0c0; box-shadow: var(--bevel-out); border-radius: 0; }
::-webkit-scrollbar-corner { background: #c0c0c0; }
::-webkit-scrollbar-button { background: #c0c0c0; box-shadow: var(--bevel-out); display: block; height: 17px; width: 17px; background-repeat: no-repeat; background-position: center; }
::-webkit-scrollbar-button:active { box-shadow: var(--bevel-in); }
::-webkit-scrollbar-button:vertical:decrement { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M4 2L7 6H1Z' fill='%23000'/%3E%3C/svg%3E"); }
::-webkit-scrollbar-button:vertical:increment { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M1 2H7L4 6Z' fill='%23000'/%3E%3C/svg%3E"); }
::-webkit-scrollbar-button:horizontal:decrement { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M2 4L6 1V7Z' fill='%23000'/%3E%3C/svg%3E"); }
::-webkit-scrollbar-button:horizontal:increment { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M6 4L2 1V7Z' fill='%23000'/%3E%3C/svg%3E"); }
/* a single button at each end (hide the doubled inner ones) */
::-webkit-scrollbar-button:vertical:start:increment, ::-webkit-scrollbar-button:vertical:end:decrement,
::-webkit-scrollbar-button:horizontal:start:increment, ::-webkit-scrollbar-button:horizontal:end:decrement { display: none; }

/* Browsers WITHOUT ::-webkit-scrollbar (Firefox): a chunky grey baseline, and win95scroll.js draws a
   full Win95 bar (beveled track/thumb + arrow buttons) over the key scrollers, hiding the native one. */
@supports not selector(::-webkit-scrollbar) {
  * { scrollbar-width: auto; scrollbar-color: #c0c0c0 #e6e6e6; }
}
/* wherever the custom bar mounts: hide the native scrollbar (no-op in normal Chromium, class never added
   there) and reserve a CONSTANT 17px gutter for the overlay bar. Constant (not toggled) so it can't feed
   back into the bar's layout() and oscillate. */
.w95sb-host { scrollbar-width: none; padding-right: 17px; }
.w95sb-host::-webkit-scrollbar { width: 0; height: 0; }
/* modal with the custom overlay bar (Firefox): reserve a matching LEFT gutter so the cards stay centered
   (the overlay sits in the right 17px). Chromium modals use the native bar + scrollbar-gutter instead. */
.modal-body.w95sb-host { padding-left: 17px; padding-right: 25px; }
/* sidebar scrollbar breathing room: Firefox overlay bar needs full 28px (bar is outside),
   Chromium native just needs a bit of extra gap on top of its built-in gutter.
   The :has() override below zeros it out when child grids own their own scrollbar. */
.sidebar-body { padding-right: 8px; }
.sidebar-body.w95sb-visible { padding-right: 28px; }
.w95sb { position: fixed; width: 17px; box-sizing: border-box; display: flex; flex-direction: column; }
.w95sb-btn { flex: 0 0 17px; height: 17px; background-color: #c0c0c0; background-repeat: no-repeat; background-position: center; box-shadow: var(--bevel-out); }
.w95sb-btn.pressed { box-shadow: var(--bevel-in); }
.w95sb-up { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M4 2L7 6H1Z' fill='%23000'/%3E%3C/svg%3E"); }
.w95sb-down { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath d='M1 2H7L4 6Z' fill='%23000'/%3E%3C/svg%3E"); }
.w95sb-track { flex: 1 1 auto; position: relative; min-height: 0;
  background-color: #c0c0c0;
  background-image: linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%), linear-gradient(45deg, #fff 25%, transparent 25%, transparent 75%, #fff 75%);
  background-size: 2px 2px; background-position: 0 0, 1px 1px; }
.w95sb-thumb { position: absolute; left: 0; right: 0; background: #c0c0c0; box-shadow: var(--bevel-out); }

/* ============================================================================
   CSS-3D cube skeleton - used by renderStatic() for F2L thumbnails + inspector
   3D diagrams. Structure & --plastic/--s-* are load-bearing. PRESERVED.
   ============================================================================ */
.scene { width: 320px; height: 320px; perspective: 1400px; cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none; }
.scene.grabbing { cursor: grabbing; }
.scene.static { cursor: inherit; touch-action: auto; user-select: auto; }
.cube-rotator { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform .12s ease-out; }
.cube { position: absolute; left: 50%; top: 50%; width: 0; height: 0; transform-style: preserve-3d; }
.layer-group { position: absolute; left: 0; top: 0; width: 0; height: 0; transform-style: preserve-3d; }
.cubie { position: absolute; left: 0; top: 0; transform-style: preserve-3d; }
.cubie-face { position: absolute; left: 0; top: 0; background: var(--plastic); border-radius: 16px; backface-visibility: hidden; }
.sticker {
  position: absolute; inset: 0; border-radius: 16px; background-clip: padding-box;
  background-image: radial-gradient(125% 125% at 50% 40%,
    rgba(255,255,255,.12) 0%, rgba(255,255,255,0) 42%, rgba(0,0,0,.06) 80%, rgba(0,0,0,.12) 100%);
}
.sticker.s-U { background-color: var(--s-U); }
.sticker.s-D { background-color: var(--s-D); }
.sticker.s-F { background-color: var(--s-F); }
.sticker.s-B { background-color: var(--s-B); }
.sticker.s-R { background-color: var(--s-R); }
.sticker.s-L { background-color: var(--s-L); }
.cubie.glow .sticker { box-shadow: inset 0 0 0 3px var(--signal), inset 0 -3px 8px -3px rgba(0,0,0,.18); }
.cubie.dim .sticker { filter: saturate(.45) brightness(1.04); opacity: .82; }
.cubie.ghost .sticker { filter: saturate(.2) brightness(1.06); opacity: .42; }

/* ---------- mode switch (Solve / Learn) as a tab pair ---------- */
.segmented { display: flex; gap: 3px; background: transparent; border-radius: 0; padding: 0; border: none; }
.seg {
  flex: 1 1 0; border: none; background: #c0c0c0; cursor: pointer; padding: 7px 0; border-radius: 0;
  box-shadow: var(--bevel-out);
  font-family: var(--font-ui); font-weight: 700; font-size: 12px; letter-spacing: 0; text-transform: none;
  color: #000; transition: none;
}
.seg:hover:not(.active) { color: #000; }
.seg.active { background: var(--signal); color: #fff; box-shadow: var(--bevel-in); }

/* ---------- Solve panel ---------- */
.solve-panel { display: flex; flex-direction: column; gap: 10px; }
.scramble-split { display: flex; gap: 2px; }
.scramble-split .btn.primary { flex: 1 1 auto; border-radius: 0; padding: 9px 14px; }
.scramble-split .btn.primary.split { flex: 0 0 auto; border-radius: 0; padding: 9px 11px; margin-left: 0; font-size: 13px; }
.solve-actions { display: flex; gap: 6px; }
.solve-actions .iconbtn { flex: 1 1 auto; width: auto; }
.field { display: block; }
.palette-row { gap: 6px; }
.more { margin-top: 2px; }
.more > summary {
  list-style: none; cursor: pointer; padding: 4px 0;
  font-family: var(--font-ui); font-weight: 700; font-size: 11px; letter-spacing: 0; text-transform: none; color: #000;
  display: flex; align-items: center; gap: 6px;
}
.more > summary::-webkit-details-marker { display: none; }
.more > summary::before { content: "+"; font-size: 12px; color: #000; line-height: 0; }
.more[open] > summary::before { content: "\2013"; }

/* ---------- method solver: progress strip + Solve-next + playback (a Win95 group box) ---------- */
.solver-progress { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; padding: 0 1px; font-size: 11px; color: #000; }
.solver-prog-next { font-weight: 700; }
.ch-pbar.solver-pbar { margin-bottom: 0; }
.solve-actions .btn { flex: 1 1 auto; min-width: 0; }
.solve-actions .btn.solve-next { flex: 2 1 auto; }
.solve-actions .btn#solve-all, .solve-actions .btn#solve-inc { flex: 1 1 auto; }
.solve-panel .step-group { display: flex; flex-direction: column; gap: 8px; }
.solve-panel .linky.shuffle-summary { width: auto; align-self: flex-start; color: var(--signal); margin-top: -4px; }
.solve-panel .insp-scrub { margin-top: 0; }
.solve-panel .insp-scrub-lbl { background: var(--field); box-shadow: var(--bevel-field); padding: 5px 7px; min-width: 46px; }
.optrow { display: flex; align-items: center; gap: 9px; padding: 1px 1px; }
.optlbl { flex: 0 0 86px; font-family: var(--font-ui); font-size: 11px; color: #000; }
.optrow input[type=range] { flex: 1 1 auto; width: auto; }
/* an in-panel instance of the appbar's custom Win95 combobox (.lang-dd-*): fill the row, drop up to full width */
.w95-dd { flex: 1 1 auto; min-width: 0; }
.w95-dd .lang-dd-btn { width: 100%; max-width: none; height: 24px; }
.w95-dd .lang-dd-list { left: 0; right: 0; }

/* ---------- detect + F2L finder + pair trainer ---------- */
.detect-btn { margin-bottom: 8px; }
.detect-msg { font-family: var(--font-ui); font-size: 11px; font-weight: 400; color: #000; margin-bottom: 8px; line-height: 1.4; letter-spacing: 0; }
.detect-msg:empty { margin: 0; }
.detect-msg.hit { color: var(--signal-ink); font-weight: 700; }
.f2l-find { margin-bottom: 8px; }
.f2l-find.active { background: var(--signal); color: #fff; box-shadow: var(--bevel-in); }
.f2l-find-hint { font-family: var(--font-ui); font-size: 11px; font-weight: 400; color: #000; margin-bottom: 8px; line-height: 1.4; }
.f2l-find-hint:empty { margin: 0; }
.f2l-ways { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; flex: 0 0 auto; max-height: 46%; overflow-y: auto; overflow-x: hidden; padding: 2px; background: var(--field); box-shadow: var(--bevel-field); }
.f2l-ways:empty { margin: 0; padding: 0; box-shadow: none; background: transparent; }
.f2l-way {
  display: flex; flex-direction: column; gap: 2px; text-align: left; width: 100%;
  padding: 7px 9px; border: none; border-radius: 0; cursor: pointer;
  font-family: inherit; background: var(--field); color: #000; transition: none;
}
.f2l-way:hover { background: var(--signal); }
.f2l-way:hover .fw-name, .f2l-way:hover .fw-moves { color: #fff; }
.f2l-way.computed { cursor: default; }
.f2l-way.computed:hover { background: var(--field); }
.f2l-way.computed:hover .fw-name { color: #000; } .f2l-way.computed:hover .fw-moves { color: #404040; }
.fw-name { font-size: 12px; font-weight: 700; color: #000; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.fw-moves { font-family: var(--font-mono); font-size: 11px; font-weight: 400; color: #404040; white-space: normal; word-break: break-word; line-height: 1.35; }
.pair-trainer { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; animation: fade .15s ease; }
.pair-trainer .f2l-ways { max-height: none; flex: 1 1 auto; overflow-y: scroll; }
.pt-hint { flex: 0 0 auto; }
/* the station hint when the cube is positioned the taught way: a green "go" read */
.pt-hint.guide-ready { color: var(--good); font-weight: 700; }
.pt-prompt { padding: 16px 14px; border-radius: 0; background: var(--paper); box-shadow: var(--bevel-win);
  text-align: center; color: #000; font-weight: 700; line-height: 1.45; }
.pt-note { font-family: var(--font-mono); font-weight: 400; font-size: 13px; color: #000;
  background: var(--field); box-shadow: var(--bevel-field); border: none; border-radius: 0; padding: 8px 10px; margin: 5px 0 2px; word-break: break-word; }
.pt-actions { display: flex; flex-direction: column; gap: 7px; margin-top: 11px; flex: 0 0 auto; }
.pt-suggest { margin-left: auto; flex: 0 0 auto; white-space: nowrap; }
.pt-warn { font-family: var(--font-ui); font-size: 12px; font-weight: 700; color: #000; background: #ffffcc;
  border-radius: 0; padding: 8px 10px; margin: 6px 0 2px; box-shadow: var(--bevel-field); line-height: 1.4; }

/* ---------- Learn: filter + case grid ---------- */
.learn-filter { flex: 0 0 auto; display: flex; flex-direction: column; gap: 9px; margin-bottom: 9px; }
.learn-filter .alg-search { flex: 1 1 auto; }
.case-grid { flex: 1 1 auto; min-height: 0; overflow-y: scroll; overflow-x: hidden; display: grid; gap: 7px; padding: 4px; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); align-content: start; background: var(--field); box-shadow: var(--bevel-field); }
.case-grid.f2l { grid-template-columns: 1fr; }

/* ---------- inspector (inside the sidebar) ---------- */
.inspector { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; animation: fade .15s ease; }
.insp-scroll { flex: 1 1 auto; min-height: 0; min-width: 0; overflow-y: scroll; }
.inspector #insp-run { margin-top: 11px; flex: 0 0 auto; }
.insp-head { display: flex; align-items: center; gap: 9px; margin-bottom: 11px; }
.insp-head:empty { display: none; }
.insp-head .btn { padding: 6px 11px; }
.insp-title { font-family: var(--font-ui); font-weight: 700; font-size: 14px; letter-spacing: 0; }
.insp-diagram { display: flex; align-items: center; justify-content: center; padding: 2px 0 12px; }
.insp-diagram .diagram-svg { border-radius: 0; box-shadow: var(--bevel-field); background: var(--field); }
.insp-aim { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--paper); border-radius: 0; padding: 9px 12px; box-shadow: var(--bevel-win); }
.aim-face { font-family: var(--font-mono); font-weight: 700; font-size: 12px; letter-spacing: 0; color: var(--signal-ink); text-transform: uppercase; }
.insp-notation { margin: 11px 0 2px; }
.changed-note { text-align: center; font-family: var(--font-ui); font-size: 11px; font-weight: 700; color: var(--signal-ink); margin: 8px 0; }
.insp-scrub { display: flex; align-items: center; gap: 7px; margin-top: 11px; }
.insp-scrub input[type=range] { flex: 1 1 auto; min-width: 0; }
.insp-scrub .iconbtn { width: 30px; height: 28px; font-size: 12px; flex: 0 0 auto; }
.insp-scrub-lbl { font-family: var(--font-mono); font-size: 11px; font-weight: 400; color: #000; min-width: 42px; text-align: right; font-variant-numeric: tabular-nums; }
.insp-lock { margin: 2px 0 6px; padding: 8px 11px; }
/* out-specify .btn.ghost (equal-specificity, later in file) so the locked state keeps its navy fill */
.btn.insp-lock.active { background: var(--signal); color: #fff; box-shadow: var(--bevel-in); }

/* ---------- overlays: Win95 dialogs ---------- */
.modal { position: fixed; inset: 0; display: grid; place-items: center; z-index: 9; background: var(--scrim); -webkit-backdrop-filter: none; backdrop-filter: none; }
.modal[hidden] { display: none; }
.modal-card { background: var(--paper); border: none; border-radius: 0; box-shadow: var(--bevel-win); padding: 3px; width: min(508px, 94vw); max-height: 84vh; display: flex; flex-direction: column; overflow: hidden; animation: fade .12s ease; }
/* the dialog's own title bar: a non-scrolling flex header, so it stays pinned at the top */
.drawer-head { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; margin: 0 0 3px; padding: 4px 4px 4px 7px;
  background: var(--title-grad); border-bottom: none; }
/* scrollable, padded content area (width:100% children fit; no horizontal overflow).
   scrollbar-gutter:both-edges reserves a matching gutter on the left so the scrollbar can't make the
   left/right card margins unequal. */
.modal-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; scrollbar-gutter: stable both-edges; padding: 10px 11px 14px 3px; }
.drawer-head .section-title { margin: 0; color: #fff; font-weight: 700; font-size: 12px; letter-spacing: 0; text-transform: none; }
.drawer-head .section-title::before { content: none; }
.drawer-head .iconbtn { height: 20px; width: 22px; background: #c0c0c0; color: #000; box-shadow: var(--bevel-out); }
.drawer-head .iconbtn:active { box-shadow: var(--bevel-in); }
.popover { position: fixed; z-index: 10; background: var(--paper); border: none; border-radius: 0; box-shadow: var(--bevel-win); padding: 2px; display: flex; flex-direction: column; gap: 0; animation: fade .1s ease; }
.popover[hidden] { display: none; }
.popover button { border: none; background: transparent; font-family: var(--font-ui); font-weight: 400; font-size: 12px; cursor: pointer; padding: 5px 22px 5px 14px; border-radius: 0; color: #000; text-align: left; }
.popover button:hover { background: var(--signal); color: #fff; }
/* ---- Scramble generator modal ---- */
.chip.mini { padding: 2px 9px; font-size: 11px; }
.sg-types { display: flex; gap: 6px; margin: 2px 0 8px; }
.sg-types .chip { flex: 1; text-align: center; }
.sg-desc { font-size: 12px; color: var(--ink-3); margin: 0 0 8px; line-height: 1.4; }
.sg-section { margin: 12px 0; }
.sg-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 5px; }
.sg-title { font-family: var(--font-ui); font-weight: 700; font-size: 12px; color: #000; }
.sg-ctrls { display: flex; align-items: center; gap: 5px; }
.sg-count { font-size: 11px; color: #000; margin-right: 4px; }
.sg-note { font-size: 11px; color: var(--ink-3); margin-bottom: 6px; }
.sg-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(62px, 1fr)); gap: 6px; }
.sg-grid.f2l { grid-template-columns: repeat(auto-fill, minmax(78px, 1fr)); }
/* case card: selected = bright + navy ring; deselected = dimmed (so what you're practising is obvious) */
.sg-card { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 5px 3px 3px; background: var(--field); box-shadow: var(--bevel-field); cursor: pointer; border: none; opacity: .4; filter: grayscale(.65); transition: opacity .12s ease; }
.sg-card.on { opacity: 1; filter: none; box-shadow: var(--bevel-field), inset 0 0 0 2px var(--signal); }
.sg-card:hover { opacity: .85; }
.sg-card.on:hover { opacity: 1; }
.sg-dia { width: 54px; height: 54px; display: flex; align-items: center; justify-content: center; }
.sg-dia svg, .sg-dia canvas { display: block; }
.sg-label { font-family: var(--font-mono); font-size: 10px; color: #000; }
.sg-check { display: flex; align-items: center; gap: 6px; font-size: 12px; color: #000; cursor: pointer; margin: 6px 0; }
.sg-genrow { display: flex; align-items: center; gap: 6px; margin: 6px 0; }
.sg-genrow .btn { margin-left: auto; }
.sg-out { white-space: pre-wrap; word-break: break-word; font-family: var(--font-mono); font-size: 11px; line-height: 1.6; min-height: 44px; max-height: calc(84vh - 260px); overflow-y: auto; }
.sg-foot { display: flex; gap: 8px; justify-content: flex-end; margin-top: 14px; padding-bottom: 6px; background: var(--paper); box-shadow: 0 -1px 0 var(--line); }
/* saved-settings summary under the Scramble button (click to open the generator) */
.shuffle-summary { display: block; width: 100%; text-align: left; font-size: 11px; color: var(--ink-3); background: transparent; border: none; box-shadow: none; cursor: pointer; padding: 3px 2px; margin-top: -2px; }
.shuffle-summary:hover { color: var(--signal); text-decoration: underline; }

/* keyboard-shortcut flash */
@keyframes keyflash { 0% { box-shadow: var(--bevel-out); } 40% { box-shadow: var(--bevel-in); } 100% { box-shadow: var(--bevel-out); } }
.key-flash { animation: keyflash .3s steps(1) ; }

/* ---------- generic controls ---------- */
.section-title {
  display: flex; align-items: center; gap: 7px;
  font-family: var(--font-ui); font-size: 11px; text-transform: none; letter-spacing: 0;
  color: #000; font-weight: 700; margin: 0 0 9px;
}
.section-title::before { content: ""; width: 0; height: 0; }
.iconbtn {
  width: 34px; height: 32px; border: none; border-radius: 0; cursor: pointer;
  background: #c0c0c0; box-shadow: var(--bevel-out); font-size: 14px; color: #000; display: grid; place-items: center; transition: none;
}
.iconbtn:hover { background: #c0c0c0; color: #000; }
.iconbtn:active { box-shadow: var(--bevel-in); }

.method-card-wrap { width: min(528px, 94vw); }
.method-intro { font-size: 12px; color: #000; line-height: 1.5; margin: 0 0 13px; }
.method-card { display: grid; gap: 2px; width: 100%; text-align: left; cursor: pointer; margin-bottom: 8px; position: relative;
  border: none; background: var(--paper); border-radius: 0; padding: 11px 13px; box-shadow: var(--bevel-out); transition: none; }
.method-card:hover { background: var(--paper); }
.method-card.active { box-shadow: var(--bevel-in); background: #b8b8b8; }
.mc-name { font-weight: 700; font-size: 14px; color: #000; }
.mc-sub { font-family: var(--font-mono); font-weight: 400; font-size: 10.5px; letter-spacing: 0; text-transform: uppercase; color: var(--signal-ink); }
.mc-blurb { font-size: 12px; color: #000; line-height: 1.45; margin-top: 4px; }
.mc-tag { font-family: var(--font-mono); font-size: 10px; font-weight: 400; color: #404040; letter-spacing: 0; margin-top: 5px; }

.btn {
  font-family: var(--font-ui); font-weight: 700; font-size: 12px; letter-spacing: 0;
  border: none; cursor: pointer; border-radius: 0; background: #c0c0c0; box-shadow: var(--bevel-out);
  padding: 8px 14px; color: #000; transition: none;
}
.btn:hover { background: #c0c0c0; }
.btn:active { box-shadow: var(--bevel-in); }
.btn[disabled] { color: #808080; text-shadow: 1px 1px #fff; box-shadow: var(--bevel-out); cursor: not-allowed; }
.btn.primary { background: #c0c0c0; color: #000; box-shadow: var(--bevel-out), inset 0 0 0 2px transparent; outline: 1px solid #000; outline-offset: -4px; }
.btn.primary:active { box-shadow: var(--bevel-in); }
.btn.ghost { background: #c0c0c0; box-shadow: var(--bevel-out); }
.btn.ghost:active { box-shadow: var(--bevel-in); }
.btn.wide { width: 100%; }

.chips { display: flex; flex-wrap: wrap; gap: 5px; }
.chip {
  border: none; cursor: pointer; font-family: var(--font-ui); font-weight: 400; font-size: 12px;
  padding: 5px 11px; border-radius: 0; color: #000; background: #c0c0c0; box-shadow: var(--bevel-out); transition: none;
}
.chip:hover { color: #000; }
.chip:active { box-shadow: var(--bevel-in); }
.chip.active { background: var(--signal); color: #fff; box-shadow: var(--bevel-in); }
.chip:disabled { color: #808080; text-shadow: 1px 1px #fff; cursor: not-allowed; }
.chip:disabled:hover { color: #808080; }

/* fast styled tooltips (yellow Win95 hint) */
.tooltip {
  position: fixed; z-index: 1200; pointer-events: none; max-width: 230px;
  padding: 4px 7px; border-radius: 0; font-family: var(--font-ui); font-size: 11px; font-weight: 400; line-height: 1.3;
  color: #000; background: #ffffe1; border: 1px solid #000;
  opacity: 0; transition: opacity .1s ease; white-space: normal;
}
.tooltip.show { opacity: 1; transform: none; }
.tooltip::after { content: ''; position: absolute; left: var(--arrow-x, 50%); top: 100%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: #000; }
.tooltip.below::after { top: auto; bottom: 100%; border-top-color: transparent; border-bottom-color: #000; }
@media (prefers-reduced-motion: reduce) { .tooltip { transition: opacity .1s ease; transform: none; } }

/* forms - sunken white fields */
.field-label { font-family: var(--font-ui); font-size: 11px; font-weight: 700; letter-spacing: 0; text-transform: none; color: #000; margin-bottom: 6px; display: block; }
select, input[type="text"], input[type="search"] {
  font-family: var(--font-ui); font-size: 12px; font-weight: 400; color: #000;
  border: none; background: var(--field); box-shadow: var(--bevel-field); border-radius: 0; padding: 5px 8px; width: 100%;
}
input::placeholder { color: #5a5a5a; font-weight: 400; }
input:focus, select:focus { outline: 1px dotted #000; outline-offset: -4px; border-color: transparent; box-shadow: var(--bevel-field); }
/* Win95 trackbar: a sunken rail with a raised rectangular slider */
input[type="range"] { -webkit-appearance: none; appearance: none; width: 100%; height: 22px; background: transparent; cursor: pointer; }
input[type="range"]::-webkit-slider-runnable-track { height: 4px; background: var(--field); box-shadow: var(--bevel-field); border-radius: 0; }
input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 11px; height: 20px; margin-top: -8px; background: #c0c0c0; box-shadow: var(--bevel-out); border-radius: 0; }
input[type="range"]::-moz-range-track { height: 4px; background: var(--field); box-shadow: var(--bevel-field); }
input[type="range"]::-moz-range-thumb { width: 11px; height: 20px; background: #c0c0c0; box-shadow: var(--bevel-out); border: none; border-radius: 0; }

.seg:focus-visible, .iconbtn:focus-visible, .btn:focus-visible, .chip:focus-visible, .move-btn:focus-visible, .case-card:focus-visible {
  outline: 1px dotted #000; outline-offset: -4px;
}

/* notation readout - sunken white instrument display */
.notation {
  font-family: var(--font-mono); font-weight: 400; font-size: 13px; line-height: 1.7; letter-spacing: 0; color: #000;
  background: var(--field); box-shadow: var(--bevel-field); border: none; border-radius: 0; padding: 9px 11px; word-spacing: 3px; min-height: 40px;
}
/* per-token move spans so the move at the playhead can be outlined while a sequence plays/scrubs */
.notation .mv { display: inline-block; padding: 0 3px; margin: 0 1px; }
.notation .mv.current { background: var(--signal); color: #fff; font-weight: 700; box-shadow: var(--bevel-in); }
.hint { font-size: 11px; color: #000; font-weight: 400; line-height: 1.45; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 9px; }

/* ---------- move pad ---------- */
.pad-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 5px; margin-bottom: 8px; }
.move-btn {
  font-family: var(--font-mono); font-weight: 700; font-size: 14px;
  border: none; cursor: pointer; border-radius: 0; padding: 8px 0;
  background: #c0c0c0; box-shadow: var(--bevel-out); color: #000; transition: none;
}
.move-btn:hover { background: #c0c0c0; color: #000; }
.move-btn:active { box-shadow: var(--bevel-in); }

/* ---------- algorithm case cards ---------- */
.alg-search { width: 100%; }
.case-card {
  display: flex; flex-direction: column; align-items: center; gap: 6px; position: relative;
  border: none; cursor: pointer; font-family: var(--font-ui); text-align: center;
  background: #c0c0c0; box-shadow: var(--bevel-out); border-radius: 0; padding: 9px 7px; transition: none;
}
.case-grid.f2l .case-card { flex-direction: row; align-items: center; gap: 11px; text-align: left; }
.case-card:hover { transform: none; box-shadow: var(--bevel-out); }
.case-card:active { box-shadow: var(--bevel-in); }
.case-card.detected { box-shadow: var(--bevel-out); outline: 2px solid var(--signal); outline-offset: -2px; }
.case-card.detected::after { content: 'ON CUBE'; position: absolute; top: 3px; right: 4px; font-family: var(--font-ui); font-size: 8px; font-weight: 700; color: #fff; background: var(--signal); padding: 1px 4px; border-radius: 0; letter-spacing: 0; text-transform: uppercase; }
.cc-diagram { width: 74px; height: 74px; flex: 0 0 auto; display: flex; align-items: center; justify-content: center; overflow: hidden; background: var(--field); box-shadow: var(--bevel-field); }
.case-grid.f2l .cc-diagram { width: 66px; height: 66px; }
.case-card .cc-name { font-weight: 700; font-size: 11px; color: #000; line-height: 1.25; }
.case-grid.f2l .case-card > div:not(.cc-diagram) { flex: 1; min-width: 0; }
.case-card .cc-notation {
  font-family: var(--font-mono); font-size: 10px; color: #404040;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Practice algorithm list: a single-column readable list (full algorithm wraps, nothing truncated) */
.case-grid.alg-list { grid-template-columns: 1fr; }
.case-grid.alg-list .case-card { flex-direction: row; align-items: center; gap: 11px; text-align: left; padding: 7px 9px; }
.case-grid.alg-list .cc-diagram { width: 60px; height: 60px; }
.case-grid.alg-list .cc-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.case-grid.alg-list .cc-notation { white-space: normal; overflow: visible; text-overflow: clip; word-break: break-word; line-height: 1.45; font-size: 11px; color: #000; }
/* Practice: the current case's scramble (mirror it on a real cube) */
.practice-scramble { margin: 8px 0 2px; }
.practice-scramble .notation { margin-top: 3px; white-space: normal; word-break: break-word; line-height: 1.5; }
.diagram-svg { display: block; }
/* F2L case art is a low-res canvas upscaled nearest, so its dither grid matches the viewport's */
.diagram-canvas { image-rendering: pixelated; image-rendering: crisp-edges; }

/* ---------- guide / welcome prose (rendered inside the method modal) ---------- */
.guide-doc { font-family: var(--font-ui); color: #000; font-size: 12px; line-height: 1.55; }
.welcome-lead { color: #000; font-size: 13px; line-height: 1.5; margin: 2px 0 4px; font-weight: 700; }
.cfl-c { color: #0000a8; font-weight: 700; }
.cfl-f { color: #008000; font-weight: 700; }
.cfl-o { color: #aa5500; font-weight: 700; }
.cfl-p { color: #aa0000; font-weight: 700; }
.guide-doc h3 { display: flex; align-items: center; gap: 7px; margin: 18px 0 8px;
  font-family: var(--font-ui); font-size: 12px; font-weight: 700; letter-spacing: 0; text-transform: none; color: #000; }
.guide-doc h3::before { content: ""; width: 0; height: 0; }
.guide-doc h3:first-child { margin-top: 2px; }
.guide-doc p { margin: 0 0 10px; }
.guide-doc ul { margin: 0 0 11px; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 7px; }
.guide-doc li { position: relative; padding-left: 15px; }
.guide-doc li::before { content: ""; position: absolute; left: 2px; top: 6px; width: 5px; height: 5px; border-radius: 0; background: #000; }
.guide-doc b { color: #000; font-weight: 700; }
.guide-doc a { color: #0000c0; text-decoration: underline; font-weight: 400; border-bottom: none; }
.guide-doc a:hover { color: #0000ff; }

/* ---------- chapter selector + diagrams ---------- */
.ab-diagram img, .cube-img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* chapter switch: fade the step content out (keeping the menu, which folds shut), then fade the new step in */
#sidebar-body.switching > :not(.learn-filter) { opacity: 0; transform: translateY(8px); transition: opacity .2s ease, transform .2s ease; }
@keyframes stepIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
#sidebar-body.switched > :not(.learn-filter) { animation: stepIn .26s ease both; }

/* "step complete" card */
.step-done { margin-top: 4px; padding: 11px; border: none; border-radius: 0; background: var(--paper); box-shadow: var(--bevel-win); animation: stepDoneIn .3s ease both; }
.step-done.final { background: #d0d0c0; box-shadow: var(--bevel-win), inset 0 0 0 2px transparent; outline: 2px solid var(--good); outline-offset: -5px; }
.step-done-badge { display: flex; align-items: center; gap: 7px; font-family: var(--font-ui); font-size: 11px; letter-spacing: 0; text-transform: uppercase; font-weight: 700; color: var(--good); }
.sd-check { display: inline-grid; place-items: center; flex: 0 0 auto; width: 16px; height: 16px; border-radius: 0; background: var(--good); color: #fff; font-size: 10px; font-weight: 700; box-shadow: var(--bevel-field); }
.sd-sub { margin: 8px 0 0; font-size: 11px; color: #000; line-height: 1.5; }
.step-next { margin-top: 10px; }
.btn.primary.step-next { display: flex; align-items: center; gap: 8px; text-align: left; }
.sn-lead { flex: 0 0 auto; font-family: var(--font-ui); font-size: 10px; letter-spacing: 0; text-transform: uppercase; color: #404040; }
.sn-name { flex: 1 1 auto; font-weight: 700; }
.sn-arrow { flex: 0 0 auto; font-weight: 700; }
@keyframes stepDoneIn { from { opacity: 0; } to { opacity: 1; } }

/* the Learn header line: "<Method> method" + the Method intro link */
.learn-hdr { display: flex; align-items: baseline; gap: 8px; padding: 0 2px; }
.lh-method { flex: 1 1 auto; font-family: var(--font-ui); font-weight: 700; font-size: 12px; color: #000; }
.linky { border: none; background: none; box-shadow: none; font-family: inherit; font-size: 11px; color: var(--signal); text-decoration: underline; cursor: pointer; padding: 0; }
.lw-reopen.linky { margin-top: 0; }

/* the step wizard: a "Step 4 of 7" headline, a chunked progress bar, and a collapsible checklist */
.chapters { margin-bottom: 11px; border: none; border-radius: 0; background: transparent; box-shadow: none; }
.chapters-sum { width: 100%; cursor: pointer; border: none; background: transparent; text-align: left; display: flex; align-items: center; gap: 7px; padding: 4px 2px 6px; }
.chapters-sum::before { content: "\25B8"; color: #000; font-size: 9px; flex: 0 0 auto; transition: transform .3s ease; }
.chapters.open .chapters-sum::before { transform: rotate(90deg); }
.ch-sum-name { flex: 1 1 auto; min-width: 0; font-family: var(--font-ui); font-weight: 700; font-size: 12px; color: #000; }
.ch-pbar { display: flex; gap: 2px; background: var(--field); box-shadow: var(--bevel-field); padding: 3px; height: 16px; margin-bottom: 8px; }
.ch-pb-chunk { flex: 1 1 0; background: transparent; }
.ch-pb-chunk.on { background: var(--signal); }
/* height animates via grid-rows 0fr<->1fr; the list is clipped while collapsing */
.ch-wrap { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .4s ease; }
.chapters.open .ch-wrap { grid-template-rows: 1fr; }
.chapters-list { overflow: hidden; min-height: 0; padding: 0; }
.ch-inner { background: var(--field); box-shadow: var(--bevel-field); padding: 5px 4px; }
@keyframes chapter-build { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
@keyframes chapter-fold { from { opacity: 1; } to { opacity: 0; transform: translateY(3px); } }
.chapters.open .chapter, .chapters.open .ch-blurb-cur { animation: chapter-build .3s ease backwards; animation-delay: calc(var(--i, 0) * 36ms + 40ms); }
.chapters.closing .chapter, .chapters.closing .ch-blurb-cur { animation: chapter-fold .2s ease forwards; animation-delay: calc((6 - var(--i, 0)) * 22ms); }
.chapter { width: 100%; display: flex; align-items: center; gap: 7px; text-align: left; cursor: pointer; border: none; background: transparent; border-radius: 0; padding: 3px 5px; font-family: inherit; transition: none; }
.chapter:hover { background: var(--signal); }
.chapter:hover .ch-name { color: #fff; }
.chapter:hover .ch-st { color: #80ff80; }
.chapter.active { background: var(--signal); box-shadow: none; }
.chapter.active .ch-name { color: #fff; }
.chapter.done .ch-name { color: #404040; }
.chapter.done:hover .ch-name, .chapter.active.done .ch-name { color: #fff; }
.ch-st { flex: 0 0 14px; font-family: var(--font-ui); font-size: 11px; font-weight: 700; color: var(--good); }
.chapter.active > .ch-st:first-child { color: #fff; }
.ch-st.ok { text-align: right; }
.chapter:hover .ch-st.ok, .chapter.active .ch-st.ok { color: #80ff80; }
.ch-fig { width: 24px; height: 24px; flex: 0 0 24px; display: grid; place-items: center; }
.ch-name { flex: 1 1 auto; min-width: 0; font-family: var(--font-ui); font-size: 12px; color: #000; }
.chapter.active .ch-name { font-weight: 700; }
.ch-blurb-cur { font-size: 10.5px; color: #404040; line-height: 1.35; padding: 2px 5px 5px 52px; }

/* the step's working area: a classic Win95 group box titled with the step name */
.step-group { border: 2px groove #fff; border-radius: 0; margin: 0 0 8px; padding: 8px 10px 10px; min-width: 0; display: flex; flex-direction: column; }
.step-group > legend { font-family: var(--font-ui); font-weight: 700; font-size: 11px; color: #000; padding: 0 4px; }

/* a Win95 checkbox row (the X-ray toggle) */
.w95check { display: flex; align-items: center; gap: 7px; border: none; background: none; box-shadow: none; cursor: pointer; font-family: var(--font-ui); font-size: 11px; color: #000; padding: 2px 4px; text-align: left; }
.w95check .wc-box { flex: 0 0 13px; width: 13px; height: 13px; background: var(--field); box-shadow: var(--bevel-field); display: grid; place-items: center; }
.w95check.on .wc-box::after { content: "\2713"; font-size: 10px; font-weight: 700; color: #000; }
.step-group > .w95check { margin: 2px 0 8px; }

/* ---------- "About this step": collapsible group box ---------- */
.step-about { margin-bottom: 11px; border: none; border-radius: 0; background: var(--paper); box-shadow: var(--bevel-win); padding: 0 11px; animation: fade .15s ease; }
.step-about > summary { cursor: pointer; list-style: none; padding: 8px 0; display: flex; align-items: center; gap: 7px;
  font-family: var(--font-ui); font-size: 11px; letter-spacing: 0; text-transform: uppercase; color: #000; font-weight: 700; }
.step-about > summary::-webkit-details-marker { display: none; }
.step-about > summary::before { content: "\25B8"; color: #000; font-size: 9px; }
.step-about[open] > summary::before { content: "\25BE"; }
.step-about > *:last-child { margin-bottom: 11px; }
.ab-goal { font-family: var(--font-ui); font-weight: 700; color: #000; font-size: 12.5px; line-height: 1.4; margin: 0 0 10px; }
.ab-figs { display: flex; gap: 11px; flex-wrap: wrap; justify-content: center; margin: 6px 0 11px; }
.ab-fig { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 7px; }
.ab-diagram { width: 150px; height: 150px; display: grid; place-items: center; overflow: hidden; background: var(--field); box-shadow: var(--bevel-field); }
.ab-fig figcaption { font-family: var(--font-ui); font-size: 11px; color: #000; text-align: center; max-width: 150px; line-height: 1.3; }
.ab-note { font-size: 12px; color: #000; line-height: 1.45; margin: 0 0 8px; }
.ab-warn { font-size: 11.5px; color: #000; background: #ffffcc; box-shadow: var(--bevel-field); border-radius: 0; padding: 7px 9px; margin: 0; line-height: 1.4; }
.ab-note b, .ab-goal b, .ab-warn b { color: #000; font-weight: 700; }

/* ---------- narrow screens: stack the sidebar under the cube ---------- */
@media (max-width: 760px) {
  .workspace { flex-direction: column; gap: 6px; }
  .sidebar { flex: 0 0 auto; max-height: 46vh; }
  .stage { min-height: 240px; }
}

/* ---- algorithm preview window (#alg-modal) + the reusable alg list ---- */
.alg-modal-card { width: min(700px, 94vw); }
.alg-preview-cube { width: 100%; height: min(460px, 56vh); background: var(--field); box-shadow: var(--bevel-field); position: relative; overflow: hidden; margin-bottom: 6px; }
.alg-preview-cube .scene, .alg-preview-cube canvas:not(.vc-canvas) { width: 100% !important; height: 100% !important; display: block; }
.alg-nav { display: flex; gap: 6px; margin-top: 6px; }
.alg-nav .btn { flex: 1 1 0; }
.alg-list-title { margin-top: 10px; margin-bottom: 4px; }
.practice-case-btn { text-align: center; }

/* ---- notation cheat-sheet modal (#notation-modal): cube on the left, scannable tables on the right ---- */
.notation-modal-card { width: min(880px, 96vw); }
/* this modal's body owns no scrollbar (the sheet pane does), so drop the both-edges gutter + big right pad
   that would otherwise leave the pane's bar floating away from the card edge. */
.notation-modal-card .modal-body { scrollbar-gutter: auto; padding: 10px 5px 12px 5px; }
.notation-split { display: flex; gap: 12px; align-items: stretch; }
.notation-cube-pane { flex: 1 1 46%; min-width: 280px; }
.notation-cube-pane .alg-preview-cube { height: min(440px, 56vh); margin-bottom: 0; }
/* the cheat-sheet pane is the scroller. No explicit right padding: Chromium's native bar shrinks the content
   box, and on Firefox win95scroll adds the .w95sb-host 17px so the custom bar never sits over the buttons. */
.notation-sheet-pane { flex: 1 1 54%; min-width: 240px; max-height: min(440px, 56vh); overflow-y: auto; scrollbar-gutter: stable; }
.notation-intro { margin: 0 0 9px; }
.notation-intro p { font-size: 11px; color: #000; line-height: 1.4; margin: 0 0 6px; }
.notation-intro p:last-child { margin-bottom: 0; }
.notation-prime-row { margin: 0 0 10px; }
.notation-prime-toggle { font-family: var(--font-mono); font-weight: 700; }
.notation-group { margin-bottom: 11px; }
.notation-group-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.notation-group-head .field-label { margin: 0; }
.notation-showall { white-space: nowrap; }
.notation-group-note { font-size: 10.5px; color: #404040; margin: 1px 0 4px; }
/* real table with win95 grid lines on a white field */
.notation-table { width: 100%; border-collapse: collapse; margin-top: 3px; background: #fff; box-shadow: var(--bevel-in); }
.notation-table td { border: 1px solid #a8a8a8; padding: 3px 7px; vertical-align: middle; }
.notation-row.active td { background: var(--signal); border-color: var(--signal); }
.notation-row.active .notation-tok, .notation-row.active .notation-mean { color: #fff; }
.notation-tok { font-family: var(--font-mono); font-weight: 700; font-size: 13px; color: #000; width: 1%; white-space: nowrap; text-align: center; }
.notation-mean { font-size: 11px; color: #000; }
.notation-show-cell { width: 1%; text-align: center; padding: 2px 5px; }
.notation-show { padding: 1px 9px; font-size: 11px; line-height: 1.3; }
@media (max-width: 620px) {
  .notation-split { flex-direction: column; }
  .notation-cube-pane, .notation-sheet-pane { flex: 1 1 auto; width: 100%; max-height: none; }
}

/* ---- tutorial walkthrough modal (#tutorial-modal): cube on the left, a paged explainer on the right ---- */
.tutorial-modal-card { width: min(820px, 96vw); }
.tutorial-modal-card .modal-body { scrollbar-gutter: auto; padding: 10px 8px 12px 8px; }
.tutorial-split { display: flex; gap: 12px; align-items: stretch; }
.tutorial-cube-pane { flex: 1 1 50%; min-width: 280px; }
.tutorial-cube-pane .alg-preview-cube { height: min(420px, 56vh); margin-bottom: 0; }
/* the right pane is a fixed-height column: heading + step count pinned at the top, prose scrolls in the
   middle, the Back/dots/Next nav pinned at the bottom so it never scrolls away. */
.tutorial-text-pane { flex: 1 1 50%; min-width: 240px; height: min(420px, 56vh); display: flex; flex-direction: column; }
.tutorial-step-count { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; font-size: 10px; color: #404040; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; margin: 0 0 5px; }
.tutorial-replay { margin-left: auto; text-transform: none; letter-spacing: 0; font-family: var(--font-mono); }
.tutorial-head { flex: 0 0 auto; font-size: 14px; font-weight: 700; color: #000; margin: 0 0 8px; }
.tutorial-body { flex: 1 1 auto; overflow-y: auto; min-height: 0; }
.tutorial-body p { font-size: 12px; color: #000; line-height: 1.5; margin: 0 0 9px; }
.tutorial-body p:last-child { margin-bottom: 0; }
/* scrubbable algorithm step: a centred move list (current move lit) over a slider + prev/next arrows */
.tutorial-scrub { margin-top: 6px; }
.tutorial-scrub .notation { font-size: 15px; text-align: center; margin: 0; padding: 4px 0; }
.tutorial-scrub .insp-scrub { margin-top: 7px; }
/* narrator text field: a plain sunken white input the cursor types into (no window chrome).
   It takes ALL the remaining pane height up front - full-size from the first frame, never grows. */
.tutorial-body.narrate { display: flex; flex-direction: column; overflow: visible; }
.tutorial-typefield { flex: 1 1 auto; min-height: 0; background: #fff; box-shadow: var(--bevel-field); margin-top: 4px; padding: 8px 9px; overflow-y: auto; cursor: text; }
.tutorial-toggles { flex: 0 0 auto; }
.tutorial-typeline { font-size: 12px; color: #000; line-height: 1.5; margin: 0 0 7px; }
.tutorial-typeline:last-child { margin-bottom: 0; }
.tutorial-typeline.typing::after { content: ''; display: inline-block; width: 1.5px; height: 13px; margin-left: 1px; background: #000; vertical-align: text-bottom; animation: tutCaret 1.05s steps(1) infinite; }
@keyframes tutCaret { 50% { opacity: 0; } }
/* Learn welcome: the method outline + scramble-and-start (first visit per method) */
.learn-welcome { display: flex; flex-direction: column; }
.lw-title { font-size: 14px; font-weight: 700; color: #000; margin: 2px 0 7px; }
.lw-intro { font-size: 12px; color: #000; line-height: 1.5; margin: 0 0 8px; }
.lw-steps { list-style: none; margin: 2px 0 4px; padding: 0; counter-reset: lwstep; }
.lw-step { display: flex; gap: 8px; align-items: center; background: var(--paper); box-shadow: var(--bevel-out); padding: 5px 7px; margin-bottom: 6px; }
.lw-fig { width: 44px; height: 44px; flex: 0 0 auto; }
.lw-name { font-size: 11.5px; font-weight: 700; color: #000; }
.lw-blurb { font-size: 10.5px; color: #404040; line-height: 1.35; }
.lw-go { margin-top: 6px; font-weight: 700; }
/* station guides (first + middle layer): progress line + the big algorithm button(s) */
.guide-progress { margin: 7px 0 2px; font-size: 11px; }
.guide-trigger { margin-top: 9px; font-weight: 700; }
.guide-algrow { display: flex; gap: 7px; }
.guide-algrow .guide-trigger { flex: 1 1 0; min-width: 0; }
/* toggle buttons under the text field: real working toggles the narrator clicks (and the learner can too) */
.tutorial-toggles { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; }
.tut-toggle.active { background: var(--signal); color: #fff; box-shadow: var(--bevel-in); }
/* "Step done": signed off by the narrator at the end of each beat; pressing it unlocks the cube */
.tut-done { margin-top: 7px; }
.tut-done.active { background: var(--signal); color: #fff; box-shadow: var(--bevel-in); opacity: 1; }
/* the cube is hands-off while the narrator walks the step (his synthetic drags bypass pointer-events) */
#tutorial-cube.tut-locked { pointer-events: none; }
/* the fake cursor: arrow by default, I-beam over the text field (.text). center the I-beam on the point. */
.tut-cursor .tc-ibeam { display: none; }
.tut-cursor.text .tc-arrow { display: none; }
.tut-cursor.text .tc-ibeam { display: block; }
.tut-cursor.text { margin: -11px 0 0 -5px; }
/* the on-screen element the narrator is pointing at (e.g. the Notation button) pulses */
@keyframes tutPulse { 0%, 100% { outline: 0 solid transparent; outline-offset: 1px; } 50% { outline: 2px solid var(--signal); outline-offset: 2px; } }
.tut-target { animation: tutPulse 1s ease infinite; }
/* the frozen "after the slice" comparison window: a floating win95 window holding a 1:1 crop of the cube */
.tutorial-snap { position: fixed; z-index: 11; background: var(--paper); box-shadow: var(--bevel-win); padding: 3px; }
.tutorial-snap-head { font-size: 11px; font-weight: 700; color: #fff; background: var(--title-grad); padding: 3px 7px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tutorial-snap-vp { overflow: hidden; background: var(--field); box-shadow: var(--bevel-field); margin-top: 3px; }
.tutorial-snap-img { display: block; }
/* fake mouse cursor for the capture sequence (the win95 arrow) */
.tut-cursor { position: fixed; z-index: 14; pointer-events: none; margin: -1px 0 0 -1px; }
.tut-cursor svg { display: block; filter: drop-shadow(1px 1px 0 rgba(0, 0, 0, .35)); transition: transform .1s ease; }
.tut-cursor.down svg { transform: translate(1px, 1px) scale(.9); }
/* Paint-style marching-ants selection marquee */
.tut-marquee { position: fixed; z-index: 12; pointer-events: none;
  background-image: repeating-linear-gradient(90deg, #000 0 4px, #fff 4px 8px), repeating-linear-gradient(90deg, #000 0 4px, #fff 4px 8px), repeating-linear-gradient(0deg, #000 0 4px, #fff 4px 8px), repeating-linear-gradient(0deg, #000 0 4px, #fff 4px 8px);
  background-size: 8px 1px, 8px 1px, 1px 8px, 1px 8px; background-position: 0 0, 0 100%, 0 0, 100% 0;
  background-repeat: repeat-x, repeat-x, repeat-y, repeat-y; animation: tutMarch .5s linear infinite; }
@keyframes tutMarch { to { background-position: 8px 0, -8px 100%, 0 -8px, 100% 8px; } }
/* the "same result" pulse, fired on the snapshot AND the live cube together */
@keyframes tutFlash { 0%, 100% { outline: 0 solid rgba(255, 206, 58, 0); outline-offset: 0; } 35%, 65% { outline: 3px solid #ffce3a; outline-offset: 2px; } }
.tut-flash { animation: tutFlash 1.15s ease; }
.tutorial-nav { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; margin-top: 10px; padding-top: 9px; border-top: 1px solid #a8a8a8; }
.tutorial-nav .btn { flex: 0 0 auto; min-width: 76px; }
.tutorial-dots { flex: 1 1 auto; display: flex; justify-content: center; gap: 6px; }
.tutorial-dot { width: 8px; height: 8px; background: #c0c0c0; box-shadow: var(--bevel-in); }
.tutorial-dot.on { background: var(--signal); }
@media (max-width: 620px) {
  .tutorial-split { flex-direction: column; }
  .tutorial-cube-pane, .tutorial-text-pane { flex: 1 1 auto; width: 100%; height: auto; max-height: none; }
}

/* respect reduced-motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}
