/* ═══════════════════════════════════════════════════════════════════
   Gusta GIF - theme + layout.
   Two themes: dark (default) and light via [data-theme='light'] on
   <html>. NEVER hardcode colors in components - use the tokens.
   Accent is the cyan SAMPLED from this product's own mark
   (assets/gusta-gif-mark-128.png, whose G runs cyan to blue to violet),
   per the family rule that each product wears an accent from its own
   logo. Gusta Draw's teal-green belongs to Gusta Draw.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  --bg: #0f1013;
  --surface: #17181d;
  --surface2: #1f2027;
  --surface3: #272831;
  --border: #2e3039;
  --text: #e8e8ef;
  --text-dim: #8b8d99;
  --accent: #00d0d0;            /* sampled from the mark's brightest gradient stop */
  --accent-dim: #00a3a8;
  --accent-bg: rgba(0, 208, 208, 0.12);
  --on-accent: #04232b;
  --accent-2: #6030f0;          /* the mark's violet end, for gradient touches */
  --danger: #ff5d5d;
  --rail-btn: 40px;
  --shadow: 0 8px 28px rgba(0, 0, 0, 0.45);
}

[data-theme='light'] {
  --bg: #eceef2;
  --surface: #f7f8fa;
  --surface2: #ffffff;
  --surface3: #e6e8ee;
  --border: #d3d6de;
  --text: #23242b;
  --text-dim: #6d6f7a;
  --accent: #07767e;            /* darkened for contrast on light surfaces */
  --accent-dim: #055e64;
  --accent-bg: rgba(7, 118, 126, 0.10);
  --on-accent: #ffffff;
  --accent-2: #4b1fc4;
  --shadow: 0 8px 28px rgba(30, 30, 40, 0.18);
}

* { box-sizing: border-box; }

html, body {
  margin: 0; height: 100%;
  background: var(--bg); color: var(--text);
  font: 13px/1.45 -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
}

body { display: flex; flex-direction: column; }
button { font: inherit; color: inherit; }
/* Sliders and checkboxes wear the product accent rather than the browser's. */
input { accent-color: var(--accent); }

.noscript-note {
  max-width: 60ch; margin: 24px auto; padding: 14px 16px;
  background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
}

.spacer { flex: 1 1 auto; }

/* Header labels have a long and a short form; the compact shell swaps them so
   every control still fits and nothing has to be hidden. */
.lbl-short { display: none; }

/* ── Header ─────────────────────────────────────────────────────── */
header {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px; background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex: 0 0 auto; position: relative; z-index: 20;
  overflow-x: clip;
}
.brand { display: flex; align-items: center; gap: 7px; margin-right: 6px; user-select: none; }
.brand-mark { border-radius: 5px; display: block; }
.brand-name { font-weight: 600; letter-spacing: 0.02em; white-space: nowrap; }

/* Segmented button clusters: adjacent buttons share borders and read as one
   control (the suite shell contract). */
.seg { display: inline-flex; }
.seg > button {
  background: var(--surface2); border: 1px solid var(--border);
  padding: 5px 10px; cursor: pointer; white-space: nowrap;
}
.seg > button + button { border-left: 0; }
.seg > button:first-child { border-radius: 6px 0 0 6px; }
.seg > button:last-child { border-radius: 0 6px 6px 0; }
.seg > button:only-child { border-radius: 6px; }
.seg > button:hover:not(:disabled) { background: var(--surface3); }
.seg > button:disabled { opacity: 0.4; cursor: default; }
.seg > button.primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); font-weight: 600; }
.seg > button.primary:hover:not(:disabled) { background: var(--accent-dim); border-color: var(--accent-dim); }

/* The family's standalone button (same component as gusta-draw / 3d / game). */
.tool-btn {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--surface2); border: 1px solid var(--border);
  color: var(--text); border-radius: 6px; padding: 5px 9px;
  cursor: pointer; white-space: nowrap;
}
.tool-btn:hover:not(:disabled) { border-color: var(--accent-dim); }
.tool-btn:disabled { opacity: 0.45; cursor: default; }
.tool-btn.is-active { background: var(--accent-bg); border-color: var(--accent); color: var(--accent); }
.tool-btn.wide { width: 100%; justify-content: center; margin-top: 4px; }

