:root {
  --paper: #f3f1ec;
  --panel: #ffffff;
  --ink: #1c1f1e;
  --ink-soft: #565f5c;
  --line: #dcd6c9;
  --accent: #c96a1f;
  --accent-soft: #f2ddc4;
  --teal: #1f6f6b;
  --teal-soft: #d9ebe9;
  --danger: #b4483f;
}

/* The root cause of "clicking a launcher tile / next / back does nothing":
   several elements below (.launcher, .panel, .app) set their own `display`
   value, which — by normal CSS cascade rules — silently overrides the
   browser's built-in `[hidden] { display: none }` rule, since an author
   stylesheet always wins over the user-agent stylesheet at equal
   specificity. That meant setting the `hidden` attribute via JS (exactly
   what showLauncher()/enterWorkflow()/goToStep() do) had no visual effect
   at all — the element stayed on screen, just no longer receiving the
   click handlers meant for whatever should have replaced it. This single
   rule guarantees `hidden` always wins, everywhere in the app, regardless
   of what other display rules a class sets.
*/
[hidden] { display: none !important; }
@media (prefers-color-scheme: dark) {
  :root {
    --paper: #15181a;
    --panel: #1d2224;
    --ink: #eef1ef;
    --ink-soft: #a9b3b0;
    --line: #32393a;
    --accent: #e2984f;
    --accent-soft: #3a2b1a;
    --teal: #5cb3ac;
    --teal-soft: #1b2d2b;
    --danger: #e08079;
  }
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background: var(--paper);
  color: var(--ink);
}

.app { display: flex; min-height: 100vh; position: relative; }

/* ---- Stepper sidebar ---- */
/* Collapsible 2026-09-15 — this used to be a fixed 260px column, permanently
   eating a third of the screen on a laptop/pad. It's still 260px expanded
   (the step list needs real room), but now collapses to a slim rail with
   #stepperToggle, and remembers the choice per browser. */
.stepper {
  width: 260px;
  flex-shrink: 0;
  background: var(--panel);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  padding: 20px 0;
  overflow: hidden;
  transition: width 0.16s ease, padding 0.16s ease;
}
.stepper.collapsed {
  width: 0;
  padding-left: 0;
  padding-right: 0;
  border-right: none;
}
.stepper > * { width: 260px; } /* keep inner content from reflowing/wrapping while the column animates to 0 */
#stepperToggle {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 40;
  width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--panel); color: var(--ink);
  cursor: pointer; font-size: 0.95rem; padding: 0;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}
/* When collapsed, the fixed toggle button sits right where the panel
   header's title used to start — give the header (and footer, for the
   same reason) room so text never renders underneath the button. */
