/* TypeMotion Engine 0.4 — workspace UI. Bold dark glass, precision studio (visual polish pass: material hierarchy).
 * The interface provides atmosphere; the artwork stays the hero: nothing here styles the imported SVG
 * (it lives in a shadow root) and no effect is ever drawn over it. */

/* ======================================================================== tokens */
:root {
  color-scheme: dark;
  /* palette */
  --graphite: #111416;
  --workspace: #171c1e;
  --smoke: #252c30;
  --raised: #30393d;
  --glass-border: rgba(231, 236, 238, 0.12);
  --glass-border-soft: rgba(231, 236, 238, 0.07);
  --glass-hi: rgba(255, 255, 255, 0.08);
  --text: #e7ecee;
  --dim: #c3cccf;
  --muted: #929fa2;
  --faint: #66726f;
  --accent: #c8f36a;
  --accent-2: #819d54;
  --accent-ink: #12170b;
  --accent-soft: rgba(200, 243, 106, 0.1);
  --accent-line: rgba(200, 243, 106, 0.55);
  --err: #f0897c;
  --err-bg: rgba(240, 137, 124, 0.1);
  --warn: #e3bd68;
  --warn-bg: rgba(227, 189, 104, 0.09);
  --ok: #b6dc8c;
  --ok-bg: rgba(182, 220, 140, 0.08);
  --morph: #8bbcf0;
  --xfade: #c9a5f1;

  /* ---- light ------------------------------------------------------------------------
   * ONE key light, from the top-left. Every surface follows it: highlights on top/left edges, a darker
   * lower edge, shadows cast down and to the right, light washing across glass from the upper-left. */

  /* ---- glass materials ------------------------------------------------------------
   * Measured diagnosis (0.4 polish): surfaces already transmitted 31–51% of the background, but the
   * environment behind them was featureless, so glass read as opaque card. The fix is the environment
   * (body background) + lighting, with moderately lower tint — not "more blur".
   *  primary   top bar, tools/layers, inspector, timeline dock — tinted smoked glass + backdrop blur
   *  canvas    the canvas card frame — thicker glass (no blur pass: see .viewport)
   *  secondary tab tray, control groups, buttons — translucent sheets on the primary glass (never a nested blur)
   *  base      inspector sections, preset cards, status bar — a quieter etched layer
   *  active    selected tool / tab / segment — brighter glass, lime indicator, fine luminous edge
   *  inset     fields, tracks, timecode, the canvas well — darker, more opaque, recessed */
  --glass-float:
    linear-gradient(142deg, rgba(255, 255, 255, 0.085) 0%, rgba(255, 255, 255, 0.025) 26%, rgba(255, 255, 255, 0) 52%, rgba(0, 0, 0, 0.12) 100%),
    rgba(15, 19, 21, 0.44);
  --glass-canvas:
    linear-gradient(142deg, rgba(255, 255, 255, 0.07) 0%, rgba(255, 255, 255, 0.02) 30%, rgba(0, 0, 0, 0.1) 100%),
    rgba(14, 17, 19, 0.7);
  --glass-filter: blur(28px) saturate(90%) brightness(0.8); /* brightness keeps text contrast over bright light fields; low saturation keeps the environment's lime from blooming into patches behind text */
  --glass-raised: linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.04));
  --glass-raised-hover: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0.065));
  --glass-tray: linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.025));
  --glass-active: linear-gradient(180deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.09));
  --glass-active-edge: 0 0 0 1px rgba(200, 243, 106, 0.4), 0 0 12px -5px rgba(200, 243, 106, 0.45);
  --glass-base: linear-gradient(180deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.015));
  --glass-base-solid: rgba(12, 15, 17, 0.5);
  --glass-solid: #191f22; /* fallback when backdrop-filter is unsupported: opaque, still layered */
  --inset: rgba(6, 8, 9, 0.82);
  --inset-strong: rgba(5, 7, 8, 0.92);
  --inset-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.6), inset 0 0 0 1px rgba(0, 0, 0, 0.25), 0 1px 0 rgba(255, 255, 255, 0.06);
  --edge-secondary: inset 0 1px 0 rgba(255, 255, 255, 0.16), inset 1px 0 0 rgba(255, 255, 255, 0.05), inset 0 -1px 0 rgba(0, 0, 0, 0.3);
  --blur-float: 26px;
  --blur-base: 14px;
  --blur: var(--blur-float);
  /* glass rim: bright where the key light hits (top-left), fading around the panel, faint lime reflection bottom-right */
  --edge-light: linear-gradient(135deg, rgba(255, 255, 255, 0.42) 0%, rgba(255, 255, 255, 0.13) 20%, rgba(255, 255, 255, 0.045) 48%, rgba(255, 255, 255, 0.02) 78%, rgba(200, 243, 106, 0.12) 100%);
  /* specular bloom where the light enters the glass (top-left), plus a faint caustic along the top */
  --sheen: radial-gradient(380px 160px at 6% -24px, rgba(255, 255, 255, 0.12), transparent 70%), linear-gradient(180deg, rgba(255, 255, 255, 0.04), transparent 90px);

  /* shape, space, depth, motion */
  --r-panel: 14px;
  --r-box: 10px;
  --r-ctl: 7px;
  --r-sm: 5px;
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --gap: 14px; /* wider gutters: the environment must be visible around the glass to be read through it */
  --ctl-h: 30px;
  --shadow-panel: 0 22px 44px -22px rgba(0, 0, 0, 0.75), 0 2px 8px rgba(0, 0, 0, 0.35);
  /* elevation (shadows fall down-right, away from the key light). Top bar floats highest, side panels and dock
     next, the canvas card sits lowest so the artwork frame feels anchored. Each ends with a darker lower edge. */
  --shadow-top: 14px 34px 64px -26px rgba(0, 0, 0, 0.92), 4px 12px 24px -12px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(0, 0, 0, 0.3), inset 0 -1px 0 rgba(0, 0, 0, 0.45);
  --shadow-float: 12px 30px 58px -26px rgba(0, 0, 0, 0.88), 3px 10px 20px -10px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(0, 0, 0, 0.3), inset 0 -1px 0 rgba(0, 0, 0, 0.45);
  --shadow-low: 6px 16px 34px -18px rgba(0, 0, 0, 0.8), 0 0 0 1px rgba(0, 0, 0, 0.35), inset 0 -1px 0 rgba(0, 0, 0, 0.5);
  --shadow-raised: 1px 2px 3px rgba(0, 0, 0, 0.4), var(--edge-secondary);
  --ring: 0 0 0 2px var(--accent-line);
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --t-fast: 110ms;
  --t: 170ms;
  --font: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", Consolas, monospace;
}

/* ======================================================================== base */
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  color: var(--text);
  font: 13px/1.45 var(--font);
  -webkit-font-smoothing: antialiased; /* crisper light-on-dark text on macOS (no effect elsewhere) */
  -moz-osx-font-smoothing: grayscale;
  overflow: hidden;
  background: #020303;
}
/* ENVIRONMENT (static, never animated): the Glass Ribbons image, cover-fitted to the window with its aspect kept
 * and centred, so its dark middle sits behind the canvas and the ribbons frame the panels. A 10 % dim and a soft
 * vignette keep it under the UI. A fixed layer of its own (not the body's background) so Focus can filter it alone.
 * It takes no pointer events and never reaches the canvas (an opaque well) or the exported SVG/video. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(130% 110% at 50% 38%, transparent 58%, rgba(0, 0, 0, 0.55) 100%),
    linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)),
    #020303 url("../assets/environment/glass-ribbons.webp") 50% 50% / cover no-repeat;
  transition: filter 250ms var(--ease);
}
/* Focus (view only, F): the environment in black and white, dimmed, so the interface's lime is the only colour left */
body.env-focus::before { filter: grayscale(1) brightness(0.65); }
@media (prefers-reduced-motion: reduce) { body::before { transition: none; } }
button, input, select { font: inherit; color: inherit; }
::selection { background: rgba(200, 243, 106, 0.28); }
.hidden { display: none !important; }
.muted { color: var(--muted); }
kbd { border: 1px solid var(--glass-border); border-bottom-width: 2px; border-radius: 4px; padding: 0 4px; font: 10.5px var(--mono); color: var(--dim); background: rgba(255, 255, 255, 0.04); }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--accent-line); outline-offset: 1px; }