.link-btn {
  background: none; border: none; padding: 0; color: var(--accent);
  cursor: pointer; font-size: 12px;
}
.link-btn:hover { text-decoration: underline; }

/* The suite pill: in the other apps this opens the AI copilot. Here it opens
   the product launcher, which is the one door out to the rest of Gusta Labs. */
.gusta-pill {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--accent-bg); color: var(--accent);
  border: 1px solid var(--accent); border-radius: 999px;
  padding: 5px 12px; cursor: pointer; font-weight: 600;
}
.gusta-pill:hover { background: var(--accent); color: var(--on-accent); }

/* One-time attention pull after the first export: the moment someone has just
   made something is the moment the rest of the suite is worth a glance. A glow
   on the existing door, never a dialog that interrupts the win. */
.gusta-pill.is-nudge { animation: pill-nudge 1.1s ease-in-out 3; }
@keyframes pill-nudge {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  50% { box-shadow: 0 0 0 4px var(--accent-bg); }
}
@media (prefers-reduced-motion: reduce) {
  .gusta-pill.is-nudge { animation: none; background: var(--accent); color: var(--on-accent); }
}

/* ── Menus / popovers (family component) ────────────────────────── */
.menu-wrap { position: relative; }
.pop-menu {
  position: absolute; top: calc(100% + 6px); right: 0; min-width: 260px;
  background: var(--surface2); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px; box-shadow: var(--shadow); z-index: 100;
  /* Never run past the viewport on short screens: scroll inside the popover
     instead of growing the page. */
  max-height: calc(100vh - 64px); overflow-y: auto; overscroll-behavior: contain;
}
.pop-menu[hidden] { display: none; }
.menu-heading { font-weight: 600; margin-bottom: 6px; }
.menu-note { font-size: 11px; color: var(--text-dim); margin-top: 6px; line-height: 1.5; }
.menu-item {
  display: block; width: 100%; text-align: left;
  background: none; border: none; padding: 6px 8px; border-radius: 5px; cursor: pointer;
}
.menu-item:hover { background: var(--accent-bg); color: var(--accent); }
.menu-item.danger:hover { background: rgba(255, 93, 93, 0.12); color: var(--danger); }
.menu-sep { height: 1px; background: var(--border); margin: 5px 0; }

/* The context menu is the ONE pop-menu not anchored under a button: ui.js
   places it at the pointer. `right: auto` is load-bearing - .pop-menu pins
   itself to its wrapper's right edge, and setting `left` without clearing
   `right` leaves BOTH sides resolved, which CSS reads as "stretch". */
#context-menu { position: fixed; top: 0; left: 0; right: auto; min-width: 180px; }

/* ── Gustalabs app launcher (family component) ──────────────────── */
.launcher-grid { display: flex; flex-direction: column; gap: 4px; margin-top: 4px; }
.launcher-card {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 10px;
  border: 1px solid transparent; border-radius: 9px;
  background: transparent; text-align: left; cursor: pointer;
  font: inherit; color: inherit;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.launcher-card:hover:not(:disabled) { background: var(--surface3); border-color: var(--border); }
.launcher-card.here { cursor: default; opacity: 0.7; }
.launcher-card.coming-soon { cursor: default; opacity: 0.55; }
.launcher-card.coming-soon .launcher-mark img { filter: grayscale(1); }
.launcher-badge {
  margin-left: 6px; padding: 1px 5px; border-radius: 6px;
  font-size: 9px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--text-dim); background: var(--surface3);
  border: 1px solid var(--border); vertical-align: middle;
}
.launcher-mark { flex: none; width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; }
.launcher-mark img, .launcher-mark svg { width: 34px; height: 34px; border-radius: 8px; }
.launcher-text { display: flex; flex-direction: column; min-width: 0; }
.launcher-name { font-size: 13px; font-weight: 600; color: var(--text); }
.launcher-tagline { font-size: 11px; color: var(--text-dim); line-height: 1.3; }

/* ── Modal dialogs (family component) ───────────────────────────── */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(0, 0, 0, 0.45);
  display: flex; align-items: center; justify-content: center;
}
.modal-backdrop[hidden] { display: none; }
.modal [hidden] { display: none !important; }
.modal {
  background: var(--surface2); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: var(--shadow);
  padding: 14px; width: min(430px, calc(100vw - 32px));
  max-height: calc(100vh - 48px); overflow-y: auto;
}