body.sidebar-collapsed .panel-header { padding-left: 50px; }
body.sidebar-collapsed .panel-footer { padding-left: 50px; }
.stepper-header {
  padding: 38px 20px 16px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 12px;
}
.brand { display: block; font-weight: 700; font-size: 1.05rem; }
.franchise-badge {
  display: inline-block;
  margin-top: 6px;
  font-size: 0.75rem;
  padding: 3px 8px;
  border-radius: 3px;
  background: var(--teal-soft);
  color: var(--teal);
}
#stepList { list-style: none; margin: 0; padding: 0 12px; flex: 1; }
.step {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 8px;
  border-radius: 6px;
  color: var(--ink-soft);
  cursor: default;
}
.step.active { background: var(--accent-soft); color: var(--ink); }
.step.done .step-num { background: var(--teal); color: #fff; }
.step-num {
  width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--line);
  color: var(--ink-soft);
  display: flex; align-items: center; justify-content: center;
  font-size: 0.8rem; font-weight: 600;
  flex-shrink: 0;
}
.step.active .step-num { background: var(--accent); color: #fff; }
.stepper-footer { padding: 12px 20px 0; border-top: 1px solid var(--line); }
.conn-status { font-size: 0.75rem; padding: 4px 0; display: block; }
.conn-unknown { color: var(--ink-soft); }
.conn-ok { color: var(--teal); }
.conn-error { color: var(--danger); }

/* ---- Workspace ---- */
.workspace { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.panel { display: flex; flex-direction: column; flex: 1; }
/* Trimmed 2026-09-15 — this used to be a tall title+description block on
   every step, eating vertical space a drawing/stylus step can't spare.
   Title and description now sit on one compact line; the description
   still reads fine, it just doesn't need its own full-height row. */
.panel-header {
  padding: 10px 20px;
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  border-bottom: 1px solid var(--line);
}
.panel-header h1 { margin: 0; font-size: 1.1rem; white-space: nowrap; }
.panel-header p { margin: 0; color: var(--ink-soft); font-size: 0.82rem; line-height: 1.3; }
.panel-body { flex: 1; padding: 12px 16px; overflow: auto; }
.panel-footer {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 20px; border-top: 1px solid var(--line);
}
.panel-footer[hidden] { display: none; }

/* ---- Compact canvas panels (added 2026-09-16, revised 2026-09-19) ----
   Mike: "I'd love to have the app launch with only a half inch high
   wrapper on the top and bottom... all the other browser functionality
   isn't needed." Applies to the three panels built around a Stylus Studio
   (character Style & Iterate, set Style & Iterate, website Paint Your
   Brand) via the .panel-canvas-compact class on their <section>. Collapses
   the title/description header entirely and drops the side padding around
   the studio so its own ss-menubar (Add Photo / Vectorize / Imagine /
   Cartoon Styles / Reset) becomes the only thing above the canvas.
   2026-09-19: Mike also flagged the bottom of the screen as "just a waste
   of space" — the panel's own footer ("Back" / "Approve & continue: ...")
   now gets physically moved (same button elements, not clones — listeners
   stay attached) into a new .ss-menu-actions group at the right end of the
   studio's own top menu bar by promoteFooterToStudioMenu() in app.js, and
   the now-empty footer is `hidden`. These rules are just a fallback in case
   a footer button is ever left behind (e.g. the studio failed to init). */
.panel-canvas-compact .panel-header { display: none; }
.panel-canvas-compact .panel-body { padding: 0; }
.panel-canvas-compact .panel-body > *:not(.stylus-mount) { padding-left: 16px; padding-right: 16px; }
.panel-canvas-compact .stylus-studio { padding: 0; border: none; border-radius: 0; }
.panel-canvas-compact .ss-minipaint-frame { border: none; border-radius: 0; }
.panel-canvas-compact .panel-footer {
  padding-top: 4px; padding-bottom: 4px; border-top: none; min-height: 0;
}
.panel-canvas-compact .panel-footer .btn-secondary { display: none; }
.panel-canvas-compact .panel-footer .btn-primary {
  padding: 3px 10px; font-size: 0.78rem; line-height: 1.5; height: auto;
}
/* The buttons promoted into the top menu bar (see above) — sized to match
   the studio's own ss-tbtn toolbar buttons instead of their old full-size
   footer look. "Back" stays hidden up here too, same reasoning as before:
   the hamburger toggle's step list already gets you back to any earlier
   step, so a second back control is redundant. */
.ss-menu-actions { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.ss-menu-actions .btn-secondary { display: none; }
.ss-menu-actions .btn-primary {
  height: 30px; padding: 0 12px; font-size: 0.78rem; line-height: 1;
  border-radius: 5px;
}
/* The hamburger toggle is position:fixed at top:10/left:10 regardless of
   which panel is showing. With the panel-header hidden above, the studio's
   own ss-menubar now starts right at the top of the page too — this just
   gives it enough left padding to clear the toggle button instead of
   underlapping it, the same trick already used for panel-header/footer
   elsewhere in this file. Only matters with the sidebar collapsed; with it
   expanded, the toggle sits over the real sidebar column instead. */
body.sidebar-collapsed .ss-menubar { padding-left: 44px; }

/* ---- Buttons / fields ---- */
.btn {
  font: inherit;
  padding: 9px 16px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--ink);
  cursor: pointer;
}
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-secondary { background: transparent; }
.btn-block { width: 100%; }
.field-label { display: block; font-size: 0.8rem; color: var(--ink-soft); margin-bottom: 6px; }
select, input[type="text"], textarea {
  font: inherit;
  width: 100%;
  padding: 8px 10px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--ink);
  margin-bottom: 14px;
}
.hint { font-size: 0.82rem; color: var(--ink-soft); margin-top: 10px; }

/* ---- Capture ---- .capture-controls is still used by the Voice panel's
   upload/record row; .capture-area was only used by the old full-screen
   Capture step (removed 2026-09-15 — see .ss-photo-area below for its
   replacement, an in-place dialog on the stylus screen itself). */
.capture-area {
  width: 100%; max-width: 480px; aspect-ratio: 4/3;
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  margin-bottom: 16px;
}
.capture-area video, .capture-area img { width: 100%; height: 100%; object-fit: cover; }
.capture-controls { display: flex; gap: 10px; flex-wrap: wrap; }

/* ---- Iterate ---- */
.iterate-body { display: flex; gap: 24px; flex-wrap: wrap; }
.canvas-wrap { flex: 1; min-width: 320px; }
#drawCanvas {
  width: 100%; max-width: 640px; aspect-ratio: 1;
  background: #fff; border: 1px solid var(--line); border-radius: 8px;
  touch-action: none; cursor: crosshair;
}
.canvas-tools { display: flex; gap: 8px; align-items: center; margin-top: 10px; flex-wrap: wrap; }
.tool-btn {
  padding: 6px 12px; border-radius: 6px; border: 1px solid var(--line);
  background: var(--panel); color: var(--ink); cursor: pointer; font-size: 0.85rem;
}
.tool-btn[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent); }
.iterate-side { width: 280px; flex-shrink: 0; }
.history { margin-top: 16px; display: flex; flex-direction: column; gap: 8px; }
.history-empty { color: var(--ink-soft); font-size: 0.85rem; }
.history-item {
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 6px; font-size: 0.82rem;
  display: flex; justify-content: space-between; gap: 8px;
}
.history-author {
  color: var(--ink-soft); font-size: 0.78rem; flex-shrink: 0;
}