/* ---------------------------------------------------------------- controls */
button {
  cursor: pointer;
  height: var(--ctl-h);
  padding: 0 11px;
  border: 1px solid var(--glass-border);
  border-radius: var(--r-ctl);
  background: var(--glass-raised); /* material B */
  box-shadow: var(--shadow-raised);
  white-space: nowrap;
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
button:hover:not(:disabled) { background: var(--glass-raised-hover); border-color: rgba(231, 236, 238, 0.2); }
button:active:not(:disabled) { transform: scale(0.96); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5); }
/* disabled: dimmed, flat (no raised highlight), no hover — distinguishable without relying on transparency alone */
button:disabled { opacity: 0.42; cursor: not-allowed; background: rgba(255, 255, 255, 0.025); box-shadow: none; border-style: dashed; border-color: rgba(231, 236, 238, 0.1); }
button.primary { background: linear-gradient(180deg, #d4fb7f, var(--accent)); border-color: rgba(220, 255, 150, 0.9); color: var(--accent-ink); font-weight: 650; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55), 0 1px 2px rgba(0, 0, 0, 0.45), 0 8px 18px -10px rgba(200, 243, 106, 0.5); }
button.primary:hover:not(:disabled) { background: linear-gradient(180deg, #e0ff97, #d2fb7c); border-color: #e0ff97; }
button.primary:disabled { background: rgba(200, 243, 106, 0.16); border: 1px dashed rgba(200, 243, 106, 0.35); color: rgba(200, 243, 106, 0.7); box-shadow: none; }
button.ghost { background: transparent; border-color: transparent; box-shadow: none; }
button.ghost:hover:not(:disabled) { background: var(--glass-raised); border-color: var(--glass-border); box-shadow: var(--shadow-raised); }
button.ghost:disabled { border-color: transparent; background: transparent; }
button.danger:hover:not(:disabled) { color: var(--err); border-color: rgba(240, 137, 124, 0.45); }
button.small { height: 26px; padding: 0 9px; font-size: 12px; }
button.icon { width: var(--ctl-h); padding: 0; display: inline-grid; place-items: center; font-size: 14px; }
/* one icon set: inline 16px outline SVGs drawn in currentColor (hover / active / disabled come from the button) */
.svg-ic { display: block; flex: none; }

select, input[type=text], input[type=number] {
  height: var(--ctl-h);
  width: 100%;
  padding: 0 9px;
  border: 1px solid rgba(231, 236, 238, 0.08);
  border-radius: var(--r-ctl);
  background: var(--inset); /* material E */
  box-shadow: var(--inset-shadow);
  color: var(--text);
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
select:disabled, input:disabled { opacity: 0.45; cursor: not-allowed; }
input[type=number] { font-variant-numeric: tabular-nums; padding-right: 4px; }
select { padding-right: 4px; }
select:hover, input[type=text]:hover, input[type=number]:hover { border-color: var(--glass-border); }
select:focus, input[type=text]:focus, input[type=number]:focus { border-color: var(--accent-line); box-shadow: var(--inset-shadow), var(--ring); }
select option { background: var(--smoke); }
input[type=checkbox] { accent-color: var(--accent); width: 14px; height: 14px; margin: 0; }

/* range: recessed track (material E) + raised frost thumb with a lime rim. Visual only — value, min/max/step
   and input/change events are the browser's native ones, so slider ↔ number-field sync is unchanged. */
input[type=range] { -webkit-appearance: none; appearance: none; width: 100%; height: 18px; margin: 0; background: transparent; cursor: pointer; }
input[type=range]::-webkit-slider-runnable-track { height: 4px; border-radius: 4px; background: var(--inset-strong); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.7), 0 1px 0 rgba(255, 255, 255, 0.06); }
input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 14px; height: 14px; margin-top: -5px; border-radius: 50%; background: linear-gradient(180deg, #f3f6f7, #c4ccce); border: 2px solid var(--accent); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.6); transition: transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease); }
input[type=range]:hover::-webkit-slider-thumb { transform: scale(1.1); }
input[type=range]:focus-visible { outline: none; }
input[type=range]:focus-visible::-webkit-slider-thumb { box-shadow: 0 2px 5px rgba(0, 0, 0, 0.6), var(--ring); }
input[type=range]::-moz-range-track { height: 4px; border-radius: 4px; background: var(--inset-strong); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.7); }
input[type=range]::-moz-range-progress { height: 4px; border-radius: 4px; background: var(--accent-2); }
input[type=range]::-moz-range-thumb { width: 11px; height: 11px; border-radius: 50%; background: linear-gradient(180deg, #f3f6f7, #c4ccce); border: 2px solid var(--accent); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.6); }

/* segmented control: inset well (E) holding raised/active segments (D) */
/* control groups (scope switch, view controls) = SECONDARY glass tray holding transparent segments */
.seg { display: inline-flex; align-items: stretch; height: var(--ctl-h); border: 1px solid rgba(231, 236, 238, 0.11); border-radius: var(--r-ctl); background: var(--glass-tray); box-shadow: var(--edge-secondary), 1px 2px 4px rgba(0, 0, 0, 0.3); padding: 2px; gap: 2px; }
/* inner radius = tray radius − (1px border + 2px padding): concentric corners */
.seg button { height: auto; border: 1px solid transparent; border-radius: calc(var(--r-ctl) - 3px); background: transparent; box-shadow: none; padding: 0 9px; font-size: 12px; color: var(--dim); }
.seg button:hover:not(:disabled) { background: rgba(255, 255, 255, 0.06); border-color: transparent; color: var(--text); }
.seg button.active { background: var(--glass-active); color: var(--accent); border-color: rgba(231, 236, 238, 0.2); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22), inset 0 -2px 0 var(--accent), 1px 2px 4px rgba(0, 0, 0, 0.45); font-weight: 600; }
.seg button.icon { width: 26px; padding: 0; font-size: 14px; } /* equal-width −/+ around the zoom label */
.zoom-label { font: 11px var(--mono); color: var(--dim); padding: 0 6px; min-width: 46px; display: inline-grid; place-items: center; font-variant-numeric: tabular-nums; }

/* ======================================================================== glass system */
/* PRIMARY glass — top bar, tools/layers, inspector, timeline dock. Tinted smoked glass that blurs and darkens the
   environment behind it, a light wash from the top-left, a masked rim (::after) and a specular bloom (::before). */
.panel, .topbar {
  position: relative;
  background: var(--glass-float);
  border: 0;
  border-radius: var(--r-panel);
  box-shadow: var(--shadow-float);
  -webkit-backdrop-filter: var(--glass-filter);
  backdrop-filter: var(--glass-filter);
}
/* the side panels hold the densest text over the brightest ribbons: a denser smoke there */
.left-panel, .inspector-panel {
  --glass-float:
    linear-gradient(142deg, rgba(255, 255, 255, 0.085) 0%, rgba(255, 255, 255, 0.025) 26%, rgba(255, 255, 255, 0) 52%, rgba(0, 0, 0, 0.12) 100%),
    rgba(12, 15, 17, 0.6);
}
.topbar { box-shadow: var(--shadow-top); z-index: 20; } /* its own stacking context (backdrop-filter): above the panels, so the File menu opens over them */
.panel::before, .topbar::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: var(--sheen);
  z-index: -1; /* behind the panel's content (the panel is its own stacking context), above its glass */
}
.panel::after, .topbar::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  pointer-events: none;
  background: var(--edge-light);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  z-index: 4;
}
/* The canvas card and timeline dock repaint every frame during playback/dragging; a masked ::after there was
   measured at ~1.6ms/frame (software rendering). They get the same top-left rim light from inset shadows instead. */
.viewport::after, .timeline::after { display: none; }
.timeline {
  box-shadow: var(--shadow-float),
    inset 0 1px 0 rgba(255, 255, 255, 0.24),
    inset 1px 0 0 rgba(255, 255, 255, 0.1),
    inset -1px 0 0 rgba(255, 255, 255, 0.03),
    inset 0 -1px 0 rgba(0, 0, 0, 0.45);
}
/* CANVAS card — thicker, quieter glass that frames the artwork and sits lowest. It is almost entirely covered by
   the opaque stage, and a backdrop blur here cost ~2ms/frame while dragging artwork (measured), so it uses a denser
   tint instead of a blur pass; the refraction arcs are kept soft by that density. */
.viewport {
  background: var(--glass-canvas);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  box-shadow: var(--shadow-low),
    inset 0 1px 0 rgba(255, 255, 255, 0.2),
    inset 1px 0 0 rgba(255, 255, 255, 0.08),
    inset -1px 0 0 rgba(255, 255, 255, 0.025);
}
/* STATUS bar — a thin, low strip of glass: subordinate, lower blur, no rim */
.statusbar {
  position: relative;
  background: var(--glass-base-solid);
  border: 1px solid rgba(231, 236, 238, 0.06);
  box-shadow: 4px 8px 18px -12px rgba(0, 0, 0, 0.8), inset 0 1px 0 rgba(255, 255, 255, 0.06);
  -webkit-backdrop-filter: blur(var(--blur-base)) saturate(140%) brightness(0.75);
  backdrop-filter: blur(var(--blur-base)) saturate(140%) brightness(0.75);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  /* no backdrop blur: opaque, still layered (tint + light wash + rim), never see-through-and-unreadable */
  .panel, .topbar { background: linear-gradient(142deg, rgba(255, 255, 255, 0.06), rgba(0, 0, 0, 0.1)), var(--glass-solid); }
  .viewport { background: linear-gradient(142deg, rgba(255, 255, 255, 0.05), rgba(0, 0, 0, 0.1)), #161b1d; }
  .statusbar { background: #14181a; }
}

/* ======================================================================== shell */
/* one column that never outgrows the window: a long one-line status message (nowrap) once widened the whole app */
.app { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto; height: 100vh; }

/* ---- top bar ---- */
.topbar { display: flex; align-items: center; gap: var(--sp-3); margin: var(--gap) var(--gap) 0; padding: 8px 10px 8px 12px; min-height: 52px; }
.brand { display: flex; align-items: center; gap: 10px; flex: none; }
.mark { width: 30px; height: 30px; border-radius: 8px; background: linear-gradient(160deg, #e0ff9a, var(--accent) 55%, #a9d04f); color: var(--accent-ink); display: grid; place-items: center; font-weight: 900; font-size: 13px; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6), 0 2px 6px rgba(0, 0, 0, 0.5); }
.brand h1 { font-size: 13.5px; margin: 0; letter-spacing: 0.01em; font-weight: 650; }
.brand p { margin: 0; color: var(--dim); font-size: 11px; } /* under the top-left light wash */
/* version: legible but subordinate to the name */
.version { color: var(--dim); background: rgba(255, 255, 255, 0.04); border: 1px solid rgba(231, 236, 238, 0.12); padding: 1px 6px; border-radius: var(--r-sm); font: 10.5px var(--mono); }
/* hairline separators that read as etched into the glass */
.top-sep { width: 1px; height: 22px; background: linear-gradient(180deg, transparent, rgba(231, 236, 238, 0.16), transparent); box-shadow: 1px 0 0 rgba(0, 0, 0, 0.35); flex: none; }
.doc { display: flex; align-items: center; gap: 6px; min-width: 0; flex: 1; }
.doc button.icon { flex: none; } /* undo/redo keep their 30px box when the title field is squeezed */
.doc input[type=text] { max-width: 240px; background: transparent; border-color: transparent; box-shadow: none; font-weight: 550; }
.doc input[type=text]:hover { border-color: var(--glass-border-soft); background: var(--inset); }
.top-actions { display: flex; align-items: center; gap: 6px; flex: none; }
/* unsaved work: a small dot beside the project name (hidden when the work is saved or untouched) */
.dirty-mark { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 3px rgba(200, 243, 106, 0.16); }
.dirty-mark[hidden] { display: none; }
/* recovery of unsaved work from ended sessions: the last row of the top bar itself (it wraps onto its own line), so it
   always sits under every top-bar control, at any width and whatever the bar's height */
.topbar:has(#recoverBar:not([hidden])) { flex-wrap: wrap; }
.recover-bar { order: 10; flex: 1 0 100%; min-width: 0; display: grid; gap: 6px; padding: 8px 10px 8px 12px; border-radius: var(--r-box); border: 1px solid rgba(200, 243, 106, 0.35); background: rgba(200, 243, 106, 0.06); font-size: 12px; }
.recover-bar[hidden] { display: none; }
.recover-main { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.recover-main #recoverText { flex: 1 1 220px; min-width: 0; }
.recover-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.recover-list[hidden] { display: none; }
.recover-list li { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding-top: 4px; border-top: 1px solid rgba(231, 236, 238, 0.08); }
.recover-list li > span { flex: 1 1 220px; min-width: 0; color: var(--dim); }
/* File menu: Import, Save, Save as, Clear project */
.file-menu { position: relative; display: inline-flex; }
.menu { position: absolute; top: calc(100% + 6px); left: 0; z-index: 60; min-width: 230px; display: grid; gap: 2px; padding: 6px; border-radius: var(--r-box); border: 1px solid var(--glass-border); background: var(--glass-solid); box-shadow: var(--shadow-float); }
.menu[hidden] { display: none; }
.menu [role="menuitem"] { display: flex; align-items: center; justify-content: space-between; gap: 18px; width: 100%; height: 30px; padding: 0 10px; text-align: left; background: transparent; border-color: transparent; box-shadow: none; }
.menu [role="menuitem"]:hover:not(:disabled), .menu [role="menuitem"]:focus-visible { background: rgba(255, 255, 255, 0.07); }
.menu kbd { font: 10.5px var(--mono); color: var(--muted); }
.menu .menu-sep { height: 1px; margin: 4px 2px; background: rgba(231, 236, 238, 0.1); }
.menu #resetBtn { color: var(--muted); }
.menu #resetBtn:hover:not(:disabled), .menu #resetBtn:focus-visible { color: var(--err); background: var(--err-bg); }
.top-actions select { width: auto; }
/* the top bar's secondary actions are light hairline controls; Export keeps its weight as the one primary action */
.top-actions button:not(.primary), .top-actions select { background: rgba(255, 255, 255, 0.03); border-color: rgba(231, 236, 238, 0.1); box-shadow: none; }
.top-actions button:not(.primary):hover:not(:disabled) { background: rgba(255, 255, 255, 0.07); border-color: rgba(231, 236, 238, 0.2); }
.file-btn { position: relative; display: inline-flex; overflow: hidden; border-radius: var(--r-ctl); }
.file-btn input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.file-btn:focus-within { box-shadow: var(--ring); }

/* ---- workspace grid ---- */
.workspace {
  display: grid;
  /* the side panels widen with very wide windows (left from ~1915px, inspector from ~1770px: 365px at 1920, 480px from
     ~2530); below that, exactly 268 / 336 as before. The canvas keeps the rest */
  grid-template-columns: clamp(268px, 14vw, 340px) minmax(0, 1fr) clamp(336px, 19vw, 480px);
  /* the timeline scales with the window (≈ 187px at 720 tall, 236px from ~910 up) so short screens keep the canvas */
  grid-template-rows: minmax(0, 1fr) clamp(156px, 26vh, 236px);
  gap: var(--gap);
  padding: var(--gap);
  min-height: 0;
}
.panel { display: flex; flex-direction: column; min-height: 0; min-width: 0; overflow: hidden; }
.left-panel { grid-column: 1; grid-row: 1 / span 2; }
.viewport { grid-column: 2; grid-row: 1; }
.timeline { grid-column: 2; grid-row: 2; }
.inspector-panel { grid-column: 3; grid-row: 1 / span 2; }

.panel-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); padding: 10px 12px 8px; position: relative; }
.panel-head h2 { font-size: 12.5px; margin: 0; font-weight: 650; color: var(--text); letter-spacing: 0.01em; }
.panel-head .meta { color: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.panel-body { padding: var(--sp-3); overflow: auto; min-height: 0; flex: 1; position: relative; }
.divider { height: 1px; background: rgba(0, 0, 0, 0.35); box-shadow: 0 1px 0 rgba(255, 255, 255, 0.05); margin: 2px 12px 0; flex: none; }
.panel-body, .tl-body, .layer-scroll { scrollbar-width: thin; scrollbar-color: rgba(231, 236, 238, 0.16) transparent; }
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-thumb { background: rgba(231, 236, 238, 0.14); border-radius: 9px; border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-track { background: transparent; }

/* ======================================================================== left panel: tools + layers */
.tool-section { padding: 0 12px 10px; position: relative; }
.tool-groups { display: flex; gap: 5px; flex-wrap: wrap; }
.tool-group { display: flex; flex-direction: column; gap: 4px; }
.tool-group .grp-label { font-size: 10.5px; color: var(--dim); padding-left: 2px; } /* dim: sits under the brightest key-light wash */
.tool-group .grp-row { display: flex; gap: 2px; padding: 2px; border-radius: var(--r-ctl); background: rgba(0, 0, 0, 0.2); border: 1px solid rgba(231, 236, 238, 0.06); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.35); } /* a quiet inset well: the selected tool is the only raised thing in it */
.tool {
  position: relative;
  width: 37px; height: 40px; padding: 0;
  display: grid; place-items: center; align-content: center; gap: 1px;
  border: 1px solid transparent; border-radius: calc(var(--r-ctl) - 3px); /* concentric in the 2px-padded tray */
  background: transparent; box-shadow: none; color: var(--dim);
  transition: background var(--t) var(--ease), color var(--t) var(--ease), box-shadow var(--t) var(--ease), border-color var(--t) var(--ease);
}
.tool .ic { font-size: 15px; line-height: 1; display: grid; place-items: center; }
.tool .lb { font-size: 10.5px; line-height: 1; color: var(--dim); } /* on the lighter secondary-glass tray */
.tool:hover:not(:disabled) { background: rgba(255, 255, 255, 0.07); border-color: transparent; color: var(--text); }
/* Selected tool = material D: brighter raised glass + fine luminous lime edge + indicator bar + label weight
   (identifiable without colour: surface, bar and weight all change) */
.tool.active { background: var(--glass-active); border-color: rgba(231, 236, 238, 0.22); color: var(--accent); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.24), var(--glass-active-edge), 1px 3px 5px rgba(0, 0, 0, 0.45); }
.tool.active .lb { color: var(--text); font-weight: 650; }
.tool.active::after { content: ""; position: absolute; left: 9px; right: 9px; bottom: 2px; height: 2px; border-radius: 2px; background: var(--accent); }
.scope-row { display: flex; flex-direction: column; gap: 4px; margin-top: 10px; }
.scope-row .lbl { font-size: 10.5px; color: var(--muted); padding-left: 2px; }
.scope-row .seg { width: 100%; background: rgba(0, 0, 0, 0.2); border-color: rgba(231, 236, 238, 0.06); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.35); }
.scope-row .seg button { flex: 1; padding: 0 4px; }

.layer-tools { display: flex; gap: 4px; padding: 8px 12px; flex-wrap: wrap; position: relative; }
.layer-scroll { flex: 1; overflow: auto; min-height: 0; position: relative; }
.layer-tree { list-style: none; margin: 0; padding: 2px 6px 6px; font-size: 12.5px; user-select: none; }
.layer-row {
  display: flex; align-items: center; gap: 5px; height: 26px;
  padding: 0 8px 0 calc(6px + var(--depth, 0) * 14px);
  margin: 1px 0; border-radius: var(--r-sm); cursor: pointer; color: var(--dim);
  border: 1px solid transparent;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.layer-row:hover { background: rgba(255, 255, 255, 0.045); color: var(--text); }
.layer-row.selected { background: linear-gradient(90deg, rgba(200, 243, 106, 0.13), rgba(200, 243, 106, 0.04)); border-color: rgba(200, 243, 106, 0.2); color: var(--text); box-shadow: inset 2px 0 0 var(--accent); }
.layer-row.selected .name { font-weight: 600; }
.layer-row .twisty { width: 14px; text-align: center; color: var(--muted); flex: none; font-size: 10px; }
.layer-row .kind { width: 16px; text-align: center; color: var(--accent-2); flex: none; font-size: 11px; }
.layer-row .name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.layer-row .badge { font: 10.5px var(--mono); background: none; color: var(--muted); padding: 0 2px; line-height: 16px; font-variant-numeric: tabular-nums; } /* a quiet count, no pill; lime only when selected */
.layer-row.selected .badge { color: var(--accent); }
.layer-row .warn { color: var(--warn); font-size: 11px; }
.layer-row .note-info { color: var(--muted); font-size: 11px; } /* descriptive notes only (R2): information, not a warning */
/* Bodies → Marks: one role chip per shape while the preset is previewed (click: next role; never selects) */
.layer-row .role-chip { position: relative; font: 10.5px var(--mono); min-width: 30px; height: 17px; padding: 0 5px; border-radius: 9px; border: 1px solid var(--glass-border); background: var(--inset); color: var(--dim); cursor: pointer; line-height: 15px; }
.layer-row .role-chip.role-mark { color: var(--accent-ink); background: var(--accent); border-color: var(--accent); }
.layer-row .role-chip.role-excluded { color: var(--muted); text-decoration: line-through; }
.layer-row .role-chip.uncertain { border-color: var(--warn); border-style: dashed; }
.layer-row .role-chip.role-mark.uncertain { background: var(--warn); border-color: var(--warn); }
.layer-row .role-chip.set { box-shadow: 0 0 0 1px var(--accent-line); }
.layer-row .role-chip:focus-visible { outline: none; box-shadow: var(--ring); }
/* the 17px chip is clicked repeatedly: extend its hit area to the 26px row height (inside its own row, no overlap) */
.layer-row .role-chip::before { content: ""; position: absolute; inset: -5px -3px; }
.section-label { font-size: 11px; color: var(--muted); font-weight: 600; margin: 14px 0 6px; }
/* empty states: before import the layer tools and the group form wait (they could do nothing yet) */
.no-art .layer-tools, .no-art .groups-area .section-label, .no-art .groups-area .row, .no-art .groups-area .hint { display: none; }
.layers-empty { list-style: none; margin: 4px 6px; padding: 18px 14px; border: 1px dashed rgba(231, 236, 238, 0.12); border-radius: var(--r-ctl); color: var(--muted); font-size: 12px; text-align: center; text-wrap: balance; }
/* first-use guide (Motion panel before import) */
.guide { border: 1px solid rgba(231, 236, 238, 0.08); border-radius: var(--r-box); padding: 14px 14px 6px; background: var(--glass-base); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09); }
.guide-head { display: flex; flex-direction: column; gap: 2px; margin-bottom: 12px; }
.guide-head strong { font-size: 13px; font-weight: 650; text-wrap: balance; }
.guide-head span { font-size: 11px; color: var(--muted); }
.guide-steps { list-style: none; margin: 0; padding: 0; }
.guide-steps li { display: flex; gap: 10px; padding: 0 0 14px; position: relative; }
.guide-steps li:not(:last-child)::before { content: ""; position: absolute; left: 11px; top: 26px; bottom: 2px; width: 1px; background: rgba(231, 236, 238, 0.1); }
.guide-steps .n { flex: none; width: 23px; height: 23px; border-radius: 50%; display: grid; place-items: center; font: 11px var(--mono); color: var(--muted); border: 1px solid rgba(231, 236, 238, 0.16); background: var(--inset); font-variant-numeric: tabular-nums; }
.guide-steps li.on .n { color: var(--accent-ink); background: var(--accent); border-color: var(--accent); }
.guide-steps li > div { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.guide-steps strong { font-size: 12.5px; font-weight: 600; color: var(--text); }
.guide-steps li:not(.on) strong { color: var(--dim); }
.guide-steps span { font-size: 11.5px; color: var(--muted); line-height: 1.45; text-wrap: pretty; }
.guide-steps .file-btn { margin-top: 8px; align-self: flex-start; }
.guide-actions { gap: 8px; }
.group-list { list-style: none; padding: 0; margin: 6px 0 0; }
.group-list li { display: flex; align-items: center; gap: 6px; padding: 2px 0; font-size: 12px; }
.group-list li button.link { background: none; border: 0; box-shadow: none; height: 24px; padding: 0 4px; text-align: left; flex: 1; color: var(--dim); }
.group-list li button.link:hover { color: var(--accent); background: none; }
.row { display: flex; gap: 6px; align-items: center; }
.hint { font-size: 11px; color: var(--muted); margin-top: 5px; line-height: 1.4; text-wrap: pretty; }

/* ======================================================================== canvas */
.viewport { display: flex; flex-direction: column; }
.canvas-bar { display: flex; align-items: center; gap: 8px; padding: 8px 10px; position: relative; flex-wrap: wrap; }
.canvas-bar .title { font-size: 12.5px; font-weight: 650; }
.canvas-bar .art-info { font-size: 11px; color: var(--dim); /* dim, not muted: the bright top of the glass card needs it */ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1; }
.canvas-bar .toggles { display: flex; gap: 10px; font-size: 11.5px; color: var(--dim); }
.canvas-bar .toggles label { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; min-height: var(--ctl-h); } /* whole row height clickable */
/* The canvas well: an opaque, recessed surface framed by the floating glass card. Quiet, unlit, unfiltered —
   the ambient backdrop never shows through here, so artwork colours are judged against a neutral field. */
.stage {
  position: relative; flex: 1; margin: 0 9px 9px; min-height: 0;
  border-radius: calc(var(--r-panel) - 9px); overflow: hidden; /* concentric with the card at its 9px margin */
  border: 1px solid rgba(0, 0, 0, 0.75);
  background: radial-gradient(120% 95% at 50% 45%, #14181a 0%, #0c0f10 68%, #090b0c 100%);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.035),
    inset 0 22px 44px -24px rgba(0, 0, 0, 0.95),
    inset 0 -10px 24px -18px rgba(0, 0, 0, 0.7),
    0 1px 0 rgba(255, 255, 255, 0.07);
}
/* Optional, view-only grid (toggle). Painted under the artwork, never over it. */
.stage.grid-on { background-image: linear-gradient(rgba(231, 236, 238, 0.035) 1px, transparent 1px), linear-gradient(90deg, rgba(231, 236, 238, 0.035) 1px, transparent 1px), radial-gradient(120% 90% at 50% 45%, #15191b 0%, #0d1011 70%, #0a0c0d 100%); background-size: 32px 32px, 32px 32px, auto; }
/* Light "paper" well (chosen automatically for dark ink, see ui.js autoCanvas; the Light toggle overrides it): a quiet
   warm-neutral sheet with the same soft falloff as the dark well, so dark lettering reads at full contrast */
.stage.light-bg { background: radial-gradient(120% 95% at 50% 45%, #f6f6f2 0%, #eeefea 68%, #e5e7e1 100%); border-color: rgba(0, 0, 0, 0.55); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.5), inset 0 18px 40px -26px rgba(0, 0, 0, 0.35), 0 1px 0 rgba(255, 255, 255, 0.07); }
.stage.light-bg.grid-on { background-image: linear-gradient(rgba(0, 0, 0, 0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(0, 0, 0, 0.05) 1px, transparent 1px); background-size: 32px 32px; background-color: #f2f3f0; }
/* on the light well the lime overlay would vanish: same marks in a deep olive */
.stage.light-bg .overlay .sel-box { border-color: rgba(70, 98, 18, 0.85); box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.6); }
.stage.light-bg .overlay .hover-box { border-color: rgba(38, 98, 170, 0.85); }
.stage.light-bg .handles .frame, .stage.light-bg .handles .rot-stem { stroke: #4a6a12; }
.stage.light-bg .handles .corner { fill: #f6f6f2; stroke: #4a6a12; }
.stage.light-bg .handles .rot-knob { fill: #4a6a12; stroke: #f6f6f2; }
.stage.light-bg .overlay .role-box.role-body { border-color: rgba(20, 24, 26, 0.5); }
/* The host's box is driven by the viewport zoom/pan (layout, not CSS transforms): screen matrices stay exact.
   The 28px inset must match INSET in ui.js applyView(). */
.svg-host { position: absolute; left: 28px; top: 28px; width: calc(100% - 56px); height: calc(100% - 56px); }
.stage.tool-move, .stage.tool-move * { cursor: move; }
.stage.tool-scale { cursor: nwse-resize; }
.stage.tool-rotate { cursor: grab; }
.stage.tool-pivot { cursor: crosshair; }
.stage.panning, .stage.panning * { cursor: grabbing !important; }
.overlay { position: absolute; inset: 0; pointer-events: none; }
.overlay .sel-box { position: absolute; border: 1px dashed var(--accent-line); border-radius: 2px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35); }
.overlay .hover-box { position: absolute; border: 1px solid rgba(139, 188, 240, 0.8); border-radius: 2px; }
/* Bodies → Marks role overlay: drawn over the canvas, never inside the artwork (so never exported) */
.overlay .role-box { position: absolute; border-radius: 3px; pointer-events: none; }
.overlay .role-box.role-body { border: 1px solid rgba(231, 236, 238, 0.45); }
.overlay .role-box.role-mark { border: 2px solid var(--accent); background: rgba(200, 243, 106, 0.12); }
.overlay .role-box.role-excluded { border: 1px dotted var(--muted); background: rgba(10, 12, 13, 0.35); }
.overlay .role-box.uncertain { border-style: dashed; border-color: var(--warn); }
.overlay .role-box.group-box { border: 2px solid var(--morph); background: rgba(139, 188, 240, 0.08); }
.handles { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.handles .frame { fill: none; stroke: var(--accent); stroke-width: 1; stroke-dasharray: 4 3; }
.handles .frame.secondary { stroke-opacity: 0.5; }
.handles .corner { fill: #0d1011; stroke: var(--accent); stroke-width: 1.5; pointer-events: all; cursor: nwse-resize; }
.handles .rot-knob { fill: var(--accent); stroke: #0d1011; stroke-width: 1.5; pointer-events: all; cursor: grab; }
.handles .rot-stem { stroke: var(--accent); stroke-width: 1; }
.handles .pivot circle { fill: none; stroke: var(--morph); stroke-width: 1.5; }
.handles .pivot line { stroke: var(--morph); stroke-width: 1.5; }
.handles .pivot .hit { fill: transparent; stroke: none; pointer-events: all; cursor: move; }

/* empty state */
/* The card needs ~316px but the stage only gets what is left after the top bar, timeline row and canvas header —
   in short browser windows that is 150–230px and the stage's overflow:hidden used to slice the Import button off.
   .empty is a size container so the card adapts to the CANVAS height (not the window): decorative parts compact
   first, the heading + Import button always stay. `safe center` + overflow:auto are the last resort: content can
   scroll, never be pushed out of reach. */
.empty { position: absolute; inset: 0; display: grid; place-items: center; place-items: safe center; padding: 12px; pointer-events: none; overflow: auto; container-type: size; }
/* (padding lives here, not in the queries below: a container query cannot restyle its own container) */
.empty-card { pointer-events: auto; text-align: center; max-width: 370px; padding: 28px 30px 22px; border-radius: var(--r-panel); border: 1px dashed rgba(231, 236, 238, 0.18); background: linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012)); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05); }
.empty-card .em { width: 46px; height: 46px; margin: 0 auto 14px; border-radius: 13px; display: grid; place-items: center; background: var(--glass-raised); border: 1px solid rgba(231, 236, 238, 0.16); box-shadow: var(--shadow-raised), 0 0 18px -8px rgba(200, 243, 106, 0.35); color: var(--accent); font-size: 20px; }
.empty-card strong { display: block; font-size: 15px; margin-bottom: 6px; text-wrap: balance; }
.empty-card p { margin: 0 0 14px; color: var(--muted); font-size: 12px; text-wrap: pretty; }
.empty-card .file-btn button { height: 34px; padding: 0 16px; }
.empty-card .hint { margin-top: 12px; }
@container (max-height: 330px) {
  .empty-card { padding: 16px 22px 14px; }
  .empty-card .em { width: 34px; height: 34px; margin-bottom: 8px; border-radius: 10px; font-size: 15px; }
  .empty-card p { margin-bottom: 10px; }
  .empty-card .hint { margin-top: 8px; }
}
@container (max-height: 250px) {
  .empty-card .em, .empty-card .hint { display: none; }
}
@container (max-height: 158px) {
  .empty-card { padding: 12px 18px; }
  .empty-card p { display: none; }
  .empty-card strong { margin-bottom: 10px; }
}
@container (max-height: 96px) {
  .empty-card { display: flex; align-items: center; gap: 12px; padding: 8px 14px; }
  .empty-card strong { margin: 0; }
}
.stage.drop-hover { box-shadow: inset 0 0 0 2px var(--accent-line); }

/* ======================================================================== timeline dock */
.timeline { display: flex; flex-direction: column; }
.transport { display: flex; align-items: center; gap: 6px; padding: 8px 10px; flex-wrap: wrap; position: relative; }
@media (min-width: 1141px) { .transport { flex-wrap: nowrap; } .transport .timecode { flex: none; } } /* one line in the desktop layout */
.transport select { width: auto; }
.transport input[type=number] { width: 58px; }
.transport .check { margin: 0 4px; }
.transport .lbl { font-size: 11px; color: var(--muted); display: inline-flex; align-items: center; gap: 6px; }
.timecode { font: 12px var(--mono); color: var(--text); margin-left: auto; font-variant-numeric: tabular-nums; padding: 0 10px; height: 26px; display: inline-grid; place-items: center; border-radius: var(--r-sm); background: var(--inset-strong); border: 1px solid rgba(231, 236, 238, 0.08); box-shadow: var(--inset-shadow); letter-spacing: 0.02em; }
/* "▶ Play" ↔ "❚❚ Pause": one width for both labels, so the transport never shifts when it toggles */
#playBtn { min-width: 6em; text-align: center; }
#playBtn.playing { background: linear-gradient(180deg, #d4fb7f, var(--accent)); color: var(--accent-ink); border-color: rgba(220, 255, 150, 0.9); font-weight: 650; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55), 0 0 14px -5px rgba(200, 243, 106, 0.5); }
/* timeline well: recessed track surface inside the floating dock (material E) */
.tl-body { display: grid; grid-template-columns: 172px minmax(0, 1fr); flex: 1; min-height: 0; overflow: auto; margin: 0 9px 9px; border-radius: calc(var(--r-panel) - 9px); background: var(--inset-strong); border: 1px solid rgba(0, 0, 0, 0.7); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.035), inset 0 14px 26px -18px rgba(0, 0, 0, 0.9), 0 1px 0 rgba(255, 255, 255, 0.06); }
.tl-names { border-right: 1px solid rgba(231, 236, 238, 0.07); background: rgba(255, 255, 255, 0.012); }
.tl-ruler-name { height: 24px; border-bottom: 1px solid rgba(231, 236, 238, 0.07); display: flex; align-items: center; padding: 0 10px; font-size: 11px; color: var(--muted); position: sticky; top: 0; background: #111517; z-index: 2; }
.tl-name { height: 30px; display: flex; align-items: center; gap: 7px; padding: 0 10px; font-size: 12px; border-bottom: 1px solid rgba(231, 236, 238, 0.045); cursor: pointer; color: var(--dim); transition: background var(--t-fast) var(--ease); }
.tl-name:hover, .tl-lane:hover { background: rgba(255, 255, 255, 0.03); }
.tl-name.selected { background: linear-gradient(90deg, rgba(200, 243, 106, 0.12), rgba(200, 243, 106, 0.035)); color: var(--text); box-shadow: inset 2px 0 0 var(--accent); }
.tl-lane.selected { background: rgba(200, 243, 106, 0.07); box-shadow: inset 0 1px 0 rgba(200, 243, 106, 0.18), inset 0 -1px 0 rgba(200, 243, 106, 0.18); }
.tl-name.selected { box-shadow: inset 3px 0 0 var(--accent), inset 0 1px 0 rgba(200, 243, 106, 0.18), inset 0 -1px 0 rgba(200, 243, 106, 0.18); }
.tl-name .nm { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tl-name.disabled .nm { color: var(--faint); text-decoration: line-through; }
.tl-name .cnt { font: 10.5px var(--mono); color: var(--muted); }
.tl-tracks { position: relative; min-width: 0; }
.tl-ruler { height: 24px; border-bottom: 1px solid rgba(231, 236, 238, 0.07); position: sticky; top: 0; background: #111517; z-index: 2; cursor: ew-resize; user-select: none; -webkit-user-select: none; }
.tl-ruler .tick { position: absolute; top: 0; bottom: 0; border-left: 1px solid rgba(231, 236, 238, 0.1); font: 10.5px var(--mono); color: var(--muted); padding: 6px 0 0 4px; }
.tl-lane { height: 30px; position: relative; border-bottom: 1px solid rgba(231, 236, 238, 0.045); cursor: pointer; }
/* motion bars: small raised glass slabs on the recessed track */
.tl-bar { position: absolute; top: 8px; height: 14px; border-radius: 4px; background: linear-gradient(180deg, #46523f, #313a2d); border: 1px solid rgba(182, 220, 140, 0.32); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 3px rgba(0, 0, 0, 0.6); }
.tl-lane.selected .tl-bar { top: 4px; height: 22px; border-color: rgba(200, 243, 106, 0.85); background: linear-gradient(180deg, #4b5c33, #333f25); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 1px 3px rgba(0, 0, 0, 0.6), 0 0 10px -4px rgba(200, 243, 106, 0.45); }
/* the selected motion's own easing curve, drawn inside its bar (timeline-ease.js): one curve per play of the first
   target, under the keyframes; it never takes the pointer (drag, grip and selection work as before) */
.tl-ease { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.tl-ease .area { fill: rgba(200, 243, 106, 0.12); }
.tl-ease .curve { fill: none; stroke: var(--accent); stroke-width: 1.4; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
/* timing by direct manipulation: drag a bar to move its start, its right end to change its duration */
.tl-bar { cursor: grab; touch-action: none; }
.tl-bar.dragging { cursor: grabbing; }
.tl-bar .tl-grip { position: absolute; top: -2px; bottom: -2px; right: -4px; width: 9px; cursor: ew-resize; z-index: 2; }
.tl-bar .tl-grip::after { content: ''; position: absolute; top: 3px; bottom: 3px; left: 3px; width: 2px; border-radius: 1px; background: rgba(231, 236, 238, 0.35); opacity: 0; transition: opacity var(--t-fast) var(--ease); }
.tl-bar:hover .tl-grip::after, .tl-lane.selected .tl-grip::after { opacity: 1; }
.tl-bar.morph { background: linear-gradient(180deg, #24384f, #1c2c3f); border-color: rgba(139, 188, 240, 0.6); }
.tl-bar.crossfade { background: linear-gradient(180deg, #3a2a50, #2d2140); border-color: rgba(201, 165, 241, 0.6); }
/* stagger: a soft band from the first to the last start, capped at both ends; keyframes stay readable on top */
.tl-bar .stag-band { position: absolute; top: 2px; bottom: 2px; border-radius: 2px; background: linear-gradient(90deg, rgba(231, 236, 238, 0.22), rgba(231, 236, 238, 0.06)); pointer-events: none; }
.tl-bar .stag { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--dim); border-radius: 1px; opacity: 0.7; }
.tl-bar .kf { z-index: 1; }
/* behaviour family tint (all within the green family; the selected track keeps the bright lime edge) */
.tl-bar.cat-loop { background: linear-gradient(180deg, #33554e, #24403a); border-color: rgba(120, 220, 190, 0.38); }
.tl-bar.cat-expressive { background: linear-gradient(180deg, #555b31, #3e4324); border-color: rgba(214, 232, 120, 0.4); }
.tl-bar.cat-from-references { background: linear-gradient(180deg, #554c33, #3e3726); border-color: rgba(227, 189, 104, 0.38); }
.tl-bar.cat-full-artwork-motion { background: linear-gradient(180deg, #3b5048, #2b3c36); border-color: rgba(170, 210, 190, 0.36); }
.tl-bar.cat-effect { background: linear-gradient(180deg, #2f4b52, #23383e); border-color: rgba(120, 200, 220, 0.38); }
.tl-bar .rep { position: absolute; top: 0; bottom: 0; border-left: 1px dashed rgba(255, 255, 255, 0.45); }
/* Real compiled keyframe times of the motion's first target (read-only markers, not draggable). */
.tl-bar .kf { position: absolute; top: 50%; width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px; transform: rotate(45deg); background: #0d1011; border: 1px solid rgba(231, 236, 238, 0.6); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.7); pointer-events: none; }
.tl-lane.selected .tl-bar .kf { border-color: #e2ff9e; background: var(--accent); box-shadow: 0 0 6px -1px rgba(200, 243, 106, 0.6); }
.tl-hold { position: absolute; top: 0; bottom: 0; background: repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.03) 0 6px, transparent 6px 12px); pointer-events: none; }
/* glow via box-shadow (not a filter): the playhead moves every frame during playback */
.playhead { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--accent); pointer-events: none; z-index: 3; box-shadow: 0 0 6px rgba(200, 243, 106, 0.4); }
.playhead::before { content: ""; position: absolute; top: 0; left: -6px; border: 5px solid transparent; border-top: 7px solid var(--accent); }
/* empty timeline: no playhead or ruler in a void — one centred hint across the track area */
.tl-tracks .tl-empty { position: absolute; left: 0; right: 0; top: 24px; bottom: 0; display: grid; place-items: center; padding: 14px 24px; color: var(--muted); font-size: 12px; text-align: center; text-wrap: balance; }
.tl-tracks .tl-empty strong { color: var(--dim); font-weight: 600; }
.tl-body.is-empty .playhead, .tl-body.is-empty .tl-ruler { visibility: hidden; }
.tl-body.is-empty .tl-tracks { min-height: 100%; }

/* ======================================================================== inspector */
/* tab tray = SECONDARY glass; the active tab is the brightest, most elevated pane in it */
.tabs { display: flex; gap: 2px; margin: 10px 10px 0; padding: 3px; border-radius: calc(var(--r-sm) + 4px); /* tab 5px + 1px border + 3px padding */ background: var(--glass-tray); border: 1px solid rgba(231, 236, 238, 0.11); box-shadow: var(--edge-secondary), 1px 2px 4px rgba(0, 0, 0, 0.3); position: relative; }
.tabs button { flex: 1; height: 28px; border: 1px solid transparent; border-radius: var(--r-sm); background: transparent; box-shadow: none; padding: 0 4px; font-size: 12px; color: var(--dim); transition: background var(--t) var(--ease), color var(--t) var(--ease), box-shadow var(--t) var(--ease); }
.tabs button:hover:not(.active) { background: rgba(255, 255, 255, 0.05); color: var(--text); border-color: transparent; }
/* active tab = material D: raised glass + lime indicator + fine luminous edge */
.tabs button.active { background: var(--glass-active); color: var(--text); border-color: rgba(231, 236, 238, 0.22); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.24), inset 0 -2px 0 var(--accent), 0 0 12px -6px rgba(200, 243, 106, 0.4), 1px 3px 5px rgba(0, 0, 0, 0.45); font-weight: 600; }
.field { margin-bottom: 10px; }
.field:last-child { margin-bottom: 0; }
.field > label, .field > .lbl { display: flex; justify-content: space-between; align-items: center; font-size: 11.5px; color: var(--dim); margin-bottom: 5px; gap: 8px; }
.field output { color: var(--accent); font: 11px var(--mono); font-variant-numeric: tabular-nums; }
.field .hint { font-size: 11px; color: var(--muted); margin-top: 4px; }
.range-row { display: grid; grid-template-columns: minmax(0, 1fr) 70px; gap: 8px; align-items: center; }
.range-row input[type=number] { height: 26px; font-size: 12px; text-align: right; }
.check { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--dim); margin-bottom: 10px; cursor: pointer; }
/* manual start order: an inset list of target layers with ↑/↓ per row */
.target-list { list-style: none; margin: 0; padding: 3px; max-height: 216px; overflow: auto; border-radius: var(--r-ctl); background: var(--inset); border: 1px solid rgba(231, 236, 238, 0.07); box-shadow: var(--inset-shadow); }
.target-list li { display: flex; align-items: center; gap: 6px; height: 28px; padding: 0 4px 0 6px; border-radius: var(--r-sm); font-size: 12px; color: var(--dim); }
.target-list li:hover { background: rgba(255, 255, 255, 0.04); color: var(--text); }
.target-list .idx { width: 18px; text-align: right; font: 10.5px var(--mono); color: var(--muted); font-variant-numeric: tabular-nums; flex: none; }
.target-list .nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.target-list button.small.icon { width: 24px; height: 22px; font-size: 12px; }
/* Motion Director instances: same inset list; the Director being edited is lit with the accent edge */
.director-list li { padding: 0; }
.director-list li.active { background: rgba(200, 243, 106, 0.07); color: var(--text); box-shadow: inset 2px 0 0 var(--accent); }
.director-list .dir-pick { display: flex; align-items: center; gap: 6px; width: 100%; height: 28px; padding: 0 6px; background: none; border: 0; box-shadow: none; color: inherit; font-size: 12px; text-align: left; }
.director-list .dir-pick:hover { background: none; color: var(--text); }
.director-list .tag { flex: none; font: 10.5px var(--mono); color: var(--dim); padding: 1px 6px; border-radius: 8px; border: 1px solid rgba(231, 236, 238, 0.14); background: rgba(255, 255, 255, 0.04); }
.director-list .tag.warn { color: var(--warn); border-color: rgba(227, 189, 104, 0.35); }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.grid3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
/* inspector sections = material A (base glass): a quieter layer inside the floating panel, no blur of its own */
/* sections of one continuous panel, not cards: a hairline between them, no frame, no shadow */
.group-box { border: 0; border-top: 1px solid rgba(231, 236, 238, 0.08); border-radius: 0; padding: 14px 2px; margin: 0; background: none; box-shadow: none; }
.group-box:first-child { border-top: 0; }
.group-box > h3 { margin: 0 0 12px; font-size: 12.5px; font-weight: 650; color: var(--text); display: flex; align-items: center; gap: 8px; }
.group-box > h3::before { content: ""; width: 3px; height: 11px; border-radius: 2px; background: var(--accent-2); }
/* compact motion header: the name, then its actions (no section title — the name is the title) */
.motion-head { padding: 4px 2px 14px; }
.motion-head > input[type=text] { font-weight: 600; font-size: 13px; }
.motion-head .motion-actions { flex-wrap: wrap; gap: 4px; margin-top: 8px; }
.motion-head .motion-actions .danger { margin-left: auto; }
.motion-head .motion-actions .small { padding: 0 7px; } /* the four actions fit one row in the narrow (1280 px) panel */
/* Targets: a disclosure styled as a section; its summary says who moves and in which order */
.targets-box > summary { list-style: none; cursor: pointer; display: flex; align-items: baseline; gap: 8px; margin: 0; }
.targets-box > summary::-webkit-details-marker { display: none; }
.targets-box > summary .h3 { font-size: 12px; font-weight: 650; color: var(--text); display: flex; align-items: center; gap: 8px; flex: none; }
.targets-box > summary .h3::before { content: ""; width: 3px; height: 11px; border-radius: 2px; background: var(--accent-2); }
.targets-box > summary .t-sum { flex: 1; min-width: 0; font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.targets-box > summary::after { content: "▸"; font-size: 10px; color: var(--muted); transition: transform var(--t-fast) var(--ease); }
.targets-box[open] > summary::after { transform: rotate(90deg); }
.targets-box[open] > summary { margin-bottom: 10px; }
.targets-box > summary:hover .t-sum, .targets-box > summary:hover::after { color: var(--text); }
.targets-box .target-list { max-height: min(360px, 45vh); }
.target-list li[data-target] { cursor: default; }
/* one-line hints with the method one click away */
.hint details.more { display: inline; }
.hint details.more > summary { display: inline; cursor: pointer; color: var(--dim); margin-left: 4px; text-decoration: underline dotted; text-underline-offset: 2px; list-style: none; }
.hint details.more > summary::-webkit-details-marker { display: none; }
.hint details.more[open] { display: block; margin-top: 4px; }
.ease-canvas { width: 100%; height: 90px; display: block; background: var(--inset-strong); border: 1px solid var(--glass-border-soft); border-radius: var(--r-ctl); margin-top: 4px; }
.notice { padding: 9px 11px; border: 1px solid rgba(227, 189, 104, 0.32); background: var(--warn-bg); color: #ecd9a8; border-radius: var(--r-ctl); font-size: 12px; line-height: 1.45; margin-bottom: 10px; text-wrap: pretty; }
.notice.error { border-color: rgba(240, 137, 124, 0.4); background: var(--err-bg); color: #ffd2cb; }
.notice.ok { border-color: rgba(182, 220, 140, 0.32); background: var(--ok-bg); color: #d6eec0; }
.notice.info { border-color: rgba(231, 236, 238, 0.075); background: var(--glass-base); color: var(--dim); }
.notice ul { margin: 6px 0 0; padding-left: 18px; }
.notice strong { color: var(--text); }
.preset-group { margin-bottom: 14px; }
/* equal-height cards in two equal columns (minmax(0, …): a long label or tag never widens its column) */
.preset-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 1fr; gap: 6px; }
.preset-grid .preset { min-width: 0; }
.preset .recipe-tag { white-space: nowrap; flex: none; }
.preset strong { max-width: 100%; overflow-wrap: anywhere; }
/* finder: search + group chips (view only) */
.preset-finder { display: flex; flex-direction: column; gap: 6px; margin: 0 0 8px; }
.preset-finder input[type=search] { height: 30px; }
/* search + the closed Options disclosure on one row; opened, Options takes the full width below the search */
.finder-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: flex-start; }
.finder-row input[type=search] { flex: 1 1 0; min-width: 0; }
.finder-row .presets-options { margin: 0; flex: none; height: 30px; padding: 0 10px; display: flex; align-items: center; }
.finder-row .presets-options[open] { flex: 1 1 100%; height: auto; display: block; padding: 6px 10px 10px; }
/* every group visible: the chips wrap (two rows at the desktop inspector width) instead of scrolling out of sight */
.preset-chips { display: flex; flex-wrap: wrap; gap: 4px; padding: 1px; }
.preset-chips .chip { flex: none; }
.preset-chips .chip { height: 24px; padding: 0 9px; font-size: 11px; border-radius: 12px; color: var(--dim); background: rgba(255, 255, 255, 0.03); box-shadow: none; border-color: rgba(231, 236, 238, 0.1); }
.preset-chips .chip:hover:not(:disabled) { color: var(--text); background: rgba(255, 255, 255, 0.07); }
.preset-chips .chip[aria-pressed="true"] { color: var(--accent-ink); background: var(--accent); border-color: var(--accent); font-weight: 600; }
.presets-none { padding: 18px 12px; text-align: center; color: var(--muted); font-size: 12px; border: 1px dashed rgba(231, 236, 238, 0.12); border-radius: var(--r-box); }
.presets-none .small { margin-left: 6px; }
/* preset cards sit as base glass (A) and lift to raised glass (B) on hover */
.preset { transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease), transform var(--t-fast) var(--ease); }
.preset { height: auto; text-align: left; padding: 9px 10px; border-radius: var(--r-box); min-height: 66px; display: flex; flex-direction: column; gap: 2px; white-space: normal; align-items: flex-start; background: var(--glass-base); border-color: rgba(231, 236, 238, 0.09); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09); }
.preset:hover:not(:disabled) { background: var(--glass-raised-hover); border-color: rgba(200, 243, 106, 0.5); box-shadow: var(--shadow-raised), 0 10px 18px -12px rgba(0, 0, 0, 0.85), 0 0 0 1px rgba(200, 243, 106, 0.12); transform: translateY(-1px); }
.preset .g { color: var(--accent); font-size: 15px; line-height: 1.2; display: flex; align-items: center; gap: 6px; width: 100%; min-height: 17px; }
/* family marker: the same family tints as the timeline bars */
.preset .fam { width: 8px; height: 8px; border-radius: 50%; flex: none; background: #b6dc8c; box-shadow: 0 0 0 2px rgba(182, 220, 140, 0.15); }
/* "Entrance" is most cards' family: its label is redundant there (the dot stays; the word stays for screen readers) */
.preset.fam-entrance .fam-name { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* with no label left, the dot moves onto the name line; the header row stays only for a "N motions" or Previewing chip */
.preset.fam-entrance { position: relative; }
.preset.fam-entrance .g .fam { display: none; }
.preset.fam-entrance:not(.previewing) .g:not(:has(.recipe-tag)) { min-height: 0; height: 0; }
.preset.fam-entrance strong::before { content: ''; display: inline-block; width: 7px; height: 7px; margin: 0 7px 1px 0; vertical-align: middle; border-radius: 50%; background: #b6dc8c; box-shadow: 0 0 0 2px rgba(182, 220, 140, 0.15); }
.preset .fam-name { font: 9.5px var(--mono); color: var(--muted); letter-spacing: 0.02em; text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.preset.fam-loop .fam { background: #78dcbe; box-shadow: 0 0 0 2px rgba(120, 220, 190, 0.15); }
.preset.fam-expressive .fam { background: #d6e878; box-shadow: 0 0 0 2px rgba(214, 232, 120, 0.15); }
.preset.fam-from-references .fam { background: #e3bd68; box-shadow: 0 0 0 2px rgba(227, 189, 104, 0.15); }
.preset.fam-full-artwork-motion .fam { background: #aad2be; box-shadow: 0 0 0 2px rgba(170, 210, 190, 0.15); }
.preset.fam-effect .fam { background: #78c8dc; box-shadow: 0 0 0 2px rgba(120, 200, 220, 0.15); }
.preset small { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } /* full text: the hover preview (and the accessible name) */
.preset .pv-chip { display: none; margin-left: auto; font: 10.5px var(--mono); color: var(--accent-ink); background: var(--accent); padding: 1px 6px; border-radius: 8px; font-weight: 600; }
.preset.previewing .pv-chip { display: inline-block; }
.preset.previewing .recipe-tag { display: none; } /* one chip at a time in the corner */
.preset .recipe-tag { margin-left: auto; flex: none; font: 10.5px var(--mono); color: var(--dim); padding: 1px 4px; border-radius: 8px; border: 1px solid rgba(231, 236, 238, 0.14); background: rgba(255, 255, 255, 0.04); }
/* the previewed (not yet applied) candidate: lit like an active control, never filled like an applied state */
.preset.previewing { background: var(--glass-active); border-color: rgba(200, 243, 106, 0.55); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), var(--glass-active-edge); }
/* Preview / Apply / Discard bar: sticks to the top of the Presets panel while the cards scroll */
/* compact and opaque: cards never show through it, and the previewed card is scrolled out from under it (ui.js) */
.preview-bar { position: sticky; top: calc(-1 * var(--sp-3)); z-index: 2; margin: calc(-1 * var(--sp-3)) calc(-1 * var(--sp-3)) 10px; padding: 9px var(--sp-3); display: flex; flex-direction: column; gap: 6px; background: #111517; border-bottom: 1px solid rgba(231, 236, 238, 0.1); box-shadow: 0 8px 16px -12px rgba(0, 0, 0, 0.8); }
.preview-bar.idle { display: none; } /* nothing previewed: no bar — the search field says "click one to preview", and the bar says "not added until Apply" the moment a preset is previewed */
.preview-bar.idle .pv-actions { display: none; } /* (kept in the DOM, disabled) — idle shows one hint line */
body.tm-busy, body.tm-busy * { cursor: progress !important; } /* a geometry-heavy preset is being prepared */
.preview-bar .pv-more { display: contents; } /* a wrapper for updating, not a box: its parts stay items of the bar */
.preview-bar .pv-actions button[data-pv="apply"] { flex: 1.4; }
.preview-bar .pv-info > span:not(.pv-dot):not(.pv-warn) { flex: 1 1 0; min-width: 0; } /* the text wraps beside its dot */
.preview-bar .pv-effect { font-size: 11px; color: var(--muted); line-height: 1.4; text-wrap: pretty; }
.preview-bar .pv-details > summary, .presets-options > summary { cursor: pointer; font-size: 11.5px; color: var(--dim); list-style: none; display: flex; align-items: center; gap: 6px; border-radius: var(--r-sm); padding: 2px 0; }
.preview-bar .pv-details > summary::-webkit-details-marker, .presets-options > summary::-webkit-details-marker { display: none; }
.preview-bar .pv-details > summary::before, .presets-options > summary::before { content: "▸"; font-size: 9px; color: var(--muted); width: 10px; transition: transform var(--t-fast) var(--ease); }
.preview-bar .pv-details[open] > summary::before, .presets-options[open] > summary::before { transform: rotate(90deg); }
.preview-bar .pv-details > summary:hover, .presets-options > summary:hover { color: var(--text); }
.preview-bar .pv-details .pv-auto { margin-top: 6px; }
.preview-bar .pv-details .pv-sum { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Kinetic Playground: a section above the library — title + primary action, one line of explanation, results */
.kp-box { margin: 0 0 12px; padding: 10px; border: 1px solid rgba(200, 243, 106, 0.18); border-radius: var(--r-box); background: var(--glass-base); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07); }
.kp-head { display: grid; gap: 6px; }
.kp-title { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.kp-title strong { font-size: 12.5px; font-weight: 650; }
.kp-head .hint { font-size: 11px; line-height: 1.4; }
.kp-head .kp-help { color: var(--faint); font-size: 10.5px; }
.kp-head .kp-help b { color: var(--dim); font-weight: 600; }
.kp-head .row { display: flex; align-items: center; gap: 6px; }
.kp-box .kp-grid { margin-top: 8px; }
.kp-head .kp-seed { font: 10.5px var(--mono); margin-left: auto; }
.kp-box .notice { margin: 0 0 8px; }
.kp-grid { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.kp-card { position: relative; }
.kp-card .kp-main { width: 100%; height: auto; display: grid; gap: 2px; justify-items: start; text-align: left; white-space: normal; padding: 8px 34px 8px 10px; border-radius: var(--r-box); background: var(--glass-base); border-color: rgba(231, 236, 238, 0.09); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09); }
.kp-card .kp-main:hover:not(:disabled) { background: var(--glass-raised-hover); border-color: rgba(200, 243, 106, 0.5); }
.kp-card.previewing .kp-main { background: var(--glass-active); border-color: rgba(200, 243, 106, 0.55); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), var(--glass-active-edge); }
.kp-card .kp-top { display: flex; gap: 8px; font: 10.5px var(--mono); color: var(--muted); text-transform: uppercase; letter-spacing: 0.02em; }
.kp-card .kp-reach { color: var(--faint); }
.kp-card strong { font-size: 12px; font-weight: 600; }
.kp-card .kp-family { font-size: 11px; color: var(--accent-2); }
.kp-card small { font-size: 10.5px; color: var(--muted); line-height: 1.3; }
/* live cards (proof of concept): the exploration animating on the imported artwork, in its own isolated copy */
.kp-card .kp-stage { display: block; width: 100%; aspect-ratio: 2.6; margin: 0 0 6px; padding: 4px; border-radius: 6px; overflow: hidden;
  background: radial-gradient(120% 95% at 50% 45%, #f6f6f2 0%, #eeefea 68%, #e5e7e1 100%); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.35); }
.kp-card .kp-stage.kp-dark { background: radial-gradient(120% 95% at 50% 45%, #14181a 0%, #0c0f10 68%, #090b0c 100%); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.75); }
.kp-card .kp-host { display: block; width: 100%; height: 100%; }
/* not built live: this exploration's setup is too heavy for this artwork (measured) — click to preview on the canvas */
.kp-card .kp-stage.kp-heavy { display: grid; place-items: center; }
.kp-card .kp-stage.kp-heavy .kp-host { display: none; }
.kp-card .kp-stage.kp-heavy::after { content: "Too heavy to animate live here · click to preview"; font-size: 10.5px; color: var(--muted); }
.kp-card .kp-live-chip { margin-left: auto; color: var(--accent); }
.kp-live-bar { display: flex; align-items: center; gap: 8px; margin: 8px 0 0; font-size: 11px; color: var(--muted); line-height: 1.35; }
.kp-live-bar[hidden], .kp-live-bar [hidden] { display: none; }
.kp-live-bar button { margin-left: auto; flex: none; }
.kp-card .kp-pin { position: absolute; top: 6px; right: 6px; width: 24px; height: 24px; padding: 0; color: var(--muted); }
.kp-card .kp-pin[aria-pressed="true"] { color: var(--accent); }
.presets-options { margin: 0 0 12px; padding: 6px 10px; border: 1px solid rgba(231, 236, 238, 0.08); border-radius: var(--r-ctl); background: var(--glass-base); }
.presets-options[open] { padding-bottom: 10px; }
.presets-options[open] > summary { margin-bottom: 8px; }
.presets-options .opt-state { color: var(--warn); }
.presets-options.non-default { border-color: rgba(227, 189, 104, 0.35); }
.presets-options .field { margin-top: 8px; }
.preview-bar .pv-info { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; font-size: 12px; min-height: 18px; }
.preview-bar .pv-dot { width: 7px; height: 7px; border-radius: 50%; background: rgba(200, 243, 106, 0.35); flex: none; }
.preview-bar .pv-dot.on { background: var(--accent); box-shadow: 0 0 8px rgba(200, 243, 106, 0.8); }
.preview-bar .pv-warn { font: 10.5px var(--mono); color: var(--warn); padding: 1px 6px; border-radius: 8px; border: 1px solid rgba(227, 189, 104, 0.35); }
.preview-bar .pv-note { font: 10.5px var(--mono); color: var(--dim); padding: 1px 6px; border-radius: 8px; border: 1px solid rgba(231, 236, 238, 0.14); } /* information chip (R2) */
.preview-bar .pv-actions { gap: 6px; }
.preview-bar .pv-auto { margin-top: 8px; font-size: 11.5px; color: var(--dim); line-height: 1.45; }
.preview-bar .pv-auto strong { color: var(--text); font-weight: 600; }
.preview-bar .pv-roles { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 8px; font-size: 11.5px; color: var(--dim); }
.preview-bar .pv-roles .n { font: 11px var(--mono); color: var(--text); }
.preview-bar .pv-roles .hint { flex-basis: 100%; font-size: 11px; color: var(--muted); }
.preview-bar .pv-actions button { flex: 1; }
.preset strong { font-size: 12px; font-weight: 600; }
.preset small { font-size: 10.5px; color: var(--muted); line-height: 1.3; text-wrap: pretty; }
.report h4 { margin: 0 0 4px; font-size: 12px; }
.report .steps { font-size: 11.5px; color: var(--dim); }
.anchor-grid { display: grid; grid-template-columns: repeat(3, 28px); gap: 3px; padding: 4px; border-radius: var(--r-ctl); background: var(--inset); border: 1px solid rgba(231, 236, 238, 0.07); box-shadow: var(--inset-shadow); }
.anchor-grid button { width: 28px; height: 28px; padding: 0; border-radius: 4px; } /* largest non-overlapping cell */
.anchor-grid button.on { background: var(--accent); border-color: #e2ff9e; box-shadow: 0 0 8px -2px rgba(200, 243, 106, 0.5); }

/* ======================================================================== status bar */
.statusbar { display: flex; gap: 14px; align-items: center; margin: 0 var(--gap) var(--gap); padding: 0 12px; height: 30px; font-size: 11.5px; color: var(--muted); border-radius: var(--r-ctl); }
.statusbar #statusMsg { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.statusbar #statusMsg::before { content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--faint); margin-right: 8px; vertical-align: 1px; }
.statusbar #statusMsg.error { color: var(--err); }
.statusbar #statusMsg.error::before { background: var(--err); }
.statusbar #statusMsg.ok { color: var(--ok); }
.statusbar #statusMsg.ok::before { background: var(--accent); }
.statusbar #statusMsg.warn { color: var(--warn); }
.statusbar #statusMsg.warn::before { background: var(--warn); }
.statusbar .keys { white-space: nowrap; }

/* ======================================================================== writing order (Natural Write) */
.worder-box > summary { cursor: pointer; margin-bottom: 6px; }
.worder-box > summary .t-sum { float: right; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.worder-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 2px; max-height: 320px; overflow: hidden auto; }
.worder-row { display: flex; align-items: center; gap: 8px; padding: 3px 4px 3px 6px; border-radius: var(--r-sm); border: 1px solid transparent; font-size: 12px; }
.worder-row:hover, .worder-row.hot { background: rgba(255, 255, 255, 0.05); border-color: var(--glass-border-soft); }
.worder-row:focus-visible { outline: 2px solid var(--accent-line); outline-offset: -1px; }
.worder-row .wo-n { min-width: 22px; font: 11.5px var(--mono); color: var(--accent); font-variant-numeric: tabular-nums; text-align: right; }
.worder-row .wo-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.worder-row .wo-acts { display: flex; gap: 2px; flex: none; }
.worder-row .wo-acts button.icon { width: 24px; height: 24px; font-size: 12px; }
.worder-row .wo-acts button[aria-pressed="true"] { color: var(--accent); border-color: var(--accent-line); }
.overlay .wo-overlay { position: absolute; left: 0; top: 0; overflow: visible; }
.overlay .wo-mark line, .overlay .wo-mark polyline { stroke: var(--accent); stroke-width: 1.5; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.overlay .wo-mark circle { fill: rgba(17, 20, 22, 0.88); stroke: var(--accent); stroke-width: 1.2; }
.overlay .wo-mark text { fill: var(--text); font: 600 9.5px var(--mono); text-anchor: middle; }
.overlay .wo-mark.hot circle { fill: var(--accent); }
.overlay .wo-mark.hot text { fill: var(--accent-ink); }
.overlay .wo-hot { fill: rgba(200, 243, 106, 0.18); stroke: var(--accent); stroke-width: 1.5; }

/* ======================================================================== preset hover preview */
/* A compact floating glass panel beside the hovered card: the preset's real motion on the fixed Arabic sample.
   Concentric corners: panel radius 14 = stage radius 6 + padding 8. The stage gets most of the height (the lettering
   is what the panel is for); title, category and text are a quiet frame around it. */
.hp-panel {
  --hp-out: 110ms; /* = hoverpreview.js EXIT_MS: the closing fade (the demo's last frame stays while it fades) */
  position: fixed; left: 0; top: 0; z-index: 40; width: 248px;
  border-radius: var(--r-panel); color: var(--text); pointer-events: auto;
  background: linear-gradient(142deg, rgba(255, 255, 255, 0.07), rgba(0, 0, 0, 0.12)), var(--glass-solid);
  box-shadow: var(--shadow-float), inset 0 1px 0 rgba(255, 255, 255, 0.16), inset 1px 0 0 rgba(255, 255, 255, 0.05);
  padding: 8px; display: grid; transform-origin: right center;
}
/* The entrance and exit (a short fade with a 4 px settle from the card's side) are Web Animations started by ui.js
   AFTER the sample is measured: a transform on the panel must never be in place while the renderer measures.
   Closed: pointer-events off AT ONCE, so the fading panel never intercepts the pointer; visibility follows when the
   fade has ended. */
.hp-panel:not(.open) { opacity: 0; visibility: hidden; pointer-events: none; transition: visibility 0s linear var(--hp-out); }
.hp-panel[data-side="right"] { transform-origin: left center; }
.hp-panel[data-side="below"] { transform-origin: center top; }
.hp-panel[data-side="above"] { transform-origin: center bottom; }
@media (prefers-reduced-motion: reduce) { .hp-panel, .hp-panel:not(.open) { transition: none; transform: none; } }
.hp-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; min-width: 0; padding: 2px 4px 7px; }
.hp-head strong { font-size: 12px; font-weight: 600; letter-spacing: 0.005em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hp-head .hp-fam { flex: none; font: 10.5px var(--mono); color: var(--muted); letter-spacing: 0.02em; text-transform: uppercase; } /* as the cards' family label */
.hp-stage { aspect-ratio: 2.25; border-radius: 6px; overflow: hidden; padding: 4px;
  background: radial-gradient(120% 95% at 50% 45%, #f6f6f2 0%, #eeefea 68%, #e5e7e1 100%);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.35), inset 0 10px 24px -18px rgba(0, 0, 0, 0.4); }
.hp-host { width: 100%; height: 100%; }
/* the imported artwork on the canvas's own dark well when the canvas shows it dark (light ink) — no recolouring */
.hp-panel.hp-dark .hp-stage { background: radial-gradient(120% 95% at 50% 45%, #14181a 0%, #0c0f10 68%, #090b0c 100%); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.75), inset 0 10px 24px -18px rgba(0, 0, 0, 0.6); }
.hp-note { margin: 0; padding: 8px 4px 0; font-size: 11px; line-height: 1.4; color: var(--dim); text-wrap: pretty; }
.hp-honest { margin: 0; padding: 4px 4px 0; font-size: 10.5px; line-height: 1.35; color: var(--warn); text-wrap: pretty; }
.hp-honest:empty { display: none; }
.hp-honest.info { color: var(--muted); } /* a description of what the preview shows, not a problem (R2) */
.hp-foot { padding: 7px 4px 1px; font-size: 10.5px; color: var(--faint); }
/* visually hidden, still read by assistive technology (e.g. a card's "N motions" detail, formerly a title tooltip) */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ======================================================================== video export dialog */
/* Floating glass like the panels; opened rarely, so a short ease-out entrance from the centre (modal, not anchored). */
.video-dialog {
  width: min(460px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  margin: max(16px, 14vh) auto auto; /* top-anchored: the progress row and messages grow it downwards, it never jumps */
  padding: 0;
  border: 0;
  border-radius: var(--r-panel);
  color: var(--text);
  background: linear-gradient(142deg, rgba(255, 255, 255, 0.07), rgba(0, 0, 0, 0.12)), var(--glass-solid);
  box-shadow: var(--shadow-float), inset 0 1px 0 rgba(255, 255, 255, 0.2), inset 1px 0 0 rgba(255, 255, 255, 0.07);
  opacity: 1;
  transform: scale(1);
  transition: opacity 180ms cubic-bezier(0.23, 1, 0.32, 1), transform 180ms cubic-bezier(0.23, 1, 0.32, 1), overlay 180ms allow-discrete, display 180ms allow-discrete;
}
@starting-style { .video-dialog[open] { opacity: 0; transform: scale(0.96); } }
.video-dialog::backdrop { background: rgba(4, 6, 7, 0.55); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
.vd { display: grid; gap: 12px; padding: 18px 18px 16px; }
.vd-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.vd-head h2 { margin: 0; font-size: 15px; font-weight: 650; letter-spacing: 0.01em; }
.vd-size { font: 11.5px var(--mono); color: var(--muted); font-variant-numeric: tabular-nums; }
.vd-field { display: grid; grid-template-columns: 96px minmax(0, 1fr); align-items: center; gap: 10px; }
.vd-field[hidden] { display: none; }
.vd-label { font-size: 12px; color: var(--dim); }
.vd-seg { width: 100%; }
.vd-seg button { flex: 1; }
.vd-sub { margin-left: 4px; font-size: 11px; font-weight: 500; color: var(--muted); }
.vd-seg button.active .vd-sub { color: inherit; opacity: 0.75; }
.vd-note, .vd-hint, .vd-plan, .vd-msg { margin: 0; font-size: 12px; line-height: 1.5; text-wrap: pretty; }
.vd-note { color: var(--muted); margin-top: -4px; }
.vd-hint { color: var(--muted); margin: -6px 0 0 106px; }
.vd-hint[hidden] { display: none; }
.vd-hint.error { color: var(--err); }
.vd-bg { display: flex; align-items: center; gap: 6px; }
.vd-bg input[type=color] { width: var(--ctl-h); height: var(--ctl-h); padding: 2px; flex: none; border: 1px solid rgba(231, 236, 238, 0.12); border-radius: var(--r-ctl); background: var(--inset); cursor: pointer; }
.vd-bg input[type=color]::-webkit-color-swatch-wrapper { padding: 0; }
.vd-bg input[type=color]::-webkit-color-swatch { border: 0; border-radius: calc(var(--r-ctl) - 3px); }
.vd-bg input[type=text] { width: 92px; flex: none; font: 12px var(--mono); text-transform: lowercase; }
.vd-bg input[aria-invalid=true] { border-color: rgba(240, 137, 124, 0.6); }
.vd-plan { padding: 8px 10px; border-radius: var(--r-box); background: var(--inset); box-shadow: var(--inset-shadow); color: var(--dim); font-variant-numeric: tabular-nums; }
.vd-progress { display: flex; align-items: center; gap: 10px; }
.vd-progress[hidden] { display: none; }
.vd-progress progress { flex: 1; height: 6px; -webkit-appearance: none; appearance: none; border: 0; border-radius: 6px; overflow: hidden; background: var(--inset-strong); }
.vd-progress progress::-webkit-progress-bar { background: var(--inset-strong); border-radius: 6px; }
.vd-progress progress::-webkit-progress-value { background: var(--accent); border-radius: 6px; transition: width 120ms linear; }
.vd-progress progress::-moz-progress-bar { background: var(--accent); border-radius: 6px; }
.vd-count { font: 11.5px var(--mono); color: var(--dim); font-variant-numeric: tabular-nums; min-width: 92px; text-align: right; }
.vd-msg { min-height: 18px; color: var(--dim); overflow-wrap: anywhere; }
.vd-msg:empty { display: none; }
.vd-msg.ok { color: var(--ok); }
.vd-msg.error { color: var(--err); }
.video-dialog[data-state=running] .vd-msg, .video-dialog[data-state=finishing] .vd-msg, .video-dialog[data-state=checking] .vd-msg { color: var(--muted); }
.vd-actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 4px; }

/* ======================================================================== responsive */
@media (max-width: 1360px) {
  .workspace { grid-template-columns: 244px minmax(0, 1fr) 312px; }
  .brand p { display: none; }
}
/* tall windows (the desktop layout only): the timeline grows with the height — ≈ 281px at 1080, 340px from ~1310 — so
   more tracks show; shorter windows keep clamp(156px, 26vh, 236px) */
@media (min-width: 1141px) and (min-height: 1050px) {
  .workspace { grid-template-rows: minmax(0, 1fr) clamp(236px, 26vh, 340px); }
}
@media (max-width: 1140px) {
  /* inspector moves under the canvas; the page scrolls instead of squeezing the canvas */
  body { overflow: auto; }
  .app { height: auto; min-height: 100vh; }
  .workspace { grid-template-columns: 236px minmax(0, 1fr); grid-template-rows: minmax(420px, 62vh) 236px 520px; }
  .inspector-panel { grid-column: 1 / -1; grid-row: 3; }
  .statusbar .keys { display: none; }
}
@media (max-width: 860px) {
  .topbar { flex-wrap: wrap; }
  .top-actions { flex: 1 1 auto; flex-wrap: wrap; justify-content: flex-end; } /* six actions no longer fit on one line here */
  .doc { order: 3; flex-basis: 100%; }
  .workspace { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto; }
  .left-panel, .viewport, .timeline, .inspector-panel { grid-column: 1; grid-row: auto; }
  .left-panel { max-height: 420px; }
  .viewport { height: 62vh; min-height: 340px; }
  .timeline { height: 280px; }
  .inspector-panel { height: 560px; }
}

/* ======================================================================== reduced motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0ms !important; animation-duration: 0ms !important; }
}

/* ======================================================================== Cinematic Glass: interface refinement
 * The interface brought up to the environment: hairline controls on one glass material, a glass tab rail lit at its
 * top edge, a thin slider filled in lime (range-fill.js), label | control rows in the inspector, a large light
 * timecode, softer motion blocks and a typographic light table for the canvas. View only: no layout size changes. */
:root { --disp: "Segoe UI Variable Display", var(--font); }
/* controls: fine hairline pills; only what is raised gets glass (class rules — tools, tabs, presets, chips — keep their own shape) */
button { border-radius: 999px; background: rgba(255, 255, 255, 0.035); border-color: rgba(231, 236, 238, 0.1); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05); }
button:hover:not(:disabled) { background: rgba(255, 255, 255, 0.075); border-color: rgba(231, 236, 238, 0.22); }
button.icon { border-radius: 50%; }
select, input[type=text], input[type=number] { border-radius: 8px; background: rgba(0, 0, 0, 0.36); border-color: rgba(231, 236, 238, 0.05); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.45); }
input[type=number] { font-variant-numeric: tabular-nums; }
/* slider: a 2 px track, lime up to the value, a white thumb that gains a lime halo while in use */
input[type=range]::-webkit-slider-runnable-track { height: 2px; background: linear-gradient(90deg, var(--accent) var(--p, 0%), rgba(231, 236, 238, 0.14) var(--p, 0%)); box-shadow: none; }
input[type=range]::-webkit-slider-thumb { width: 12px; height: 12px; margin-top: -5px; background: #f4f7f8; border: 0; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.45), 0 2px 6px rgba(0, 0, 0, 0.6); }
input[type=range]:active::-webkit-slider-thumb, input[type=range]:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 5px rgba(200, 243, 106, 0.18), 0 0 0 1px rgba(0, 0, 0, 0.45); }
input[type=range]::-moz-range-track { height: 2px; background: rgba(231, 236, 238, 0.14); box-shadow: none; }
input[type=range]::-moz-range-progress { height: 2px; background: var(--accent); }
input[type=range]::-moz-range-thumb { width: 12px; height: 12px; background: #f4f7f8; border: 0; }
/* navigation: one glass rail; the active tab is clearer glass lit along its top edge, with a lime line */
.tabs { border-radius: 12px; background: rgba(0, 0, 0, 0.3); border-color: rgba(231, 236, 238, 0.05); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5); }
.tabs button { border-radius: 9px; color: var(--muted); }
.tabs button.active { background: linear-gradient(180deg, rgba(255, 255, 255, 0.13), rgba(255, 255, 255, 0.04)); border-color: transparent; color: var(--text); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28), inset 0 -1.5px 0 var(--accent), 0 4px 10px -4px rgba(0, 0, 0, 0.8); }
.seg { border-radius: 12px; background: rgba(0, 0, 0, 0.22); border-color: rgba(231, 236, 238, 0.06); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.4); }
.seg button { border-radius: 9px; }
.seg button.active { background: linear-gradient(180deg, rgba(255, 255, 255, 0.13), rgba(255, 255, 255, 0.04)); border-color: transparent; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.26), inset 0 -1.5px 0 var(--accent), 0 4px 10px -4px rgba(0, 0, 0, 0.8); }
/* typography */
.panel-head h2, .canvas-bar .title { font-family: var(--disp); font-size: 13px; letter-spacing: -0.005em; }
.group-box > h3, .targets-box > summary .h3 { font-family: var(--disp); font-size: 13px; letter-spacing: -0.005em; }
.doc input[type=text] { font-family: var(--disp); font-size: 14px; }
.version { border-radius: 999px; padding: 1px 8px; background: none; }
/* inspector: label | control on one grid; hints and wide rows sit under the control */
.panel-body .group-box > .field { display: grid; grid-template-columns: 88px minmax(0, 1fr); align-items: center; column-gap: 12px; }
.panel-body .group-box > .field { grid-template-columns: 84px minmax(0, 1fr); }
.panel-body .group-box > .field > label, .panel-body .group-box > .field > .lbl { margin: 0; color: var(--muted); flex-direction: column; align-items: flex-start; justify-content: center; gap: 0; line-height: 1.25; }
.panel-body .group-box > .field > label > *, .panel-body .group-box > .field > .lbl > * { font-size: 10px; color: var(--faint); } /* the unit, quietly under the name */
.panel-body .group-box > .field > :not(label):not(.lbl) { grid-column: 2; }
/* timeline: softer motion blocks, a large light timecode, a finer playhead */
.tl-bar { border-radius: 8px; }
.timecode { font: 500 13px var(--mono); letter-spacing: 0.03em; font-variant-numeric: tabular-nums; color: var(--dim); background: none; border-color: transparent; box-shadow: none; } /* a quiet technical readout: monospaced, so the digits never shift while playing */
.playhead { width: 1.5px; }
/* canvas: a typographic light table — the paper unchanged, a fine lit rim, a deep shadow and a faint spill of light */
.stage.light-bg { border-radius: 6px; border-color: transparent; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.22), 0 30px 70px -30px rgba(0, 0, 0, 1), 0 0 90px -24px rgba(225, 232, 226, 0.16); }
/* ======================================================================== unified states
 * One language in every state, empty or loaded: no dashed boxes or cards inside panels, one look for anything
 * disabled, one lime call to action per screen, one radius scale (controls 8 / containers 12 / panels 14 / pills) and
 * flat hairline key caps. */
:root { --r-ctl: 8px; --r-box: 12px; }
kbd { border: 1px solid rgba(231, 236, 238, 0.12); border-radius: 4px; background: none; color: var(--muted); }
/* empty canvas: the content alone in the well, no frame; the mark is a quiet ring */
.empty-card { border: 0; background: none; box-shadow: none; }
.empty-card .em { border-radius: 50%; background: none; border: 1px solid rgba(231, 236, 238, 0.14); box-shadow: none; }
/* first-use guide: a section of the panel, not a card; its Import is secondary (the canvas holds the primary one) */
.guide { border: 0; border-radius: 0; background: none; box-shadow: none; padding: 4px 2px 0; }
.guide-steps .file-btn { border-radius: 999px; }
.guide-steps .file-btn button.primary { background: rgba(200, 243, 106, 0.08); border-color: rgba(200, 243, 106, 0.45); color: var(--accent); box-shadow: none; font-weight: 600; }
.guide-steps .file-btn button.primary:hover:not(:disabled) { background: rgba(200, 243, 106, 0.16); border-color: var(--accent); }
.layers-empty { border: 0; padding: 18px 8px; }
/* disabled: one look everywhere — flat, dim, a faint solid hairline (top bar, transport, panels, primary alike) */
.app button:disabled, .app .top-actions button:disabled { opacity: 0.4; background: rgba(255, 255, 255, 0.02); border-style: solid; border-color: rgba(231, 236, 238, 0.1); box-shadow: none; color: var(--dim); }
.app button.primary:disabled { background: rgba(255, 255, 255, 0.02); border: 1px solid rgba(231, 236, 238, 0.1); color: var(--dim); }
/* ======================================================================== consistency across tabs and widths */
/* menus: flat rows, never the top bar's hairline buttons (the menu sits inside .top-actions) */
.top-actions .menu [role="menuitem"] { border-radius: 7px; background: transparent; border-color: transparent; box-shadow: none; }
.top-actions .menu [role="menuitem"]:hover:not(:disabled), .top-actions .menu [role="menuitem"]:focus-visible { background: rgba(255, 255, 255, 0.07); border-color: transparent; }
.top-actions .menu #resetBtn:hover:not(:disabled), .top-actions .menu #resetBtn:focus-visible { color: var(--err); background: var(--err-bg); }
/* explanatory notes (Director, Morph Lab…): quiet text above the section, no box; warnings and errors keep theirs */
.notice.info { border: 0; background: none; padding: 2px 2px 12px; margin-bottom: 0; color: var(--muted); }
/* Kinetic Playground: a section of the Presets panel, not a card; its action is secondary */
.kp-box { border: 0; border-top: 1px solid rgba(231, 236, 238, 0.08); border-bottom: 1px solid rgba(231, 236, 238, 0.08); border-radius: 0; background: none; box-shadow: none; padding: 12px 2px; }
.kp-box button.primary { background: rgba(200, 243, 106, 0.08); border-color: rgba(200, 243, 106, 0.45); color: var(--accent); box-shadow: none; font-weight: 600; }
.kp-box button.primary:hover:not(:disabled) { background: rgba(200, 243, 106, 0.16); border-color: var(--accent); }
/* the chosen filter chip: a lime edge, not a lime fill (lime fills are for the one primary action) */
.preset-chips .chip[aria-pressed="true"] { color: var(--accent); background: rgba(200, 243, 106, 0.1); border-color: rgba(200, 243, 106, 0.5); }
/* Morph Lab: Load target is a normal-sized button, not a full-width pill */
#tab-morph .file-btn { width: auto !important; border-radius: 999px; }
#tab-morph .file-btn > button { width: auto !important; }
/* section titles with a long aside: the aside on its own quiet line */
.group-box > h3 .h3-note { display: block; flex-basis: 100%; font-size: 11px; font-weight: 400; color: var(--muted); letter-spacing: 0; }
.group-box > h3:has(.h3-note) { flex-wrap: wrap; row-gap: 2px; }
/* 1141–1360 px: the inspector is 312 px — labels go back above their control so lists are not cut, and the tabs and
   layer tools tighten so they fit */
@media (min-width: 1141px) and (max-width: 1360px) {
  .panel-body .group-box > .field { display: block; }
  .panel-body .group-box > .field > label, .panel-body .group-box > .field > .lbl { flex-direction: row; justify-content: space-between; align-items: center; margin-bottom: 5px; gap: 8px; color: var(--dim); }
  .panel-body .group-box > .field > label > *, .panel-body .group-box > .field > .lbl > * { font-size: inherit; color: var(--muted); }
  .tabs button { font-size: 11.5px; padding: 0 2px; }
  .layer-tools button { padding: 0 7px; }
}
/* ======================================================================== collapsible lists (collapsible.js) */
.cl-head { cursor: pointer; display: flex; align-items: center; gap: 8px; user-select: none; border-radius: 6px; }
.cl-head:hover { color: var(--text); }
.cl-head:focus-visible { outline: none; box-shadow: var(--ring); }
.cl-head::after { content: ""; margin-left: auto; flex: none; width: 6px; height: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg) translate(-2px, -2px); opacity: 0.55; transition: transform var(--t) var(--ease); }
.cl-closed > .cl-head::after { transform: rotate(-45deg); }
.cl-head .cl-count { font: 10.5px var(--mono); color: var(--muted); font-variant-numeric: tabular-nums; font-weight: 400; }
/* closed: only the title row stays (a search or a group filter opens every matching group) */
.preset-group.cl-closed > :not(.cl-head) { display: none; }
#tab-presets.cl-filtering .preset-group.cl-closed > :not(.cl-head) { display: revert; }
#tab-presets.cl-filtering .preset-group.cl-closed > .preset-grid { display: grid; }
#tab-presets.cl-filtering .preset-group.cl-closed > .cl-head::after { transform: rotate(45deg) translate(-2px, -2px); } /* shown while searching: the arrow says so */
#tab-inspector .group-box.cl-closed > :not(.cl-head) { display: none; }
#tab-inspector .group-box.cl-closed > .cl-head { margin-bottom: 0; }
/* preset groups: each a glass row — the family dot, the title, the count in a pill, the arrow. Open: the row is lit
   with its family colour and its cards follow below. */
.preset-group { --gc: #c3cccf; margin-bottom: 6px; }
.preset-group[data-fam="entrance"] { --gc: #b6dc8c; }
.preset-group[data-fam="loop"] { --gc: #78dcbe; }
.preset-group[data-fam="expressive"] { --gc: #d6e878; }
.preset-group[data-fam="from-references"] { --gc: #e3bd68; }
.preset-group[data-fam="full-artwork-motion"] { --gc: #aad2be; }
.preset-group[data-fam="effect"] { --gc: #78c8dc; }
.preset-group > .section-label.cl-head { margin: 0; padding: 9px 12px; border-radius: 12px; font-size: 13px; font-weight: 600; color: var(--text); background: linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.025)); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), inset 0 0 0 1px rgba(231, 236, 238, 0.07); transition: background var(--t) var(--ease), box-shadow var(--t) var(--ease); }
.preset-group > .section-label.cl-head:hover { background: linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.04)); }
.preset-group > .section-label.cl-head::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--gc); box-shadow: 0 0 0 3px color-mix(in srgb, var(--gc) 18%, transparent); }
.preset-group > .section-label.cl-head .cl-count { margin-left: auto; padding: 1px 8px; border-radius: 999px; background: rgba(255, 255, 255, 0.06); color: var(--dim); }
.preset-group > .section-label.cl-head::after { margin-left: 10px; }
.preset-group:not(.cl-closed) > .section-label.cl-head, #tab-presets.cl-filtering .preset-group > .section-label.cl-head { margin-bottom: 8px; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), inset 0 0 0 1px color-mix(in srgb, var(--gc) 45%, transparent); }
#presetSearch::placeholder { font-size: 11.5px; } /* the hint fits the field: "Search presets · click to preview" */

/* a closed preset group's contents, on hover or focus of its title (collapsible.js) */
.cl-tip { position: fixed; z-index: 70; display: flex; flex-wrap: wrap; gap: 4px; padding: 8px; border-radius: 10px; pointer-events: none;
  background: #0b0e0f; box-shadow: inset 0 0 0 1px rgba(231, 236, 238, 0.12), 0 12px 28px -10px rgba(0, 0, 0, 0.9); }
.cl-tip[hidden] { display: none; }
.cl-tip span { font-size: 11.5px; color: var(--text); padding: 2px 8px; border-radius: 999px; background: rgba(255, 255, 255, 0.06); white-space: nowrap; }
.cl-tip span.more { background: none; color: var(--muted); }
@media (prefers-reduced-motion: no-preference) { .cl-tip:not([hidden]) { animation: clTipIn 120ms var(--ease); } }
@keyframes clTipIn { from { opacity: 0; transform: translateY(-2px); } }