/* Shortcut cheat sheet */
.shortcuts-modal { width: min(760px, calc(100vw - 32px)); }
.shortcuts-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px 20px; margin: 8px 0;
}
.shortcuts-col { min-width: 0; }
.shortcuts-h {
  font-size: 11px; font-weight: 700; color: var(--accent);
  text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 5px;
}
.shortcuts-row {
  display: flex; align-items: baseline; gap: 8px; font-size: 12px;
  padding: 2px 0; line-height: 1.4;
}
.shortcuts-row kbd {
  flex: 0 0 auto; font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 11px; color: var(--text); background: var(--surface);
  border: 1px solid var(--border); border-radius: 5px; padding: 1px 6px;
  white-space: nowrap;
}
.shortcuts-row span { color: var(--text-dim); min-width: 0; }
.modal-actions { display: flex; justify-content: flex-end; gap: 6px; margin-top: 10px; }

/* ── Main layout ────────────────────────────────────────────────── */
.main {
  flex: 1 1 auto; min-height: 0;
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr) auto;
  grid-template-rows: minmax(0, 1fr) auto;
}

.tool-rail {
  grid-column: 1; grid-row: 1 / 3;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 6px 4px; background: var(--surface);
  border-right: 1px solid var(--border); overflow-y: auto;
}
.tool-rail > button[data-tool] {
  /* flex: none, or a full rail in a short column silently shrinks every
     button below the touch floor - which is exactly what an iPad in
     landscape was getting. */
  flex: none;
  width: var(--rail-btn); height: var(--rail-btn);
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid transparent; border-radius: 8px;
  cursor: pointer; color: var(--text-dim);
}
.tool-rail > button[data-tool]:hover { background: var(--surface3); color: var(--text); }
.tool-rail > button[data-tool].is-active {
  background: var(--accent-bg); border-color: var(--accent); color: var(--accent);
}
.rail-divider { width: 24px; height: 1px; background: var(--border); margin: 6px 0; }

/* Tool options: only the active tool's controls are shown, so the rail stays
   a rail instead of becoming a second inspector. */
.rail-group { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.rail-group[hidden] { display: none; }
.rail-chips { display: grid; grid-template-columns: repeat(2, 1fr); gap: 3px; }
.rail-chips > button {
  width: 20px; height: 20px; padding: 0; line-height: 18px; font-size: 12px;
  background: var(--surface2); color: var(--text-dim);
  border: 1px solid var(--border); border-radius: 5px; cursor: pointer;
}
.rail-chips > button:hover { color: var(--text); }
.rail-chips > button.is-active { background: var(--accent-bg); border-color: var(--accent); color: var(--accent); }
.rail-check { display: flex; align-items: center; gap: 4px; font-size: 10px; color: var(--text-dim); }
#tolerance { width: 42px; }
.rail-field { width: 100%; text-align: center; }
.rail-label { display: block; font-size: 10px; color: var(--text-dim); margin-bottom: 2px; }
#brush-size { width: 42px; }
.swatches { display: grid; grid-template-columns: repeat(2, 1fr); gap: 3px; padding: 4px 2px; }
.swatch {
  width: 18px; height: 18px; border-radius: 4px; cursor: pointer;
  border: 1px solid var(--border); padding: 0;
}
.swatch.is-active { outline: 2px solid var(--accent); outline-offset: 1px; }
#color-custom {
  width: 40px; height: 26px; padding: 0; border: 1px solid var(--border);
  border-radius: 6px; background: none; cursor: pointer;
}

/* ── Stage ──────────────────────────────────────────────────────── */
.stage-frame { grid-column: 2; grid-row: 1; min-height: 0; min-width: 0; position: relative; }

/* The hint bar: one line, above the canvas, changing with what you are
   holding. It teaches the core loop at the moment the loop is relevant,
   which is the one thing no amount of tooltips achieves. */