/* ---- Sign-in overlay (added 2026-09-15) ----
   Blocking <dialog> shown before the rest of the app boots (see app.js's
   initAuthGate). Kept visually simple on purpose — this is an identity
   gate for attribution, not a security screen. */
.kvs-auth-overlay {
  border: none; border-radius: 12px; padding: 0;
  max-width: 380px; width: 92vw;
  background: var(--panel); color: var(--ink);
}
.kvs-auth-overlay::backdrop { background: rgba(0, 0, 0, 0.55); }
.kvs-auth-card {
  display: flex; flex-direction: column; gap: 12px; padding: 24px;
}
.kvs-auth-card h2 { margin: 0; font-size: 1.15rem; }
.kvs-auth-sub { margin: 0; color: var(--ink-soft); font-size: 0.85rem; line-height: 1.4; }
.kvs-auth-card label {
  display: flex; flex-direction: column; gap: 4px; font-size: 0.82rem; color: var(--ink-soft);
}
.kvs-auth-card select, .kvs-auth-card input {
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 6px;
  background: var(--paper); color: var(--ink); font-size: 0.95rem;
}
#authNewPasswordRow { display: flex; flex-direction: column; gap: 12px; }
.kvs-auth-error { margin: 0; color: var(--danger); font-size: 0.82rem; }
#authSignedInBadge { display: block; margin-top: 6px; color: var(--ink-soft); font-size: 0.8rem; }

/* ---- Stylus Studio (shared layered drawing/iteration engine) ----
   The raw painting surface is a self-hosted, embedded copy of miniPaint
   (MIT license, vendor/minipaint/) in an iframe — a real, already-
   shippable layered image editor with its own menu bar, toolbox, color
   picker, layers panel, undo/redo, etc., maximized to fill the available
   width. Our own chrome above it is deliberately minimal: just Vectorize /
   Imagine-in-a-style / Reset, since everything else (brush, shapes, fill,
   text, color, layers) is miniPaint's native UI now. */