.hint-bar {
  position: absolute; top: 8px; left: 50%; transform: translateX(-50%);
  z-index: 4; max-width: calc(100% - 24px);
  padding: 5px 12px; border-radius: 999px;
  background: var(--surface2); border: 1px solid var(--border);
  color: var(--text-dim); font-size: 12px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; box-shadow: var(--shadow);
  pointer-events: none;
}
.hint-bar[hidden] { display: none; }
.hint-bar b { color: var(--text); font-weight: 600; }
.hint-bar kbd {
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 11px;
  color: var(--accent); background: var(--accent-bg);
  border: 1px solid var(--accent-dim); border-radius: 4px; padding: 0 4px;
}

/* Object verbs only make sense while you are holding something. */
.obj-verbs[hidden] { display: none; }
.obj-verbs > button { min-width: 30px; }
.stage-wrap {
  position: absolute; inset: 0; overflow: hidden;
  background: var(--bg); touch-action: none;
}
#view { display: block; cursor: crosshair; }
.stage-wrap.is-pan-ready #view { cursor: grab; }
.stage-wrap.is-pan #view { cursor: grabbing; }
body[data-tool='select'] #view { cursor: default; }

/* The first-run welcome card (family pattern: the suite greets you with what
   to do next, never a blank room). Retires the moment the document has
   anything in it, and never comes back uninvited. */
.welcome {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(420px, calc(100% - 32px));
  padding: 18px 20px 14px; border-radius: 12px; z-index: 5;
  background: var(--surface2); border: 1px solid var(--border); box-shadow: var(--shadow);
}
.welcome[hidden] { display: none; }
.welcome h1 { margin: 0 0 2px; font-size: 17px; font-weight: 600; }
.welcome .welcome-sub { color: var(--text-dim); margin: 0 0 12px; line-height: 1.5; }
.welcome-steps { display: flex; flex-direction: column; gap: 6px; }
.welcome-step {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 10px; border-radius: 9px; cursor: pointer; text-align: left;
  background: transparent; border: 1px solid var(--border); color: inherit; font: inherit;
}
.welcome-step:hover { background: var(--surface3); border-color: var(--accent-dim); }
.welcome-step .step-key {
  flex: none; min-width: 92px; text-align: center;
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 11px;
  color: var(--accent); background: var(--accent-bg);
  border: 1px solid var(--accent-dim); border-radius: 6px; padding: 2px 6px;
}
.welcome-step .step-text { color: var(--text); }
.welcome-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border);
  color: var(--text-dim); font-size: 12px;
}

/* The suite sign-off: this app is free and has no account, so the footer link
   is the whole invitation into the rest of the platform. */
.gusta-foot { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.gusta-foot a { color: var(--text-dim); text-decoration: none; }
.gusta-foot a:hover { color: var(--accent); text-decoration: underline; }

.drop-veil {
  position: absolute; inset: 12px; display: flex; align-items: center; justify-content: center;
  border: 2px dashed var(--accent); border-radius: 12px; background: var(--accent-bg);
  color: var(--accent); font-weight: 600; pointer-events: none;
}
.drop-veil[hidden] { display: none; }

/* The inline text editor: a textarea that visually replaces the label it
   edits, so what you type sits where it lands. */
.text-editor {
  position: absolute; margin: 0; padding: 0 2px;
  background: transparent; border: 1px dashed var(--accent); outline: none;
  resize: none; overflow: hidden; white-space: pre;
}
.text-editor[hidden] { display: none; }

/* ── Timeline (transport + film strip) ──────────────────────────── */
.timeline {
  grid-column: 2 / 4; grid-row: 2;
  background: var(--surface); border-top: 1px solid var(--border);
}
.transport {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 6px 10px; border-bottom: 1px solid var(--border);
}
.transport button {
  background: var(--surface2); border: 1px solid var(--border); border-radius: 6px;
  padding: 5px 10px; cursor: pointer; white-space: nowrap;
}
.transport button:hover:not(:disabled) { background: var(--surface3); }
.transport button:disabled { opacity: 0.4; cursor: default; }
.transport button.primary-ghost { border-color: var(--accent); color: var(--accent); font-weight: 600; min-width: 64px; }
.t-sep { width: 1px; height: 20px; background: var(--border); }
.t-field, .t-check { display: inline-flex; align-items: center; gap: 5px; color: var(--text-dim); white-space: nowrap; }
.t-field input, .t-field select {
  background: var(--surface2); color: var(--text); border: 1px solid var(--border);
  border-radius: 5px; padding: 4px 6px; font: inherit;
}
.t-field input[type='number'] { width: 62px; }

.strip {
  display: flex; gap: 6px; align-items: flex-start;
  padding: 8px 10px; overflow-x: auto; overflow-y: hidden;
  min-height: 92px; scrollbar-width: thin;
}
.frame-item {
  position: relative; flex: 0 0 auto; padding: 3px; border-radius: 8px;
  border: 2px solid transparent; cursor: pointer; touch-action: none;
  background: var(--surface2);
}
.frame-item.is-current { border-color: var(--accent); }
.frame-item.is-dragging { opacity: 0.45; }
.frame-item.is-drop { box-shadow: -3px 0 0 var(--accent); }
.frame-thumb { display: block; border-radius: 4px; background: var(--surface3); }
.frame-num {
  position: absolute; left: 6px; bottom: 6px; padding: 0 5px; border-radius: 4px;
  background: rgba(0, 0, 0, 0.6); color: #fff; font-size: 10px; line-height: 15px;
}
.frame-del {
  position: absolute; top: 5px; right: 5px; width: 18px; height: 18px; padding: 0;
  border: 0; border-radius: 50%; cursor: pointer; line-height: 18px; font-size: 11px;
  background: rgba(0, 0, 0, 0.6); color: #fff; opacity: 0;
}
.frame-item:hover .frame-del, .frame-item.is-current .frame-del { opacity: 1; }
.frame-del:hover { background: var(--danger); }

/* ── Layers dock (right) ────────────────────────────────────────── */
/* Layers are DOCUMENT level, so this panel does not change as you step
   through frames - only the pixels the active layer is showing do. */
.layers {
  grid-column: 3; grid-row: 1;
  width: 190px; display: flex; flex-direction: column; min-height: 0;
  background: var(--surface); border-left: 1px solid var(--border);
}
/* Collapsed: the family's slim strip. A vertical label reopens it, because a
   lone caret hides every layer control behind a guess. */
.layers.is-collapsed { width: 30px; cursor: pointer; }
.layers.is-collapsed:hover { background: var(--surface2); }
.layers.is-collapsed .layer-list,
.layers.is-collapsed .layers-foot { display: none; }
.layers.is-collapsed .layers-head {
  flex-direction: column; gap: 8px; height: 100%; padding: 10px 4px;
  justify-content: flex-start; border-bottom: 0;
}
.layers.is-collapsed .layers-title {
  writing-mode: vertical-rl; letter-spacing: 0.08em; white-space: nowrap;
}
.layers.is-collapsed .layers-collapse { transform: rotate(90deg); }

.layers-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 8px; border-bottom: 1px solid var(--border);
}
.layers-title { font-size: 11px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em; }
.layers-collapse {
  background: none; border: 0; color: var(--text-dim); cursor: pointer;
  padding: 0 2px; line-height: 1; font-size: 12px;
}
.layers-collapse:hover { color: var(--text); }

.layer-list { flex: 1 1 auto; overflow-y: auto; padding: 4px; min-height: 0; }
.layer-row {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 6px; border-radius: 6px; cursor: pointer;
  border: 1px solid transparent; touch-action: none; user-select: none;
}
.layer-row:hover { background: var(--surface2); }
.layer-row.is-active { background: var(--accent-bg); border-color: var(--accent); }
.layer-row.is-hidden .layer-name { opacity: 0.45; text-decoration: line-through; }
.layer-row.is-dragging { opacity: 0.45; }
.layer-row.is-drop { box-shadow: 0 -3px 0 var(--accent); }
.layer-eye {
  flex: none; display: inline-flex; padding: 0; border: 0; cursor: pointer;
  background: none; color: var(--text-dim);
}
.layer-eye:hover { color: var(--text); }
.layer-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
.layer-pct { flex: none; font-size: 10px; color: var(--text-dim); }
.layer-rename {
  flex: 1 1 auto; min-width: 0; font: inherit; font-size: 12px;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--accent); border-radius: 4px; padding: 1px 4px;
}

.layers-foot { padding: 6px 8px; border-top: 1px solid var(--border); }
#layer-opacity { width: 100%; }
.layers-actions { display: flex; gap: 4px; margin-top: 6px; }
.layers-actions button {
  flex: 1 1 auto; padding: 4px 6px; font-size: 11px; cursor: pointer;
  background: var(--surface2); color: var(--text);
  border: 1px solid var(--border); border-radius: 5px;
}
.layers-actions button:hover:not(:disabled) { border-color: var(--accent-dim); }
.layers-actions button:disabled { opacity: 0.4; cursor: default; }
#smudge-strength { width: 42px; }