.stylus-studio {
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel);
  padding: 4px; max-width: 100%;
}
.ss-menubar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 3px 6px; border-bottom: 1px solid var(--line); margin-bottom: 4px;
}
.ss-menu-group { display: flex; align-items: center; gap: 8px; }
.ss-menu-info { flex: 1; min-width: 0; }
.ss-brand { font-weight: 600; font-size: 0.85rem; flex-shrink: 0; }
.ss-hint-inline {
  font-size: 0.75rem; color: var(--ink-soft); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.ss-menu-panels { margin-left: auto; flex-wrap: wrap; display: flex; gap: 6px; }
.ss-tbtn {
  height: 30px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 5px; background: var(--panel); color: var(--ink);
  cursor: pointer; font-size: 0.95rem; padding: 0;
}
.ss-tbtn.ss-wide { width: auto; padding: 0 10px; font-size: 0.78rem; }
/* "Clean Up" is meant to be the obvious first thing to try (2026-09-19) —
   a light accent border/tint sets it apart from the plain-outline buttons
   next to it without being as loud as the orange primary actions. */
.ss-cleanup { border-color: var(--accent); color: var(--accent); font-weight: 600; }
.ss-workspace { position: relative; width: 100%; }
.ss-minipaint-frame {
  width: 100%; display: block; border: 1px solid var(--line); border-radius: 6px;
  background: #666d6f;
  /* Just the fallback shown for an instant before JS measures miniPaint's
     own native content height — see fitFrameToViewport() in
     stylus-canvas.js. That function no longer clamps this to whatever
     space is left in the browser window (Mike's feedback on that attempt:
     it was cropping miniPaint's own sidebar, forcing a scrollbar inside
     it — he'd rather the OUTER page scroll than miniPaint ever be cut
     off). This value just needs to be a reasonable size before JS takes
     over, which happens within about a second of the panel showing. */
  height: 900px;
}
.ss-frame-loading {
  position: absolute; top: 0; left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--panel); color: var(--ink-soft); font-size: 0.9rem;
  border: 1px solid var(--line); border-radius: 6px;
}
/* Vectorize / Imagine now open as real <dialog> modals that float centered
   over the canvas instead of an inline block that pushed the page down and
   forced scrolling to reach it (the exact complaint on a pad with a
   stylus). The browser's native dialog backdrop dims everything behind it;
   clicking the dimmed area or pressing Esc closes it, same as the Close
   button. */
.ss-panel {
  padding: 16px 18px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--panel); color: var(--ink);
  width: min(640px, 92vw);
  max-height: 84vh;
  overflow-y: auto;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}
.ss-panel::backdrop {
  background: rgba(0, 0, 0, 0.45);
}
.ss-photo-area {
  width: 100%; max-width: 420px; aspect-ratio: 4/3;
  background: #111; border: 1px solid var(--line); border-radius: 8px;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  margin: 10px 0;
}
.ss-photo-area video { width: 100%; height: 100%; object-fit: cover; }
.ss-photo-controls { flex-wrap: wrap; align-items: center; }
.ss-photo-camera-select {
  height: 34px; padding: 0 8px; border-radius: 6px; border: 1px solid var(--line);
  background: var(--panel); color: var(--ink); font-size: 0.85rem; max-width: 220px;
}
/* Candidate review dialog (2026-09-15) — replaces the old cramped
   320px-wide vector preview. Mike: "open it up full size so I can see the
   whole picture." This one dialog is reused for Vectorize output, single
   Imagine results, and the batch/Cartoon Styles review queue — it just
   needs to be big enough for any of them. */
.ss-candidate-large { width: min(1000px, 94vw); max-height: 92vh; }
/* 2026-09-19 fix: this used to be `max-height: 70vh` on the container with
   `width: auto; height: auto` on the img/svg inside — meaning the box had
   no *definite* height (max-height alone doesn't give flex children one to
   size against), so a wide/short vectorized SVG fell back to its own tiny
   intrinsic size (an SVG with only a viewBox, no width/height, defaults to
   300x150 in most browsers) instead of filling the dialog. That's what
   produced Mike's "thin horizontal strip with big black bars on either
   side." Giving the box a real height and using object-fit:contain makes
   both <img> and inline <svg> fill it edge-to-edge while still preserving
   the source's aspect ratio — no more guessing at intrinsic size. */
.ss-candidate-preview {
  width: 100%; height: min(70vh, 640px); min-height: 260px;
  display: flex; align-items: center; justify-content: center;
  background: #111; border: 1px solid var(--line); border-radius: 8px;
  overflow: hidden; margin: 10px 0;
}
.ss-candidate-preview img, .ss-candidate-preview svg {
  width: 100%; height: 100%; object-fit: contain;
  display: block; background: #fff;
}
.ss-candidate-actions { flex-wrap: wrap; }
.ss-clean-lines-label {
  display: inline-flex; align-items: center; gap: 5px; font-size: 0.78rem;
  color: var(--ink-soft); white-space: nowrap;
}
.ss-panel-actions { display: flex; gap: 8px; }
.ss-restyle-section-label { font-size: 0.78rem; color: var(--ink-soft); margin: 10px 0 6px; font-weight: 600; }
.ss-restyle-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 8px;
}
.ss-restyle-tile {
  border: 1px solid var(--line); border-radius: 6px; background: var(--panel);
  cursor: pointer; padding: 5px; font: inherit; text-align: center;
}
.ss-restyle-tile:hover { border-color: var(--accent); }
.ss-restyle-tile img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 4px; display: block; margin-bottom: 5px; }
.ss-restyle-tile span { font-size: 0.72rem; color: var(--ink-soft); }
.ss-restyle-styles { display: flex; flex-wrap: wrap; gap: 6px; }
.ss-style-chip {
  padding: 5px 12px; border-radius: 14px; border: 1px solid var(--line);
  background: var(--panel); color: var(--ink); cursor: pointer; font-size: 0.78rem;
}
.ss-style-chip.selected { background: var(--accent); border-color: var(--accent); color: #fff; }
.ss-restyle-refs { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 10px 0; }
.ss-ref-label { font-size: 0.78rem; color: var(--ink-soft); display: flex; flex-direction: column; gap: 2px; }
.ss-ref-label input[type="file"] { font-size: 0.72rem; max-width: 180px; }
.ss-ref-image-preview { width: 36px; height: 36px; object-fit: cover; border-radius: 4px; border: 1px solid var(--line); }
.ss-ref-video-name { font-size: 0.75rem; color: var(--ink-soft); }
.ss-restyle-custom { display: flex; gap: 8px; margin: 6px 0 4px; flex-wrap: wrap; }
.ss-restyle-custom input { flex: 1; min-width: 200px; margin-bottom: 0; }
@media (max-width: 720px) {
  .ss-menubar { flex-direction: column; align-items: stretch; }
  .ss-menu-panels { margin-left: 0; }
  .ss-hint-inline { white-space: normal; }
}

/* ---- Style sheet grid ---- */
.sheet-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 12px; margin-top: 20px;
}
.sheet-tile {
  aspect-ratio: 1; border: 1px dashed var(--line); border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.75rem; color: var(--ink-soft); text-align: center; padding: 6px;
  background: var(--panel);
}
.sheet-tile.sheet-tile-real {
  border-style: solid; flex-direction: column; gap: 4px; padding: 4px;
  overflow: hidden;
}
.sheet-tile.sheet-tile-real img {
  max-width: 100%; max-height: 78%; object-fit: contain;
}
.sheet-tile.sheet-tile-real .sheet-tile-label {
  font-weight: 600; color: var(--ink);
}
.sheet-tile.sheet-tile-real .sheet-tile-remove {
  position: absolute; top: 2px; right: 2px; background: none; border: none;
  cursor: pointer; color: var(--ink-soft); font-size: 0.9rem; line-height: 1;
}
.sheet-tile.sheet-tile-real { position: relative; }

/* ---- Style sheet import (2D puppet path) ---- */
.sheet-import {
  margin-top: 28px; padding-top: 20px; border-top: 1px solid var(--line);
}
.sheet-import h2 { font-size: 1rem; margin: 0 0 6px; }
.sheet-import-row {
  display: flex; align-items: center; gap: 8px; margin: 10px 0; flex-wrap: wrap;
}
.sheet-import-row .field-label { margin: 0; }
.sheet-import-row input[type="text"], .sheet-import-row select {
  padding: 6px 10px; border: 1px solid var(--line); border-radius: 5px;
  background: var(--panel); color: var(--ink); font-size: 0.85rem;
}
.sheet-import-canvas-wrap {
  border: 1px solid var(--line); border-radius: 6px; background: var(--panel);
  max-width: 100%; overflow: auto; margin: 10px 0;
}
#sheetImportCanvas { display: block; cursor: crosshair; max-width: 100%; }