/* ── Motion / caption popovers ──────────────────────────────────── */
.motion-menu, .caption-menu { min-width: 268px; top: auto; bottom: calc(100% + 6px); }
.motion-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; }
.motion-grid > button {
  padding: 6px 8px; font-size: 12px; cursor: pointer; text-align: left;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 6px;
}
.motion-grid > button:hover { border-color: var(--accent); color: var(--accent); }
.motion-grid > button.is-active { background: var(--accent-bg); border-color: var(--accent); color: var(--accent); }
.menu-heading-2 { margin-top: 10px; }
.motion-count { margin-top: 10px; }
.motion-count input { width: 62px; }

/* A collapsed run of generated frames: one row, labelled with what made it. */
.frame-group { border-style: dashed; border-color: var(--border); }
.frame-group.is-current { border-style: solid; border-color: var(--accent); }
.frame-groupname {
  /* The delete button only appears on hover, so the label may use the full
     width the rest of the time rather than reserving space for it. */
  position: absolute; left: 6px; top: 6px; max-width: calc(100% - 12px);
  padding: 1px 5px; border-radius: 4px; font-size: 9px; line-height: 14px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  background: var(--accent); color: var(--on-accent); font-weight: 600;
}
/* Expanded members read as one run rather than unrelated frames. */
.frame-item.in-group { box-shadow: inset 0 -3px 0 var(--accent-dim); }

/* ── Footer ─────────────────────────────────────────────────────── */
footer {
  display: flex; align-items: center; gap: 10px;
  padding: 5px 10px; background: var(--surface);
  border-top: 1px solid var(--border); flex: 0 0 auto;
  color: var(--text-dim);
}
.status { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.readout { white-space: nowrap; }
footer .seg > button { padding: 3px 9px; }

/* ── About / indexable content ──────────────────────────────────── */
/* Real, visible copy, not hidden keyword text. It sits over the editor when
   opened and is present in the HTML for crawlers either way. */
.about {
  position: fixed; inset: 0; z-index: 150; overflow-y: auto;
  background: var(--bg); padding: 32px 20px 64px;
}
.about[hidden] { display: none; }
.about-inner { max-width: 68ch; margin: 0 auto; line-height: 1.65; }
.about-inner h1 { font-size: 26px; margin: 0 0 12px; }
.about-inner h2 { font-size: 17px; margin: 28px 0 8px; color: var(--accent); }
.about-inner h3 { font-size: 14px; margin: 18px 0 4px; }
.about-inner p, .about-inner li { color: var(--text-dim); }
.about-inner b { color: var(--text); }
.about-inner ol, .about-inner ul { padding-left: 20px; }
.about-inner li { margin: 5px 0; }
.about-foot { margin-top: 28px; padding-top: 16px; border-top: 1px solid var(--border); }
#about-close { margin-top: 16px; }

/* ── Export progress ────────────────────────────────────────────── */
.progress-bar {
  position: fixed; left: 50%; bottom: 76px; transform: translateX(-50%);
  width: min(340px, 80vw); height: 34px; border-radius: 999px; overflow: hidden;
  background: var(--surface2); border: 1px solid var(--border); box-shadow: var(--shadow);
  display: flex; align-items: center; z-index: 40;
}
.progress-bar[hidden] { display: none; }
.progress-fill { position: absolute; inset: 0 auto 0 0; width: 0; background: var(--accent-bg); transition: width 0.12s linear; }
.progress-text { position: relative; width: 100%; text-align: center; font-weight: 600; }

/* ── Compact shell (phones and coarse-pointer tablets) ──────────── */
/* Touch targets grow and the rail becomes a horizontal strip above the
   stage; nothing is measured or positioned in JS. */
/* ── Touch sizing: ANY coarse pointer, at any width ──────────────── */
/* This used to be bundled into the layout query and capped at 1100px, so a
   real iPad in landscape (1180 CSS px, coarse pointer) fell through to the
   desktop shell and got 31px controls. Pointer type and screen width are two
   different questions and are now asked separately. */
@media (pointer: coarse) {
  :root { --rail-btn: 44px; }
  /* Apple's 44px floor. Anything a finger has to hit gets it. */
  .seg > button, .transport button, .tool-btn, .gusta-pill,
  .layers-actions button, .motion-grid > button, .menu-item {
    min-height: 44px;
  }
  .seg > button, .transport button { padding: 10px 12px; }
  .tool-btn { padding: 10px; }
  .frame-del { width: 26px; height: 26px; line-height: 26px; font-size: 13px; opacity: 1; }
  .layer-row { padding: 9px 8px; }
  .layer-eye { padding: 4px; }
  .swatch { width: 34px; height: 34px; }
  input[type='range'] { height: 32px; }
  .t-field input, .t-field select { min-height: 40px; }
  footer .seg > button { min-height: 40px; padding: 6px 12px; }
  /* The stragglers a finger genuinely cannot hit. */
  .layers-collapse { padding: 10px; font-size: 15px; }
  #color-custom { height: 40px; }
  .t-check input[type='checkbox'] { width: 22px; height: 22px; }
  .link-btn { padding: 8px 4px; }
}

/* ── Compact LAYOUT: the stacked shell ──────────────────────────── */
/* Stacked only when the screen is NARROW. A tablet in landscape is wide, and
   stacking there spends height the canvas wants: the side layout gives an
   iPad landscape a taller stage than the stacked one does. Touch sizing is a
   separate question and is handled above. */
@media (max-width: 860px), (pointer: coarse) and (max-width: 900px) {
  :root { --rail-btn: 44px; }
  .main { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto auto; }
  .tool-rail {
    grid-column: 1; grid-row: 1;
    flex-direction: row; align-items: center; overflow-x: auto; overflow-y: hidden;
    border-right: 0; border-bottom: 1px solid var(--border);
  }
  .rail-divider { width: 1px; height: 24px; margin: 0 4px; }
  .rail-field { width: auto; display: flex; align-items: center; gap: 6px; }
  .rail-label { margin: 0; }
  #brush-size { width: 90px; }
  .swatches { grid-template-columns: repeat(5, 1fr); }
  .stage-frame { grid-column: 1; grid-row: 2; }
  .timeline { grid-column: 1; grid-row: 4; }
  /* The dock cannot be a column on a phone, so it becomes a short strip
     between the stage and the timeline. */
  .layers {
    grid-column: 1; grid-row: 3; width: auto; max-height: 132px;
    border-left: 0; border-top: 1px solid var(--border);
  }
  .layers.is-collapsed { width: auto; max-height: 30px; }
  .layer-list { max-height: 76px; }
  .strip { min-height: 78px; }
  .brand-name { display: none; }

  /* One scrolling row, not three wrapped ones. On a 375px phone the wrapped
     transport ate more height than the canvas it was controlling. */
  .transport {
    flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .transport::-webkit-scrollbar { display: none; }
  .transport > * { flex: 0 0 auto; }

  /* The header must never clip a control off the right edge (the launcher is
     the one door out of the app, and a clipped door is a missing one). Labels
     collapse first; if it still does not fit, the row wraps rather than
     hiding anything. */
  /* 6px column gap is not cosmetic: at 430 CSS px it is exactly what lets the
     launcher pill share the first row instead of being orphaned on a second.
     Narrower than that the row wraps, which is the intended last resort. */
  header { flex-wrap: wrap; gap: 6px; overflow-x: visible; }
  .brand { margin-right: 0; }
  /* Pack left so a wrap reads as a deliberate second row rather than two
     controls stranded under a gap. */
  header .spacer { display: none; }
  .lbl-full { display: none; }
  .lbl-short { display: inline; }
  .gusta-pill .btn-label { display: none; }
  .gusta-pill { padding: 7px 12px; }
  .pop-menu { min-width: min(280px, calc(100vw - 24px)); }
  .welcome-step .step-key { min-width: 84px; }
}

/* The overflow button only exists on phones. */
.header-more { display: none; }
.header-extra { display: contents; }

/* ── Phones: the canvas has to win ───────────────────────────────── */
@media (max-width: 560px) {
  /* The header wrapped to TWO rows (107px of a 690px screen) because seven
     controls cannot fit 320px. The secondary three fold behind one button. */
  header { flex-wrap: nowrap; }
  .header-more { display: inline-flex; }
  .header-extra {
    display: none; position: absolute; top: calc(100% + 4px); right: 8px;
    z-index: 110; flex-direction: column; gap: 6px; padding: 8px;
    background: var(--surface2); border: 1px solid var(--border);
    border-radius: 10px; box-shadow: var(--shadow);
  }
  header.is-open .header-extra { display: flex; }
  .header-extra .tool-btn, .header-extra .gusta-pill { width: 100%; justify-content: flex-start; }
  .header-extra .gusta-pill .btn-label { display: inline; }
  /* The launcher popover hangs off its wrapper, which now sits inside a
     popover of its own: pin it to the viewport edge instead of the wrapper. */
  .header-extra .pop-menu { position: fixed; top: auto; right: 8px; left: 8px; min-width: 0; }

  /* The rail was 92px tall because the size field and swatches stacked under
     the tools. One scrolling line instead. */
  .tool-rail { flex-wrap: nowrap; padding: 4px 6px; gap: 6px; }
  .tool-rail > button[data-tool] { width: 44px; height: 44px; }
  .rail-divider { height: 28px; }
  .rail-group, .rail-field { flex-direction: row; align-items: center; gap: 6px; }
  .rail-label { font-size: 10px; }
  #brush-size, #tolerance, #smudge-strength { width: 76px; }
  .swatches { display: flex; flex-wrap: nowrap; gap: 4px; }
  .swatch { width: 30px; height: 30px; }
  #color-custom { width: 34px; }

  /* The layers strip is HORIZONTAL here, so the collapsed dock's vertical
     label (which is right in a side column) must not follow it across. */
  .layers.is-collapsed .layers-head { flex-direction: row; height: auto; padding: 4px 8px; }
  .layers.is-collapsed .layers-title { writing-mode: horizontal-tb; }
  .layers.is-collapsed .layers-collapse { transform: rotate(0deg); }

  /* No min-height: it forced the stage past its own grid row and made it
     overlap the layers strip. The row is minmax(0, 1fr) and already gets
     everything the other rows do not take - the fix is to make them take
     less, which is what the rules above do. */
  .stage-frame { min-height: 0; }
  .strip { min-height: 68px; padding: 6px; }
  .frame-thumb { max-width: 76px; }
  .layers.is-collapsed { max-height: 26px; }
  .layers-title { font-size: 10px; }

  /* The zoom cluster and the size readout are the least useful thing on a
     device with pinch: two fingers already do it. */
  footer .seg, #canvas-readout { display: none; }
  footer { padding: 4px 8px; }
  .status { font-size: 11px; }

  /* A keyboard shortcut is not an instruction you can follow on a phone.
     The paste step is hidden there, which both makes the card correct and
     takes a third off its height - it was covering 294px of a 514px stage. */
  #welcome-paste { display: none; }
  .welcome-foot { display: block; margin-top: 8px; padding-top: 8px; font-size: 11px; }
  .welcome-foot .link-btn { display: inline-block; margin-top: 4px; }

  /* The film strip does not need a 94px row on a phone. */
  .strip { min-height: 58px; }
  /* The thumbnail size itself is set in framesPanel.js; see the note there. */

  /* A short screen must not clip the welcome card's heading off the top. */
  .welcome {
    top: 8px; transform: translateX(-50%);
    max-height: calc(100% - 16px); overflow-y: auto;
    padding: 14px 16px 12px;
  }
  .welcome h1 { font-size: 15px; }
  /* Under 380px the sub-copy is three wrapped lines for a card that is
     already covering most of the canvas. The steps say the same thing. */
  @media (max-width: 380px) { .welcome .welcome-sub { display: none; } }
  .welcome .welcome-sub { margin-bottom: 8px; font-size: 12px; }
  .welcome-step { padding: 8px; }
  .welcome-step .step-key { min-width: 72px; font-size: 10px; }
  .welcome-step .step-text { font-size: 12px; }

  .hint-bar { font-size: 11px; padding: 4px 10px; top: 6px; }
  .about { padding: 20px 14px 48px; }
}

/* Nothing may push the document sideways; a canvas app that scrolls
   horizontally feels broken before you have drawn anything. */
html, body { max-width: 100%; overflow-x: hidden; }