/* ---- Franchise ---- */
.franchise-body { max-width: 420px; }
.franchise-divider { text-align: center; color: var(--ink-soft); margin: 4px 0 14px; font-size: 0.85rem; }

/* ---- Set grid ---- */
.set-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 14px; }
.set-card {
  border: 1px solid var(--line); border-radius: 8px; padding: 16px;
  background: var(--panel); cursor: pointer; text-align: left;
}
.set-card[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-soft); }
.set-card h3 { margin: 0 0 6px; font-size: 0.95rem; }
.set-card p { margin: 0; font-size: 0.8rem; color: var(--ink-soft); }
.set-detail {
  margin-top: 16px; padding: 14px 16px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel); font-size: 0.88rem;
}

/* ---- Scene handoff ---- */
.summary-card {
  border: 1px solid var(--line); border-radius: 8px; padding: 16px 18px;
  background: var(--panel); margin-bottom: 18px; font-size: 0.9rem; line-height: 1.6;
}

/* ---- Launcher ---- */
.launcher {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 40px 20px; background: var(--paper);
}
.launcher-card { max-width: 720px; width: 100%; }
.launcher-eyebrow { font-size: 0.8rem; color: var(--accent); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }
.launcher-card h1 { margin: 6px 0 10px; font-size: 2rem; }
.launcher-card > p { color: var(--ink-soft); max-width: 56ch; margin: 0 0 28px; }
.launcher-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; }
.launcher-tile {
  text-align: left; border: 1px solid var(--line); border-radius: 10px; padding: 18px 20px;
  background: var(--panel); cursor: pointer; font: inherit; color: var(--ink);
  transition: border-color 0.15s;
}
.launcher-tile:hover { border-color: var(--accent); }
.launcher-tile h3 { margin: 0 0 6px; font-size: 1.02rem; }
.launcher-tile p { margin: 0; font-size: 0.85rem; color: var(--ink-soft); line-height: 1.45; }

.back-to-launcher {
  background: none; border: none; color: var(--ink-soft); font: inherit; font-size: 0.78rem;
  cursor: pointer; padding: 0 0 6px; display: block;
}
.back-to-launcher:hover { color: var(--accent); }

/* ---- Model / rig guided steps ---- */
.model-steps { list-style: none; margin: 0 0 16px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.model-steps li {
  border: 1px solid var(--line); border-radius: 8px; padding: 12px 16px;
  background: var(--panel); display: flex; justify-content: space-between; align-items: center; gap: 10px;
}
.model-steps li .stage-status { font-size: 0.78rem; color: var(--ink-soft); }
.model-steps li.done .stage-status { color: var(--teal); }
.model-steps li button.btn { flex-shrink: 0; }

/* ---- Scene placement + camera box ---- */
.place-area, .box-view {
  width: 100%; max-width: 640px; aspect-ratio: 4/3;
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 16px; position: relative; overflow: hidden; cursor: crosshair;
}
.place-backdrop {
  width: 100%; height: 100%; position: relative;
  display: flex; align-items: center; justify-content: center;
}
.place-empty { color: var(--ink-soft); font-size: 0.85rem; text-align: center; padding: 0 24px; }
.place-mark {
  position: absolute; width: 14px; height: 14px; margin: -7px 0 0 -7px;
  background: var(--accent); border-radius: 50%; border: 2px solid var(--panel);
}
.place-controls { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; margin-bottom: 12px; }
.place-controls select, .place-controls input { margin-bottom: 0; width: auto; min-width: 180px; }

.webcam-calibration {
  margin-top: 20px; padding: 14px 16px; border: 1px dashed var(--line); border-radius: 8px;
}
.webcam-calibration h4 { margin: 0 0 6px; }

/* ---------- Need-help button + guide dialog ---------- */
.kh-btn { display:inline-flex; align-items:center; gap:8px; border:1px solid var(--line, #3a4352); background:#1b212b; color:#f3f6fb;
  border-radius:999px; padding:6px 12px 6px 6px; font:inherit; font-size:.85rem; cursor:pointer; }
.kh-btn > span:first-child { display:inline-grid; place-items:center; width:26px; height:26px; border-radius:50%; background:var(--accent, #7cf0b8); color:#04130c; font-weight:700; }
.kh-btn:hover, .kh-btn:focus-visible { outline:2px solid var(--accent, #7cf0b8); outline-offset:2px; }
.kh-fab { position:fixed; right:16px; bottom:16px; z-index:50; box-shadow:0 4px 18px rgba(0,0,0,.35); }
.kh-inline { float:right; margin:-4px -4px 0 8px; }
@media (max-width:560px){ .kh-fab .kh-label { display:none; } .kh-fab { padding:6px; } }
.kh-dialog { border:1px solid var(--line, #3a4352); border-radius:14px; background:#ffffff; color:#1b2230; padding:0; width:min(680px, calc(100vw - 32px)); max-height:86vh; }
.kh-dialog::backdrop { background:rgba(0,0,0,.55); }
.kh-body { padding:20px 22px 8px; overflow:auto; max-height:calc(86vh - 70px); line-height:1.5; }
.kh-body h2 { margin:0 0 6px; font-size:1.25rem; } .kh-body h3 { margin:16px 0 4px; font-size:.82rem; letter-spacing:.05em; text-transform:uppercase; color:#5b6678; }
.kh-body ol, .kh-body ul { padding-left:22px; margin:4px 0; } .kh-body li { margin:5px 0; }
.kh-badge { display:inline-block; margin:2px 0 4px; padding:2px 10px; border-radius:999px; font-size:.78rem; border:1px solid currentColor; }
.kh-tested { color:#15803d; } .kh-partial { color:#b45309; } .kh-untested { color:#c2410c; }
.kh-note { margin-top:14px; padding:10px 12px; border-radius:10px; background:rgba(127,127,127,.12); font-size:.9rem; }
.kh-foot { padding:10px 22px 16px; text-align:right; }

/* ---------- Studio Tools panels ---------- */
.kt-row { display:flex; flex-wrap:wrap; gap:10px; align-items:center; margin:10px 0; }
.kt-card { border:1px solid var(--line, #3a4352); border-radius:12px; padding:14px 16px; margin:12px 0; background:rgba(127,127,127,.06); }
.kt-card h2 { margin:0 0 6px; font-size:1rem; }
.kt-status { font-size:.9rem; color:var(--ink-soft, #9aa6b8); min-height:1.3em; }
.kt-status.err { color:#f87171; } .kt-status.ok { color:#4ade80; }
.kt-mouth { width:140px; height:140px; }
.kt-graph { width:100%; height:90px; background:rgba(127,127,127,.1); border-radius:8px; }
.kt-strip { display:flex; flex-wrap:wrap; gap:2px; font:600 11px ui-monospace,monospace; }
.kt-strip span { padding:2px 4px; border-radius:3px; background:rgba(127,127,127,.2); }
.kt-table { width:100%; border-collapse:collapse; font-size:.9rem; } .kt-table td, .kt-table th { text-align:left; padding:5px 8px; border-bottom:1px solid var(--line, #3a4352); }
.kt-list { list-style:none; padding:0; margin:6px 0; } .kt-list li { padding:6px 8px; border-radius:8px; cursor:pointer; } .kt-list li:hover, .kt-list li.sel { background:rgba(124,240,184,.14); }

/* Clone Chad (voice step) */
.clone-chad { margin-top: 1rem; padding-top: .75rem; border-top: 1px solid rgba(127,127,127,.25); }
.clone-chad textarea, .clone-chad input[type=text] { width: 100%; box-sizing: border-box; }
.agent-sliders { display: flex; gap: 1rem; flex-wrap: wrap; margin: .5rem 0; }
.agent-sliders label { display: flex; flex-direction: column; font-size: .85rem; }
