/* ===== Halo aurora design tokens (Slice 1) ===== */
:root {
  --bg0:#050509; --bg1:#0a0a11; --bg2:#101019; --bg3:#1a1a26;
  --border:rgba(255,255,255,0.07); --bord2:rgba(255,255,255,0.14);
  --text:#f0f0f6; --dim:#8f8fa6; --faint:#56566a;
  --accent:#8b6cff; --accent2:#ff4fa3; --accent3:#4fd6ff;
  --grad:linear-gradient(135deg,#8b6cff,#ff4fa3 55%,#ff9a5a);
  --glow:rgba(139,108,255,0.45); --onAccent:#ffffff;
  --font-display:'Space Grotesk',system-ui,sans-serif;
  --font-ui:'Manrope',system-ui,sans-serif;
}
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pop { 0% { transform: scale(.95); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
@keyframes shim { 0% { background-position:-180% 0; } 100% { background-position:180% 0; } }

body {
  background: var(--bg0);
  color: var(--text);
  font-family: var(--font-ui);
}

/* Legacy tokens (preserved for compatibility). --border/--text/--accent are
   intentionally omitted so the aurora :root above provides them. */
:root {
  --bg: #0a0c14; --panel: #0d0f18; --muted: #718096; --accent-light: #a78bfa;
}
* { box-sizing: border-box; }
body { margin: 0; }

.mc-topbar { display: flex; justify-content: space-between; align-items: center;
  padding: 10px 16px; background: #0a0c14; border-bottom: 1px solid var(--border); }
.mc-logo { font-weight: 800; letter-spacing: .04em; }
.mc-btn { background: #141720; color: var(--text); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 14px; font-weight: 600; cursor: pointer; }
.mc-btn-primary { background: var(--accent); border-color: var(--accent); }
.mc-btn-danger { color: #fc8181; border-color: #4a2530; }

.mc-view { display: none; flex: 1; min-height: 0; }
.mc-view.mc-active { display: flex; flex-direction: column; }
.mc-view-image { position: relative; }
#mc-prompt, #mc-video-prompt { width: 100%; min-height: 90px; background: #141720; color: var(--text);
  border: 1px solid var(--border); border-radius: 8px; padding: 8px; resize: vertical; }
.mc-edit-overlay label { display: block; margin: 10px 0; font-size: .875rem; color: var(--muted); }
.mc-tool-group { border-top: 1px solid var(--border); padding-top: 10px; margin-top: 10px;
  display: flex; flex-direction: column; gap: 8px; }
.mc-library { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 12px; }
.mc-library img { width: 100%; border-radius: 8px; cursor: pointer; border: 2px solid transparent; }
.mc-library img:hover { border-color: var(--accent-light); }
.mc-thumb { display: flex; flex-direction: column; gap: 4px; }
.mc-thumb img { cursor: pointer; width: 100%; border-radius: 6px; }
.mc-use-prompt { font-size: 0.8125rem; padding: 2px 6px; }

.mc-trim-scrubber video { width: 100%; border-radius: 8px; background: #000; }
.mc-trim-track { position: relative; height: 24px; margin-top: 8px; background: var(--bg2); border-radius: 6px; }
.mc-trim-handle { position: absolute; top: 0; width: 10px; height: 24px; background: var(--accent); border-radius: 4px; cursor: ew-resize; transform: translateX(-50%); touch-action: none; }

.mc-canvas-wrap { background: #05070d; border: 1px solid var(--border);
  border-radius: 12px; display: flex; align-items: center; justify-content: center;
  overflow: auto; flex: 1; min-height: 0; }
.mc-edit-overlay { position: absolute; top: 12px; right: 12px;
  width: 220px; max-height: calc(100% - 24px); overflow-y: auto;
  background: rgba(13, 15, 24, 0.92); border: 1px solid var(--border);
  border-radius: 12px; padding: 12px; backdrop-filter: blur(6px);
  display: flex; flex-direction: column; gap: 8px; z-index: 5; }
.mc-edit-overlay[hidden] { display: none; }
.mc-overlay-handle { cursor: move; user-select: none; touch-action: none;
  font-size: .7rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); padding: 2px 4px 8px; margin: -2px -2px 4px;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between; }
.mc-overlay-close { background: none; border: none; color: var(--faint); cursor: pointer; font-size: 14px; padding: 2px 4px; }
.mc-overlay-close:hover { color: var(--text); }

.mc-draw-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 8px 10px; margin-bottom: 10px; background: var(--panel);
  border: 1px solid var(--border); border-radius: 10px; }
.mc-draw-tools .mc-btn { padding: 6px 12px; }
/* Sets the accent as the BACKGROUND, so it must also set a colour: the
   less specific `.mc-btn.mc-active` below paints the label with the same
   accent, which rendered the active tool's name invisible on itself. */
.mc-draw-tools .mc-btn.mc-active { background: var(--accent);
  border-color: var(--accent); color: #fff; }
.mc-draw-field { display: flex !important; align-items: center; gap: 6px; margin: 0 !important;
  font-size: .875rem; color: var(--muted); }
.mc-draw-field input[type="color"] { width: 32px; height: 28px; padding: 0; border: 1px solid var(--border);
  border-radius: 6px; background: #141720; cursor: pointer; }
.mc-draw-field input[type="range"] { width: 90px; }

.mc-mobile-nav { display: none; }
.halo-mobile-toggles { display: none; }

.mc-video-modes { display: flex; gap: 8px; margin-bottom: 10px; }
.mc-video-modes .mc-btn { flex: 1; }
.mc-hint { font-size: 1rem; line-height: 1.6; color: #718096; margin: 4px 0; }
.mc-clip-library { flex: 1; display: flex; flex-direction: column; gap: 12px; margin-top: 14px; min-height: 0; overflow-y: auto; }
.mc-clip-card { background: #141720; border: 1px solid #1e2535; border-radius: 12px;
  padding: 8px; display: flex; flex-direction: column; align-items: center; flex: 0 0 auto; }
.mc-clip-card video { width: 100%; max-height: 56vh;
  object-fit: contain; border-radius: 8px; display: block; background: #000; }
.mc-clip-card .mc-btn { margin-top: 8px; display: inline-block; }
.mc-clip-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.mc-clip-status { font-size: 1rem; line-height: 1.6; color: #a0aec0; padding: 28px 16px; text-align: center; }
.mc-clip-error { color: #fc8181; }
/* 14px is the fine-print floor: this is the user's own prompt text, which is
   read, not a label. It was 0.8rem (~12.8px). */
.mc-clip-prompt { font-size: 14px; color: #a0aec0; margin-top: 8px; width: 100%; line-height: 1.55; }
.mc-clip-delete { color: #fc8181; border-color: #5a2b32; }
.mc-clip-delete:hover { background: #2a1619; border-color: #7a3a43; }
/* Armed state: the second click is the destructive one, so it stops looking
   like the other buttons in the row. */
.mc-clip-delete.mc-armed { background: #fc8181; border-color: #fc8181; color: #1a1014; }
.mc-clip-delete[disabled] { opacity: 0.6; cursor: default; }
.mc-clip-msg { font-size: 14px; line-height: 1.5; color: #fc8181; margin: 8px 0 0; width: 100%; }
.mc-clip-msg[hidden] { display: none; }
.mc-clip-prompt-label { color: #718096; text-transform: uppercase; font-size: 0.62rem;
  letter-spacing: 0.05em; font-weight: 700; margin-right: 6px; }
.mc-trim { width: 100%; margin-top: 10px; }
.mc-trim-track { position: relative; height: 26px; background: #1e2535;
  border-radius: 8px; margin: 6px 0; touch-action: none; }
.mc-trim-range { position: absolute; top: 0; bottom: 0;
  background: rgba(102, 126, 234, 0.30); border-top: 1px solid rgba(102, 126, 234, 0.6);
  border-bottom: 1px solid rgba(102, 126, 234, 0.6); }
.mc-trim-handle { position: absolute; top: -3px; width: 14px; height: 32px;
  margin-left: -7px; background: #667eea; border-radius: 5px; cursor: ew-resize;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.55); touch-action: none; }
.mc-trim-readout { font-size: 0.72rem; color: #a0aec0; text-align: center; margin-top: 2px; }
.mc-trim-actions { display: flex; justify-content: center; margin-top: 8px; }
.mc-library img.mc-selected { outline: 2px solid #667eea; }

/* --- Sequencer --- */
.mc-seq-bin-label { font-size: .6rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); margin: 12px 0 6px; }

/* A sidebar section with a rule above it. The narration controls are one unit
   — voice, button, status, help — and before this they ran straight on from
   the audio bin, which put "+ Add narration" close enough to "+ Add text" to
   be hit by mistake. The rule and the extra space are the separation; the
   button below is the other half of it. */
.mc-seq-group { display: flex; flex-direction: column;
  border-top: 1px solid var(--border); margin-top: 18px; padding-top: 4px; }
.mc-seq-group > .mc-seq-bin-label:first-child { margin-top: 10px; }

.mc-seq-bin { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.mc-seq-thumb { position: relative; height: 58px; border-radius: 6px; font-size: .7rem;
  color: #cbd5e1; display: flex; align-items: center; justify-content: center;
  cursor: pointer; border: 1px solid var(--border); background: #141720;
  overflow: hidden; transition: border-color .12s ease, transform .12s ease; }
.mc-seq-thumb:hover { border-color: var(--accent); transform: translateY(-1px); }
.mc-seq-thumb img, .mc-seq-thumb video { width: 100%; height: 100%; object-fit: cover; display: block; }
.mc-seq-thumb.is-clip { background: linear-gradient(135deg,#1a2540,#243b6b); }
.mc-seq-thumb.is-image { background: linear-gradient(135deg,#3a2540,#5b2f55); }
.mc-seq-thumb.is-audio { background: linear-gradient(135deg,#1f3a32,#2f6b55); }
/* A clip tile shows a real frame; until the seek lands the gradient stands in. */
.mc-seq-thumb.is-clip video { opacity: 0; transition: opacity .18s ease; }
.mc-seq-thumb.is-clip.has-poster video { opacity: 1; }
.mc-seq-thumb-badge { position: absolute; right: 3px; bottom: 3px; font-size: .62rem;
  padding: 1px 4px; border-radius: 4px; background: rgba(0,0,0,.68); color: #e2e8f0;
  pointer-events: none; }

.mc-seq-output { margin-top: 10px; font-size: 1rem; color: var(--muted); }
.mc-seq-output a { color: var(--accent-light); }

/* .mc-view is display:none by default and display:flex+column when .mc-active —
   do NOT set display here or the view would always show. Only add the gap.

   min-width:0 is load-bearing, not tidiness. A flex item defaults to
   min-width:auto, so this column was sized by its widest descendant — the
   timeline, which is as wide as the sequence is long. At 1400px the view grew
   to 1702px, pushing the zoom slider, the snap toggle and the +Track button
   off screen where they could not be clicked, and #mc-seq-tracks' own
   overflow-x:auto never engaged because nothing upstream constrained it. */
/* The sequencer column scrolls as a whole. Before slice 4 it held a preview,
   a timeline and an inspector and just about fitted; the five workflow panels
   under it do not, and a column that overflows without scrolling puts the
   render button somewhere no pointer can reach. The preview keeps its
   min-height, so what scrolls is the stack, not the picture. */
.mc-view-seq.mc-active { gap: 10px; min-width: 0; overflow-y: auto;
  overscroll-behavior: contain; }
.mc-seq-timeline { min-width: 0; }

/* --- Sequencer canvas --- */
.mc-seq-preview { flex: 1; min-height: 220px; background: #05070d;
  border: 1px solid var(--border); border-radius: 10px; position: relative;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  padding: 10px; container-type: size; }
.mc-seq-preview-empty { color: #4a5568; font-size: 1rem; line-height: 1.6;
  position: absolute; pointer-events: none; }
/* The preview IS the render canvas, drawn by compose.js and scaled down by
   the browser. Its width/height attributes carry the frame's own ratio, so
   letting the element size itself letterboxes correctly — no aspect-ratio
   arithmetic, which is what the previous DOM stage needed. */
.mc-seq-canvas { display: block; margin: 0 auto; width: auto; height: auto;
  max-width: 100%; max-height: 100%; background: #000; border-radius: 6px; }
.mc-seq-canvas[hidden] { display: none; }

/* --- Direct manipulation overlay ---
   A transparent DOM layer sized and positioned exactly over the canvas by
   syncStage(). Selection outlines, grab handles and the inline text editor all
   live HERE and never touch the 2D context — the canvas is literally the frame
   the renderer will export, so chrome composited onto it would ship inside the
   finished video. */
.mc-seq-stage { position: absolute; touch-action: none; cursor: default;
  user-select: none; -webkit-user-select: none; }
.mc-seq-stage[hidden] { display: none; }
.mc-seq-stage-sel { position: absolute; pointer-events: none;
  border: 1px solid var(--accent); border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(5,7,13,.6); }
.mc-seq-stage-handle { position: absolute; width: 10px; height: 10px;
  background: var(--accent); border: 1px solid #05070d; border-radius: 2px;
  box-shadow: 0 1px 3px rgba(0,0,0,.5); }
.mc-seq-stage-handle.is-nw { left: -6px; top: -6px; }
.mc-seq-stage-handle.is-ne { right: -6px; top: -6px; }
.mc-seq-stage-handle.is-sw { left: -6px; bottom: -6px; }
.mc-seq-stage-handle.is-se { right: -6px; bottom: -6px; }
.mc-seq-stage.is-dragging .mc-seq-stage-handle { opacity: .45; }
/* The size is set inline to track the caption's own rendered size, floored at
   16px so a small caption never becomes an illegible editing field. */
.mc-seq-stage-edit { position: absolute; z-index: 2; margin: 0; resize: none;
  padding: 4px 6px; line-height: 1.35; font-size: 16px; overflow: hidden;
  background: rgba(5,7,13,.74); color: var(--text);
  border: 1px solid var(--accent); border-radius: 4px;
  box-shadow: 0 0 0 3px var(--glow); }
.mc-seq-stage-edit { user-select: text; -webkit-user-select: text; }
.mc-seq-stage-edit:focus { outline: none; }

/* The provisional-frame marker. Deliberately conspicuous: it is the only
   thing distinguishing a preview that skipped the effect stack from one that
   did not. Uppercase micro-chrome, so it sits outside the 16px prose floor. */
.mc-seq-provisional { position: absolute; top: 10px; right: 10px; z-index: 3;
  pointer-events: none; display: flex; align-items: center; gap: 7px;
  padding: 6px 11px; border-radius: 999px; font-size: .7rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: #ffd9a3;
  background: rgba(5,7,13,.86); border: 1px solid rgba(255,170,80,.42);
  box-shadow: 0 2px 10px rgba(0,0,0,.45); }
.mc-seq-provisional[hidden] { display: none; }
.mc-seq-provisional::before { content: ""; width: 7px; height: 7px; flex: none;
  border-radius: 50%; background: #ffaa50; animation: mc-seq-pulse 1.4s ease-in-out infinite; }
@keyframes mc-seq-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }
@media (prefers-reduced-motion: reduce) {
  .mc-seq-provisional::before { animation: none; }
}

/* --- Text toolbar --- */
.mc-seq-text-toolbar[hidden] { display: none; }  /* the attribute alone
   loses to the display rule below, so the panel outlived its clip */
.mc-seq-text-toolbar { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px;
  background: #0d0f18; border: 1px solid var(--border); border-radius: 10px;
  padding: 10px 12px; }
.mc-seq-field { display: flex; flex-direction: column; gap: 4px; font-size: .68rem;
  text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.mc-seq-field input, .mc-seq-field select { background: #141720; color: var(--text);
  border: 1px solid var(--border); border-radius: 6px; padding: 6px 8px;
  font-size: .9rem; min-width: 74px; }
.mc-seq-field.is-color input { padding: 2px; width: 46px; min-width: 46px; height: 32px;
  cursor: pointer; }
.mc-seq-toggle-group { display: flex; gap: 4px; }
.mc-seq-toggle { width: 34px; height: 32px; background: #141720; color: var(--text);
  border: 1px solid var(--border); border-radius: 6px; cursor: pointer;
  font-size: .9rem; line-height: 1; }
.mc-seq-toggle.is-bold { font-weight: 800; }
.mc-seq-toggle.is-italic { font-style: italic; }
.mc-seq-toggle.is-on { background: var(--accent); border-color: var(--accent); color: #fff; }
.mc-seq-tb-delete { margin-left: auto; }
.mc-seq-field.is-text textarea { background: #141720; color: var(--text);
  border: 1px solid var(--border); border-radius: 6px; padding: 6px 8px;
  font: inherit; font-size: 1rem; text-transform: none; letter-spacing: normal;
  min-width: 220px; resize: vertical; }

/* --- Timeline --- */
.mc-seq-timeline { background: #0d0f18; border: 1px solid var(--border); border-radius: 10px;
  padding: 10px; }
.mc-seq-transport { display: flex; align-items: center; gap: 10px; margin-bottom: 8px;
  flex-wrap: wrap; }
.mc-seq-play { width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--border);
  background: var(--accent); color: #fff; cursor: pointer; font-size: .85rem; line-height: 1; }
.mc-seq-tbtn { height: 30px; padding: 0 10px; border-radius: 7px; cursor: pointer;
  border: 1px solid var(--border); background: #141720; color: var(--text);
  font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; line-height: 1; }
.mc-seq-tbtn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent-light); }
.mc-seq-tbtn:disabled { opacity: .38; cursor: default; }
.mc-seq-time { font-size: .95rem; color: var(--text); font-variant-numeric: tabular-nums; }
.mc-seq-rate { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em;
  padding: 2px 6px; border-radius: 5px; background: var(--accent); color: #fff; }
.mc-seq-rate[hidden] { display: none; }
.mc-seq-zoom-field, .mc-seq-snap-field { display: flex; align-items: center; gap: 6px;
  font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.mc-seq-zoom-field { margin-left: auto; }
.mc-seq-zoom-field input { width: 120px; accent-color: var(--accent); }
.mc-seq-snap-field input { accent-color: var(--accent); }
.mc-seq-layouts { display: flex; gap: 6px; flex-wrap: wrap; }

/* One scroller holds every row, so the lanes, the ruler and the playhead all
   share one horizontal offset. The head column is sticky rather than a
   separate pane — two scrollers would need syncing and would drift. */
.mc-seq-tracks { --head-w: 160px; position: relative; display: flex;
  flex-direction: column; gap: 6px; overflow-x: auto; overflow-y: hidden;
  padding-bottom: 4px; }
/* stretch, not center: the head is a full-height column beside its lane, and
   centring it leaves the row's background split by a floating label. */
.mc-seq-track { display: grid; grid-template-columns: var(--head-w) max-content;
  column-gap: 8px; align-items: stretch; }
.mc-seq-track-head { position: sticky; left: 0; z-index: 3; display: flex;
  align-items: center; gap: 4px; height: 100%; padding: 0 6px;
  background: #0d0f18; border-radius: 6px; }
.mc-seq-track-name { font-size: .68rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); margin-right: auto; font-weight: 700; }
.mc-seq-track-btn { width: 22px; height: 22px; padding: 0; border-radius: 5px;
  border: 1px solid transparent; background: transparent; color: var(--muted);
  font-size: .72rem; line-height: 1; cursor: pointer; }
.mc-seq-track-btn:hover { border-color: var(--border); color: var(--accent-light); }
.mc-seq-track-btn.is-on { color: var(--accent); border-color: var(--accent); }
.mc-seq-track-btn.is-remove:hover { color: #f87171; border-color: #f87171; }

.mc-seq-track.is-ruler { --lane-h: 20px; }
.mc-seq-ruler { position: relative; height: 20px; cursor: ew-resize;
  touch-action: none; }
.mc-seq-tick { position: absolute; top: 0; font-size: .62rem; color: var(--faint);
  white-space: nowrap; padding-top: 4px; border-left: 1px solid var(--border);
  padding-left: 3px; pointer-events: none; }

.mc-seq-lane { position: relative; height: var(--lane-h, 44px); background: #05070d;
  border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }

.mc-seq-clip { position: absolute; top: 3px; bottom: 3px; min-width: 8px;
  border-radius: 5px; font-size: .68rem; color: var(--text); display: flex;
  align-items: center; justify-content: center; cursor: grab;
  border: 1px solid #2d3748; overflow: hidden; touch-action: none; }
.mc-seq-clip:active { cursor: grabbing; }
.mc-seq-clip-label { pointer-events: none; padding: 0 10px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.mc-seq-clip.is-clip { background: linear-gradient(135deg,#1a2540,#243b6b); }
.mc-seq-clip.is-image { background: linear-gradient(135deg,#3a2540,#5b2f55); }
.mc-seq-clip.is-text, .mc-seq-clip.is-caption { background: #1b1830;
  border-style: dashed; border-color: var(--accent); color: var(--accent-light); }
.mc-seq-clip.is-audio { background: linear-gradient(135deg,#1f3a32,#2f6b55);
  color: #d7f5ea; }
.mc-seq-clip.is-selected { outline: 2px solid var(--accent); outline-offset: -2px; }
.mc-seq-clip.is-off { opacity: .45; }
/* The waveform, and the ducking envelope drawn over it. Under the label and
   under the trim handles, and never interactive: dragging the clip must work
   the same whether or not its peaks have arrived yet. */
.mc-seq-wave { position: absolute; left: 0; right: 0; top: 4px;
  width: 100%; height: calc(100% - 8px); display: block;
  pointer-events: none; opacity: .9; }
.mc-seq-clip.is-audio .mc-seq-clip-label { position: relative;
  text-shadow: 0 1px 3px rgba(0,0,0,.85); }

.mc-seq-clip-edge { position: absolute; top: 0; bottom: 0; width: 8px;
  cursor: ew-resize; background: rgba(139,108,255,.35); }
.mc-seq-clip-edge.is-start { left: 0; }
.mc-seq-clip-edge.is-end { right: 0; }

/* Overlays exactly the lane column, so the playhead's left is a true time.
   Absolute, not a grid item: as a grid item spanning column 2 it displaced the
   auto-placed lanes into the head column. */
.mc-seq-scale { position: absolute; left: calc(var(--head-w) + 8px);
  top: 0; bottom: 4px; pointer-events: none; }
.mc-seq-playhead { position: absolute; top: 0; bottom: 0; left: 0;
  width: 2px; margin-left: -1px; background: var(--accent2);
  pointer-events: auto; cursor: ew-resize; touch-action: none; z-index: 4; }
.mc-seq-playhead::before { content: ""; position: absolute; top: -2px; left: 50%;
  width: 12px; height: 12px; border-radius: 3px; background: var(--accent2);
  transform: translateX(-50%) rotate(45deg); }

/* --- Keyframes ---
   The strip's rows are built into the SAME scroller as the track lanes, so
   they inherit .mc-seq-track's grid, its sticky head column and its
   horizontal offset. That is what keeps a diamond under the clip it belongs
   to at every zoom and scroll position. */
.mc-seq-track.is-kf .mc-seq-track-name { color: var(--accent-light); }
.mc-seq-lane.is-kf { background: #080a12; border-style: dashed; overflow: visible; }
/* A guide line, so a row with one key still reads as a timeline rather than a
   floating dot. */
.mc-seq-lane.is-kf::before { content: ""; position: absolute; left: 0; right: 0;
  top: 50%; height: 1px; background: var(--border); }
.mc-seq-kf-key { position: absolute; top: 50%; width: 11px; height: 11px;
  margin: 0; background: var(--accent); border: 1px solid #05070d;
  border-radius: 2px; cursor: ew-resize; touch-action: none; z-index: 2;
  transform: translate(-50%, -50%) rotate(45deg);
  transition: background-color .12s ease-out, box-shadow .12s ease-out; }
.mc-seq-kf-key:hover { background: var(--accent-light);
  box-shadow: 0 0 0 3px var(--glow); }
.mc-seq-kf-key:focus-visible { outline: 2px solid var(--accent3);
  outline-offset: 2px; }
/* A held key steps rather than ramps, so it is drawn square rather than as a
   diamond — the shape says what the interval after it will do. */
.mc-seq-kf-key.is-hold { transform: translate(-50%, -50%); background: var(--accent3); }

/* The right-click easing menu. Fixed to the viewport so the timeline's own
   scroller cannot clip it. */
.mc-seq-kf-menu { position: fixed; z-index: 60; min-width: 190px; padding: 6px;
  display: flex; flex-direction: column; gap: 2px; background: #0d0f18;
  border: 1px solid var(--bord2); border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0,0,0,.55); }
.mc-seq-kf-menu-title { font-size: .66rem; text-transform: uppercase;
  letter-spacing: .06em; color: var(--faint); padding: 4px 8px 6px; }
.mc-seq-kf-menu-item { text-align: left; padding: 7px 10px; border-radius: 7px;
  border: 1px solid transparent; background: transparent; color: var(--text);
  font: inherit; font-size: .95rem; cursor: pointer; }
.mc-seq-kf-menu-item:hover { background: #141720; border-color: var(--border); }
.mc-seq-kf-menu-item.is-on { color: var(--accent-light); font-weight: 700; }
.mc-seq-kf-menu-item.is-danger { color: #fc8181; margin-top: 4px;
  border-top: 1px solid var(--border); border-radius: 0 0 7px 7px; }

/* The stopwatch that turns one parameter into an animated one. */
.mc-seq-field.is-keyable { display: flex; flex-direction: column; gap: 4px; }
.mc-seq-field-head { display: flex; align-items: center; gap: 6px; }
.mc-seq-field.is-keyable .mc-seq-field-head span { margin-right: auto; }
.mc-seq-stopwatch { width: 22px; height: 22px; flex: none; padding: 0;
  border-radius: 5px; border: 1px solid var(--border); background: transparent;
  color: var(--faint); font-size: .7rem; line-height: 1; cursor: pointer;
  transition: color .12s ease-out, border-color .12s ease-out; }
.mc-seq-stopwatch:hover { color: var(--accent-light); border-color: var(--accent); }
.mc-seq-stopwatch.is-on { color: var(--accent); border-color: var(--accent);
  background: rgba(139,108,255,.14); }
.mc-seq-field.is-animated input { border-color: rgba(139,108,255,.55); }
/* Below the rules it overrides: an equal-specificity `transition` further down
   the sheet would otherwise win and the motion would ship anyway. */
@media (prefers-reduced-motion: reduce) {
  .mc-seq-kf-key, .mc-seq-stopwatch { transition: none; }
}

/* The grading, effects and mask panels can make this column far taller than
   the stage area it sits in, so the inspector scrolls in its own box rather
   than pushing the preview and the timeline off the screen. Capped, never
   `100vh` — the app shell's brand credit stays reachable. */
.mc-seq-inspector { background: #0d0f18; border: 1px solid var(--border); border-radius: 10px;
  padding: 12px; flex: none; max-height: 42vh; overflow-y: auto;
  overscroll-behavior: contain; }
.mc-seq-inspector-title { font-size: .68rem; text-transform: uppercase;
  letter-spacing: .05em; color: var(--muted); margin-bottom: 10px; }
.mc-seq-inspector-grid { display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
.mc-seq-inspector-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.mc-seq-inspector input, .mc-seq-inspector select { width: 100%; }

/* ===== The grading, effects and mask panels =====
   Three collapsible sections under the inspector's own grid. They are shut by
   default: a grade, an effect stack and a mask are all deep controls, and a
   fully expanded inspector would bury the start/duration/speed fields every
   clip needs. */
.mc-seq-panel { margin-top: 12px; border: 1px solid var(--border);
  border-radius: 10px; background: #0a0c14; overflow: hidden; }
.mc-seq-panel.is-open { border-color: var(--bord2); }
.mc-seq-panel-head { display: flex; align-items: stretch; gap: 8px;
  padding: 0 10px 0 0; }
.mc-seq-panel-toggle { flex: 1; display: flex; align-items: center; gap: 8px;
  padding: 11px 12px; background: transparent; border: 0; color: var(--text);
  font: inherit; text-align: left; cursor: pointer; }
.mc-seq-panel-toggle:hover { background: rgba(255,255,255,.03); }
.mc-seq-panel-toggle:focus-visible { outline: 2px solid var(--accent3);
  outline-offset: -2px; }
.mc-seq-panel-caret { width: 12px; flex: none; color: var(--faint);
  font-size: .8rem; line-height: 1; }
/* Uppercase micro-chrome — a section eyebrow, not prose, so it sits outside
   the 16px body floor along with the field labels and the toggle group. */
.mc-seq-panel-name { font-size: .78rem; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; }
.mc-seq-panel-state { margin-left: auto; font-size: .72rem; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.mc-seq-panel-action { align-self: center; padding: 6px 12px; font-size: .85rem; }
.mc-seq-panel-action:disabled { opacity: .4; cursor: default; }
.mc-seq-panel-body { display: flex; flex-direction: column; gap: 14px;
  padding: 4px 12px 14px; border-top: 1px solid var(--border); }
.mc-seq-panel-grid { display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
/* Prose the user is meant to read: 16px floor, generous leading. */
.mc-seq-panel-note { margin: 0; font-size: 1rem; line-height: 1.55;
  color: var(--dim); text-transform: none; letter-spacing: normal; }
.mc-seq-subhead { font-size: .72rem; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); }

/* ===== The audio panel and captions =====
   A duck is the one edit a user cannot see: they hear that something changed
   and have no picture of what. The cyan the envelope is stroked in on the lane
   is the cyan this panel names it in, so the control and the drawing read as
   the same thing. */
.mc-seq-field-head { display: flex; align-items: baseline;
  justify-content: space-between; gap: 8px; }
/* A live numeric readout, not prose — it sits with the field labels outside
   the 16px body floor. */
.mc-seq-readout { font-size: .78rem; font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--text); }
.mc-seq-panel-note.is-warn { color: #f8b4b4; }
.mc-seq-panel-note.is-status { color: var(--text); }
/* The caption style toggle needs room for two words, not a 30px square. */
.mc-seq-panel-body .mc-seq-toggle-group { display: flex; flex-wrap: wrap; gap: 8px; }

/* --- sliders --- */
.mc-seq-slider-row { display: flex; align-items: center; gap: 8px; }
.mc-seq-slider { flex: 1; min-width: 0; width: auto; accent-color: var(--accent);
  cursor: pointer; }
.mc-seq-slider-value { width: 70px; min-width: 70px; flex: none; }
.mc-seq-slider-value.is-wide { width: 100%; min-width: 0; }
.mc-seq-field.is-vector { gap: 6px; }
.mc-seq-vector-lane { display: flex; align-items: center; gap: 8px; }
.mc-seq-vector-tag { width: 14px; flex: none; font-size: .72rem; font-weight: 800;
  color: var(--faint); }
.mc-seq-field.is-flag { flex-direction: row; align-items: center; gap: 8px;
  font-size: 1rem; text-transform: none; letter-spacing: normal;
  color: var(--text); cursor: pointer; }
.mc-seq-field.is-flag input { width: auto; min-width: 0; accent-color: var(--accent); }
/* Scoped to the panel body so `.mc-seq-fx .mc-seq-toggle` further down, which
   has the same specificity, cannot silently win and squeeze a channel button
   back to 30px. */
.mc-seq-panel-body .mc-seq-toggle.is-wide { width: auto; min-width: 62px;
  padding: 0 10px; font-size: .8rem; font-weight: 700; }

/* --- the curve editor ---
   The graph is an SVG, NOT a second canvas: it lives in the inspector, so it
   could never reach the exported frame, and DOM control points are focusable
   and hit-testable for free. */
.mc-seq-curves { display: flex; flex-direction: column; gap: 8px; }
.mc-seq-curves-head { display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap; }
.mc-seq-curve-graph { display: block; width: 100%; max-width: 320px;
  aspect-ratio: 1; background: #05070d; border: 1px solid var(--border);
  border-radius: 8px; touch-action: none;
  user-select: none; -webkit-user-select: none; }
.mc-seq-curve-grid { stroke: rgba(255,255,255,.06); stroke-width: 1; }
.mc-seq-curve-diagonal { stroke: rgba(255,255,255,.13); stroke-width: 1;
  stroke-dasharray: 4 5; }
.mc-seq-curve-line { fill: none; stroke: var(--text); stroke-width: 2;
  stroke-linejoin: round; }
.mc-seq-curve-line.is-r { stroke: #ff6b6b; }
.mc-seq-curve-line.is-g { stroke: #57d98a; }
.mc-seq-curve-line.is-b { stroke: #5aa9ff; }
.mc-seq-curve-dot { fill: var(--accent); stroke: #05070d; stroke-width: 2;
  cursor: grab; }
.mc-seq-curve-dot:hover { fill: var(--accent-light); }
.mc-seq-curve-dot:focus-visible { outline: 2px solid var(--accent3);
  outline-offset: 2px; }
.mc-seq-curves-foot { display: flex; align-items: center; gap: 12px;
  flex-wrap: wrap; }
.mc-seq-curves-foot .mc-seq-panel-note { flex: 1; min-width: 180px; }

/* --- the LUT picker --- */
.mc-seq-lut { display: flex; flex-direction: column; gap: 8px; }
.mc-seq-lut-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.mc-seq-lut-name { flex: 1; min-width: 140px; font-size: 1rem;
  color: var(--dim); overflow-wrap: anywhere; }
.mc-seq-lut .mc-btn { flex: none; }
/* The library select. Deliberately the same control as `.mc-seq-fx-add
   select` — same ground, border, radius and size — because it is the same
   gesture one panel away: pick a thing from a list. A second treatment here
   would read as a different kind of control for no reason. */
.mc-seq-lut-choose { flex: 1; min-width: 160px; background: #141720;
  color: var(--text); border: 1px solid var(--border); border-radius: 6px;
  padding: 7px 8px; font-size: .95rem; cursor: pointer; }
.mc-seq-lut-choose:focus-visible { outline: 2px solid var(--accent3);
  outline-offset: 2px; }

/* --- the effect stack --- */
.mc-seq-fx-add { display: flex; align-items: center; gap: 8px; }
.mc-seq-fx-add select { flex: 1; background: #141720; color: var(--text);
  border: 1px solid var(--border); border-radius: 6px; padding: 7px 8px;
  font-size: .95rem; }
.mc-seq-fx-add .mc-btn { flex: none; }
.mc-seq-fx { display: flex; flex-direction: column; gap: 10px; padding: 10px;
  background: #0d0f18; border: 1px solid var(--border); border-radius: 8px; }
/* A disabled entry stays in the list, in its place in the order — the order is
   the render contract, so hiding it would misdescribe the stack. */
.mc-seq-fx.is-off { opacity: .5; }
.mc-seq-fx-head { display: flex; align-items: center; gap: 6px; }
.mc-seq-fx-enable { display: flex; align-items: center; gap: 7px; flex: 1;
  font-size: 1rem; cursor: pointer; }
.mc-seq-fx-enable input { width: auto; min-width: 0; accent-color: var(--accent); }
.mc-seq-fx-remove { margin-left: auto; color: #fc8181; }
.mc-seq-fx .mc-seq-toggle { width: 30px; height: 28px; font-size: .8rem; }
.mc-seq-fx .mc-seq-toggle:disabled { opacity: .3; cursor: default; }

/* --- mask chrome on the stage overlay ---
   Positioned over the SELECTED LAYER's rect, not the stage: mask points are
   fractions of the fitted layer, because the mask runs before the transform.
   Nothing here is ever drawn into #mc-seq-canvas, which is the frame the
   renderer exports. */
.mc-seq-mask-layer { position: absolute; pointer-events: none; }
.mc-seq-mask-svg { position: absolute; inset: 0; width: 100%; height: 100%;
  overflow: visible; pointer-events: none; }
.mc-seq-mask-shape { fill: none; stroke: var(--accent3); stroke-width: 1.5;
  stroke-dasharray: 6 4; }
.mc-seq-mask-pt { position: absolute; width: 13px; height: 13px; padding: 0;
  transform: translate(-50%, -50%); pointer-events: auto; cursor: grab;
  background: var(--accent3); border: 1px solid #05070d; border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0,0,0,.6); touch-action: none; }
.mc-seq-mask-pt:hover { background: #fff; }
.mc-seq-mask-pt:focus-visible { outline: 2px solid var(--accent);
  outline-offset: 2px; }
/* While the pen is armed the next click on the stage places a vertex, so the
   cursor has to say so before the click rather than after it. */
.mc-seq-stage.is-pen { cursor: crosshair; }

@media (max-width: 1024px) {
  .mc-seq-bin { grid-template-columns: 1fr 1fr 1fr; }
  .mc-view-seq.mc-active { gap: 8px; }
  .mc-seq-preview { min-height: 170px; }
  .mc-seq-tracks { --head-w: 116px; }
  .mc-seq-zoom-field input { width: 90px; }
  /* One control per row from tablet down: a 190px minimum column would other-
     wise squeeze a slider and its number field into about 60px each. */
  .mc-seq-panel-grid { grid-template-columns: 1fr; }
  .mc-seq-curve-graph { max-width: 100%; }
  /* Fingers, not a mouse: the vertex handles get a touch-sized target. */
  .mc-seq-mask-pt { width: 18px; height: 18px; }
  /* The index becomes a stack of cards below tablet: five columns inside a
     320px lane is five unreadable columns, not a table. */
  .mc-seq-index-row { grid-template-columns: 1fr; gap: 2px; }
  .mc-seq-index-row .mc-seq-index-when { justify-self: start; }
}

/* ===== The pro-workflow panels (slice 4) =====
   Export, interchange, reframe, the sequence index and the titles menu act on
   the SEQUENCE, so they sit under the timeline rather than in the inspector,
   which rebuilds itself around whichever clip is selected.

   They are <details>, unlike the inspector's panels, for one concrete reason:
   nothing tears this subtree down on a commit, so the element can hold its own
   open state. The inspector cannot, which is why `panel()` keeps openness in
   module state instead. */
.mc-seq-workflow { display: flex; flex-direction: column; gap: 10px; flex: none; }
.mc-seq-workflow .mc-seq-panel { margin-top: 0; }
summary.mc-seq-panel-head { align-items: center; gap: 8px; padding: 11px 12px;
  cursor: pointer; list-style: none; }
summary.mc-seq-panel-head::-webkit-details-marker { display: none; }
summary.mc-seq-panel-head:hover { background: rgba(255,255,255,.03); }
summary.mc-seq-panel-head:focus-visible { outline: 2px solid var(--accent3);
  outline-offset: -2px; }
.mc-seq-workflow .mc-seq-panel-caret { display: inline-block;
  transition: transform 180ms cubic-bezier(.2,.8,.3,1); }
.mc-seq-workflow details[open] > summary .mc-seq-panel-caret { transform: rotate(90deg); }
/* Anything the user types here is read at length, so it clears the body floor
   rather than sitting at the toolbar's 14px. */
.mc-seq-workflow .mc-seq-field input,
.mc-seq-workflow .mc-seq-field select { font-size: 1rem; width: 100%; }
.mc-seq-workflow .mc-btn { font-size: 1rem; }

/* --- the render queue --- */
.mc-seq-jobs { display: flex; flex-direction: column; gap: 8px; }
.mc-seq-jobs:empty::after { content: "Nothing queued."; color: var(--faint);
  font-size: 1rem; }
.mc-seq-job { border: 1px solid var(--border); border-radius: 8px;
  background: #0d0f18; padding: 10px 12px; display: flex;
  flex-direction: column; gap: 6px; }
.mc-seq-job-head { display: flex; align-items: baseline; gap: 8px; }
.mc-seq-job-name { font-size: 1rem; line-height: 1.4; color: var(--text);
  overflow-wrap: anywhere; }
.mc-seq-job-status { margin-left: auto; flex: none; font-size: .72rem;
  font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted); }
.mc-seq-job.is-done .mc-seq-job-status { color: var(--accent3); }
.mc-seq-job.is-failed .mc-seq-job-status { color: #f8b4b4; }
.mc-seq-job-bar { height: 4px; border-radius: 999px; background: var(--bg3);
  overflow: hidden; }
.mc-seq-job-bar span { display: block; height: 100%; background: var(--accent);
  transition: width 320ms cubic-bezier(.2,.8,.3,1); }
.mc-seq-job-foot { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.mc-seq-job-est { font-size: .875rem; color: var(--dim); }
.mc-seq-job-foot .mc-btn { margin-left: auto; padding: 5px 12px; font-size: .875rem; }
.mc-seq-job-foot a.mc-btn { text-decoration: none; }

/* --- the dropped-feature report ---
   Shown ABOVE the download button, never after it: the entire point is that
   the loss is visible before the file leaves. */
.mc-seq-dropped { border: 1px solid var(--bord2); border-radius: 8px;
  background: #0d0f18; padding: 10px 12px; display: flex;
  flex-direction: column; gap: 6px; }
.mc-seq-dropped[hidden] { display: none; }
.mc-seq-dropped-head { font-size: 1rem; line-height: 1.5; color: var(--text); }
.mc-seq-dropped.is-clean { border-color: var(--border); }
.mc-seq-dropped.is-clean .mc-seq-dropped-head { color: var(--accent3); }
.mc-seq-dropped-list { margin: 0; padding-left: 18px; display: flex;
  flex-direction: column; gap: 3px; }
.mc-seq-dropped-list li { font-size: 1rem; line-height: 1.5; color: var(--dim);
  overflow-wrap: anywhere; }
.mc-seq-download[hidden] { display: none; }
.mc-seq-download { align-self: flex-start; text-decoration: none; }

/* --- the sequence index --- */
.mc-seq-index { display: flex; flex-direction: column; gap: 4px;
  max-height: 32vh; overflow-y: auto; overscroll-behavior: contain; }
.mc-seq-index:empty::after { content: "No clip matches that."; color: var(--faint);
  font-size: 1rem; }
.mc-seq-index-row { display: grid; align-items: baseline; gap: 4px 10px;
  grid-template-columns: 46px minmax(0, 1fr) auto;
  width: 100%; text-align: left; background: transparent; color: var(--text);
  border: 1px solid transparent; border-radius: 8px; padding: 8px 10px;
  font: inherit; cursor: pointer; }
.mc-seq-index-row:hover { background: rgba(255,255,255,.04);
  border-color: var(--border); }
.mc-seq-index-row:focus-visible { outline: 2px solid var(--accent3);
  outline-offset: -2px; }
.mc-seq-index-row.is-selected { border-color: var(--accent);
  background: rgba(139,108,255,.12); }
.mc-seq-index-track { font-size: .72rem; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: var(--faint); }
.mc-seq-index-name { font-size: 1rem; line-height: 1.45; overflow-wrap: anywhere; }
.mc-seq-index-when { font-size: .875rem; color: var(--dim);
  font-variant-numeric: tabular-nums; justify-self: end; }
.mc-seq-index-tags { grid-column: 2 / -1; display: flex; flex-wrap: wrap; gap: 4px; }
.mc-seq-index-tag { font-size: .68rem; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: var(--accent3);
  border: 1px solid rgba(79,214,255,.35); border-radius: 999px;
  padding: 1px 7px; }

@media (prefers-reduced-motion: reduce) {
  .mc-seq-workflow .mc-seq-panel-caret,
  .mc-seq-job-bar span { transition: none; }
}

.mc-export-wrap { position: relative; display: inline-block; }
.mc-export-menu { position: absolute; right: 0; top: calc(100% + 4px); display: flex; flex-direction: column; gap: 4px; background: #0d0f18; border: 1px solid #1e2535; border-radius: 8px; padding: 6px; z-index: 50; }
.mc-export-menu[hidden] { display: none; }

.mc-upload-btn { display: inline-block; text-align: center; cursor: pointer; }
.mc-upload-btn input { display: none; }

/* ===== Halo shell layout (Slice 1) ===== */
.halo-root { display:flex; flex-direction:column; height:100vh; height:100dvh; }
.halo-topbar { height:58px; flex:none; display:flex; align-items:center; gap:18px; padding:0 18px; background:var(--bg1); border-bottom:1px solid var(--border); }
.halo-brand { display:flex; align-items:center; gap:10px; }
.halo-mark { width:30px; height:30px; border-radius:9px; background:var(--grad); box-shadow:0 0 18px var(--glow); }
.halo-word { font-family:var(--font-display); font-weight:700; font-size:19px; letter-spacing:-0.02em; }
.halo-nav { display:flex; gap:4px; background:var(--bg2); border:1px solid var(--border); border-radius:12px; padding:4px; }
.halo-nav-btn { padding:7px 15px; border:none; background:transparent; color:var(--dim); border-radius:9px; font-size:14px; font-weight:600; cursor:pointer; }
.halo-nav-btn.halo-active { background:var(--bg3); color:var(--text); }
.halo-spacer { flex:1; }
.halo-topbar-actions { display:flex; align-items:center; gap:8px; }
.halo-avatar { width:32px; height:32px; border-radius:50%; background:var(--grad); flex:none; }

.halo-view { display:none; flex:1; min-height:0; }
.halo-view.halo-active { display:flex; }
.halo-stub { margin:auto; text-align:center; color:var(--dim); }
.halo-stub h1 { font-family:var(--font-display); color:var(--text); }

/* min-width:0 is the companion to min-height:0 here: .halo-editor is a row
   flex item, so without it its min-content width (rail + panel + the full
   canvas + inspector) wins over its flex basis and the whole editor scrolls
   the page sideways instead of the stage scrolling inside itself. */
.halo-editor { flex:1; display:flex; min-height:0; min-width:0; background:var(--bg0); }
.halo-rail { width:60px; flex:none; background:var(--bg1); border-right:1px solid var(--border); display:flex; flex-direction:column; align-items:center; gap:6px; padding:12px 0; }
.halo-tool { width:40px; height:40px; border:none; background:transparent; color:var(--dim); border-radius:10px; font-size:18px; cursor:pointer; }
.halo-tool:hover { background:var(--bg3); color:var(--text); }
.halo-tool.halo-active { background:var(--bg3); color:var(--accent); }
.halo-panel { width:312px; flex:none; background:var(--bg1); border-right:1px solid var(--border); overflow-y:auto; padding:18px; }
.halo-ctx-title { font-family:var(--font-display); font-size:17px; font-weight:700; margin:0 0 14px; }
.halo-ctx-sub { font-size:11px; font-weight:700; color:var(--faint); text-transform:uppercase; letter-spacing:0.08em; margin:14px 0 10px; }
.halo-field { display:block; font-size:11px; color:var(--faint); margin-bottom:10px; }
.halo-block { width:100%; margin-top:12px; }
.halo-shape-grid { display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-bottom:14px; }
.halo-shape-card { aspect-ratio:1/1; background:var(--bg2); border:1px solid var(--border); border-radius:12px; display:flex; align-items:center; justify-content:center; cursor:pointer; }
.halo-shape-rect { width:48px; height:48px; background:var(--accent); border-radius:8px; }
.halo-shape-ell { width:48px; height:48px; background:var(--accent2); border-radius:50%; }
.halo-template-grid { display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-bottom:14px; }
.halo-template-card { background:var(--bg2); border:1px solid var(--border); border-radius:12px; padding:10px; cursor:pointer; display:flex; flex-direction:column; gap:8px; align-items:center; }
.halo-template-card:hover { border-color:var(--accent-light); }
.halo-template-swatch { width:100%; background:linear-gradient(135deg, var(--accent), var(--accent2)); border-radius:8px; }
.halo-template-name { font-size:14px; font-weight:600; color:var(--dim); text-align:center; }

.halo-stage-area { flex:1; min-width:0; position:relative; display:flex; overflow:auto; background:radial-gradient(circle at 50% 40%, var(--bg1), var(--bg0)); }
.halo-canvas-frame { margin:auto; position:relative; }
.halo-size-readout { position:absolute; right:14px; bottom:14px; font-family:'Space Mono',monospace; font-size:11px; color:var(--faint); background:var(--bg2); border:1px solid var(--border); padding:6px 11px; border-radius:9px; }
.halo-zoom { position:absolute; left:14px; bottom:14px; display:flex; align-items:center; gap:6px; background:var(--bg2); border:1px solid var(--border); border-radius:11px; padding:4px 8px; color:var(--dim); }
.halo-zoom-btn { cursor:default; opacity:0.5; }
.halo-zoom-pct { font-size:12px; font-weight:600; }

.halo-inspector { width:286px; flex:none; background:var(--bg1); border-left:1px solid var(--border); padding:16px; overflow-y:auto; }
.halo-inspector-props { border-top:1px solid var(--border); padding-top:14px; }

/* .mc-view visibility/flex is governed by the original rules above
   (.mc-view + .mc-view.mc-active = display:flex; flex-direction:column); the new
   shell relies on that flex sizing for .mc-canvas-wrap / sequencer panes, so it is
   intentionally NOT re-declared here. */

/* ===== Halo control restyle (Slice 1) ===== */
.halo-panel textarea, .halo-panel select, .halo-panel input[type="text"] {
  width:100%; background:var(--bg2); border:1px solid var(--border); border-radius:12px;
  padding:11px 12px; font-size:16px; color:var(--text); font-family:var(--font-ui);
}
.halo-panel textarea { height:96px; resize:none; line-height:1.5; }
.halo-field select { margin-top:6px; cursor:pointer; }
.mc-btn { background:var(--bg2); border:1px solid var(--border); color:var(--text); border-radius:10px; padding:9px 14px; font-size:15px; font-weight:600; cursor:pointer; font-family:var(--font-ui); }
.mc-btn:hover { border-color:var(--bord2); }
.mc-btn.mc-active { border-color:var(--accent); color:var(--accent); }
.mc-btn-primary { background:var(--accent); border-color:transparent; color:var(--onAccent); box-shadow:0 0 22px var(--glow); }
/* The narration action, deliberately NOT a twin of "+ Add text". It lives HERE,
   in the theme layer, and not beside the sequencer rules 600 lines up: the
   .mc-btn above restates background and border, so an earlier .mc-btn-voice of
   equal specificity loses to it and renders as a plain button. Accent-tinted
   rather than solid — solid --accent is the one-per-view primary (Generate
   Clip, Export PNG) and a second solid button would compete with it. */
.mc-btn-voice { display:flex; align-items:center; justify-content:center; gap:8px;
  width:100%; background:color-mix(in oklch, var(--accent) 16%, var(--bg2));
  border-color:color-mix(in oklch, var(--accent) 45%, transparent);
  transition:background .16s ease-out, border-color .16s ease-out; }
.mc-btn-voice:hover { background:color-mix(in oklch, var(--accent) 26%, var(--bg2));
  border-color:var(--accent); }
@media (prefers-reduced-motion: reduce) { .mc-btn-voice { transition:none; } }
.mc-btn-danger { color:var(--accent2); }
.mc-hint { color:var(--faint); font-size:16px; line-height:1.6; }
.mc-library { display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:12px; }
.mc-library img { width:100%; border-radius:10px; display:block; cursor:pointer; }
.mc-credit { position:fixed; bottom:0; left:0; right:0; text-align:center; padding:10px 0 calc(10px + env(safe-area-inset-bottom)); background:var(--bg1); border-top:1px solid var(--border); }
.mc-credit a { color:var(--faint); font-size:14px; text-decoration:none; opacity:0.8; }

/* ===== Halo layers + properties (Slice 2) ===== */
.halo-text-card { display:block; width:100%; text-align:left; background:var(--bg2); border:1px solid var(--border); border-radius:12px; padding:16px; margin-bottom:10px; color:var(--text); cursor:pointer; font-family:var(--font-ui); }
.halo-text-card:hover { border-color:var(--bord2); }
.halo-text-heading { font-family:var(--font-display); font-size:28px; font-weight:700; }
.mc-layers { display:flex; flex-direction:column; gap:3px; max-height:40vh; overflow-y:auto; }
.mc-layer-row { display:flex; align-items:center; gap:8px; padding:7px 8px; border-radius:9px; cursor:pointer; }
.mc-layer-row:hover { background:var(--bg2); }
.mc-layer-row.mc-selected { background:var(--bg3); }
.mc-layer-name { flex:1; min-width:0; font-size:14px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mc-layer-type { font-size:10px; color:var(--faint); }
.mc-layer-row button { background:none; border:none; color:var(--faint); cursor:pointer; font-size:12px; padding:2px; }
.mc-layer-row button:hover { color:var(--text); }
.mc-props { font-size:14px; }
.mc-prop-row { display:flex; gap:8px; margin-bottom:10px; }
.mc-prop-row label, .mc-prop-full { flex:1; display:block; font-size:13px; color:var(--faint); }
.mc-prop-full { margin-bottom:12px; }
.mc-props input[type="number"], .mc-props textarea { width:100%; margin-top:4px; background:var(--bg2); border:1px solid var(--border); border-radius:8px; padding:7px 9px; font-size:16px; color:var(--text); }
.mc-props input[type="color"] { width:44px; height:34px; margin-top:4px; background:var(--bg2); border:1px solid var(--border); border-radius:8px; cursor:pointer; }
.mc-props textarea { height:64px; resize:none; }
.mc-text-overlay { position:absolute; z-index:30; background:rgba(10,10,17,0.96); color:#fff; border:1px solid var(--accent); border-radius:6px; padding:4px; resize:none; outline:none; font-family:var(--font-ui); }

/* ===== Halo projects gallery (Slice 3) ===== */
.halo-projects { width:100%; max-width:1180px; margin:0 auto; padding:44px 32px 80px; }
.halo-projects-head { display:flex; align-items:center; justify-content:space-between; margin-bottom:24px; }
.halo-projects-head h1 { font-family:var(--font-display); font-size:32px; margin:0; }
.mc-projects-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(240px, 1fr)); gap:22px; }
.mc-project-card { cursor:pointer; }
.mc-project-thumb { aspect-ratio:4/3; border-radius:12px; background-size:cover; background-position:center; border:1px solid var(--border); }
.mc-project-card:hover .mc-project-thumb { filter:brightness(1.08); }
.mc-project-name { font-size:16px; font-weight:600; margin-top:11px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mc-project-edited { font-size:14px; color:var(--faint); margin-top:3px; }

/* ===== Halo explore gallery (Slice 4) ===== */
.halo-explore { width:100%; max-width:1180px; margin:0 auto; padding:44px 32px 80px; }
.halo-explore-head { margin-bottom:24px; }
.halo-explore-head h1 { font-family:var(--font-display); font-size:32px; margin:0 0 4px; }
.mc-explore-grid { column-width:240px; column-gap:18px; }
.mc-explore-tile { position:relative; break-inside:avoid; margin-bottom:18px; border-radius:12px; overflow:hidden; cursor:pointer; border:1px solid var(--border); }
.mc-explore-tile img { display:block; width:100%; }
.mc-explore-overlay { position:absolute; inset:0; display:flex; flex-direction:column; justify-content:flex-end; gap:8px; padding:14px; background:linear-gradient(0deg, rgba(0,0,0,0.78), rgba(0,0,0,0) 55%); opacity:0; transition:opacity .2s; }
.mc-explore-tile:hover .mc-explore-overlay { opacity:1; }
.mc-explore-prompt { font-size:16px; line-height:1.55; color:#fff; }
.mc-explore-open { align-self:flex-start; font-size:13px; font-weight:600; color:#fff; background:rgba(255,255,255,0.18); backdrop-filter:blur(4px); padding:3px 9px; border-radius:999px; }

/* ===== Video panel: control row + frame thumbnail dropdowns ===== */
.mc-video-controls { display:flex; gap:10px; margin-top:12px; }
.mc-video-controls .halo-field { flex:1; min-width:0; margin-bottom:0; }
.mc-video-controls .halo-field[hidden] { display:none; }
.mc-video-controls select { margin-top:6px; }

.mc-pic-row { display:flex; gap:12px; margin-top:14px; }
.mc-pic-row[hidden] { display:none; }
.mc-pic-dd { position:relative; flex:1; min-width:0; }
.mc-pic-dd[hidden] { display:none; }
/* Standalone reference picker in the AI panel gets its own vertical spacing
   (in the video pic-row the flex gap handles this instead). */
#mc-ref-pic { margin:10px 0; }
.mc-ref-clear { margin-top:6px; font-size:0.72rem; padding:4px 10px; }
.mc-pic-dd-cap { display:block; font-size:11px; color:var(--faint); margin-bottom:6px; }
.mc-pic-dd-cap em { font-style:normal; opacity:0.7; }
.mc-pic-dd-trigger {
  width:100%; display:flex; align-items:center; gap:8px;
  background:var(--bg2); border:1px solid var(--border); border-radius:12px;
  padding:7px 9px; cursor:pointer; color:var(--text); font-family:var(--font-ui);
  font-size:13px; text-align:left;
}
.mc-pic-dd-trigger:hover { border-color:var(--bord2); }
.mc-pic-dd.mc-open .mc-pic-dd-trigger { border-color:var(--accent); }
.mc-pic-dd-thumb {
  flex:none; width:30px; height:30px; border-radius:7px; background:var(--bg3);
  background-size:cover; background-position:center; border:1px solid var(--border);
}
.mc-pic-dd-thumb.mc-pic-dd-has { border-color:var(--accent); }
.mc-pic-dd-text { flex:1; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.mc-pic-dd-caret { flex:none; color:var(--faint); font-size:11px; }
.mc-pic-dd.mc-open .mc-pic-dd-caret { color:var(--accent); }
.mc-pic-dd-menu {
  position:absolute; z-index:40; top:calc(100% + 6px); left:0; right:0;
  background:var(--bg1); border:1px solid var(--bord2); border-radius:12px;
  padding:10px; box-shadow:0 14px 34px rgba(0,0,0,0.5); max-height:260px; overflow-y:auto;
}
.mc-pic-dd-grid { display:grid; grid-template-columns:1fr 1fr; gap:8px; }
.mc-pic-dd-grid img { width:100%; aspect-ratio:1/1; object-fit:cover; border-radius:8px;
  display:block; cursor:pointer; border:2px solid transparent; }
.mc-pic-dd-grid img:hover { border-color:var(--accent); }
.mc-pic-dd-empty { grid-column:1 / -1; font-size:12px; color:var(--faint); padding:8px 4px; }

/* The clip-to-extend picker uses <video> tiles instead of <img> -- the SAME
   box treatment, so it reads as one picker family rather than a bolted-on
   second kind of control. Muted/no controls: these are picker thumbnails,
   not a playable clip. */
.mc-pic-dd-grid video { width:100%; aspect-ratio:1/1; object-fit:cover; border-radius:8px;
  display:block; cursor:pointer; border:2px solid transparent; background:var(--bg3); }
.mc-pic-dd-grid video:hover { border-color:var(--accent); }
.mc-pic-dd-thumb video { width:100%; height:100%; object-fit:cover; border-radius:6px; display:block; }

/* ===== Halo mobile responsive layout (Slice 6a) =====
   Must come after every desktop .halo-* rule above: at matching specificity,
   CSS source order (not media-query position) decides the winner once a
   media query's condition is true, so an override placed before its
   unconditional desktop counterpart would silently lose the cascade. */
@media (max-width: 1024px) {
  #mc-mobile-nav { display: flex; position: fixed; bottom: 0; left: 0; right: 0;
    height: calc(60px + env(safe-area-inset-bottom)); background: #0a0c14;
    border-top: 1px solid var(--border); padding-bottom: env(safe-area-inset-bottom);
    /* Above the bottom sheets (z-index 1080): a closed sheet is only pushed
       down by its own height, which lands it exactly on top of this bar and
       hid the tabs entirely. Open sheets are anchored above the bar, so
       nothing is covered either way. */
    z-index: 1090; }
  .mc-tab { flex: 1; background: none; border: none; color: var(--muted);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px; font-size: .58rem; text-transform: uppercase; font-weight: 700;
    letter-spacing: .05em; cursor: pointer; }
  .mc-tab span { font-size: 1.15rem; }
  .mc-tab:hover { color: var(--accent-light); }
  .mc-tab.mc-active { color: var(--accent); }
  .mc-credit { bottom: calc(60px + env(safe-area-inset-bottom)); }
  .mc-edit-overlay { position: static; width: auto; max-height: none; margin-top: 12px; }

  .halo-nav { display: none; }
  /* The editor is a row on desktop (rail | panel | stage | inspector). On
     mobile the rail becomes a horizontal strip and the panels become bottom
     sheets, which only works if the editor itself stacks — left as a row, the
     toggles and rail consumed the full width and the stage was sized to 0. */
  .halo-editor { flex-direction: column; }
  /* Five actions plus the account email never fit a phone width, and they were
     wrapping into three-line buttons ("Save as / Copy", "Log / out") that
     doubled the topbar height. Keep each label on one line and let the row
     scroll sideways instead; the email is redundant here since it is also in
     the account menu. */
  .halo-topbar { gap: 12px; padding: 0 12px; }
  .halo-topbar-actions { flex: 1; min-width: 0; overflow-x: auto; scrollbar-width: none; }
  .halo-topbar-actions::-webkit-scrollbar { display: none; }
  .halo-topbar .mc-btn { white-space: nowrap; flex: none; }
  .halo-topbar .mc-account-email { display: none; }
  .mc-account-menu { flex: none; }
  .halo-mobile-toggles { display: flex; flex: none; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--border); }
  .halo-editor { padding-bottom: calc(60px + env(safe-area-inset-bottom)); }
  .halo-rail { flex-direction: row; width: auto; height: 56px; flex: none; border-right: none;
    border-bottom: 1px solid var(--border); overflow-x: auto; padding: 0 8px; }
  .halo-panel, .halo-inspector {
    position: fixed; left: 0; right: 0; bottom: calc(60px + env(safe-area-inset-bottom));
    width: auto; max-height: 60vh; border: none; border-top: 1px solid var(--border);
    border-radius: 16px 16px 0 0; transform: translateY(100%); transition: transform .25s ease;
    z-index: 1080;
  }
  .halo-panel.mc-sheet-open, .halo-inspector.mc-sheet-open { transform: translateY(0); }
  .mc-sheet-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.55); z-index: 1070; }
}

.mc-account-menu {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.mc-account-email {
  font-size: 0.875rem;
  color: var(--muted, #8b8fa3);
}

.mc-verify-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 0.5rem 1rem;
  background: #3a2f1a;
  color: #f0c987;
  font-size: 1rem;
  line-height: 1.5;
}

/* ===== Token balance badge (logged-in shell only) ===== */
.mc-token-badge {
  display: inline-flex; align-items: baseline; gap: 6px; text-decoration: none;
  padding: 6px 12px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--bg2); color: var(--text);
}
.mc-token-badge:hover { border-color: var(--accent); }
.mc-token-badge-value { font-size: 15px; font-weight: 700; }
.mc-token-badge-label {
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--faint);
}
/* "Unknown" is styled as muted rather than as an alarm: a token-service
   outage is not the same as an empty wallet. */
.mc-balance-unknown .mc-token-badge-value { color: var(--faint); }
.mc-balance-low .mc-token-badge-value { color: #f0c987; }
.mc-balance-zero .mc-token-badge-value { color: var(--accent2); }

/* ===== The voice-over strip =====
   A narration block is an ordinary audio clip, so it inherits the audio
   lane's waveform, its ducking overlay and its label shadow. Only two things
   are drawn differently, and both say something the user needs to know.

   The AMBER is the strip's own colour rather than the audio lane's green,
   because a block on this strip is a thing you wrote, not a file you added —
   and the difference matters when both are sitting on audio lanes together.

   UNRECORDED is a real state, not decoration: the words and the audio have
   moved apart, so the block is dashed and shows a dot. It will still render —
   the render records it — but until then its width is a placeholder and not
   how long the line actually takes to say. Nothing here relies on colour
   alone: the border becomes dashed, a marker appears, and the inspector says
   so in words. */
.mc-seq-clip.is-narration { background: linear-gradient(135deg,#3b2a12,#7a5320);
  color: #ffe9c7; border-color: #a9782f; }
.mc-seq-clip.is-narration .mc-seq-clip-label { position: relative;
  text-shadow: 0 1px 3px rgba(0,0,0,.85); }
/* Not grab/grabbing: on this strip a block moves along the lane and nothing
   else, so the cursor promises exactly that. */
.mc-seq-clip.is-narration { cursor: ew-resize; }
.mc-seq-clip.is-narration.is-unrecorded { border-style: dashed;
  background: linear-gradient(135deg,#241a0d,#4a3413); }
.mc-seq-clip.is-narration.is-unrecorded .mc-seq-clip-label::before {
  content: "\25CF"; color: #ffb74d; margin-right: 6px; font-size: .7em;
  vertical-align: middle; }

/* The line the narrator says. Prose the user reads and writes, so it clears
   the 16px body floor and drops the uppercase label styling its <label>
   otherwise inherits. */
.mc-seq-field.is-wide { grid-column: 1 / -1; }
.mc-seq-narration-text { background: #141720; color: var(--text);
  border: 1px solid var(--border); border-radius: 6px; padding: 8px 10px;
  font: inherit; font-size: 1rem; line-height: 1.55; text-transform: none;
  letter-spacing: normal; width: 100%; min-height: 76px; resize: vertical; }
.mc-seq-narration-text:focus-visible { outline: 2px solid var(--accent);
  outline-offset: 1px; border-color: var(--accent); }
/* A character count is metadata, not prose — the 14px fine-print floor. */
.mc-seq-panel-note.is-quiet { font-size: .875rem; color: var(--faint); }

/* ===== Clip inspector: Pane (viewport) section =====
   `--accent` is the site's own brand colour (#8b6cff), already used
   throughout this file — reused here rather than introducing a new token. */
.mc-seq-section-label {
  grid-column: 1 / -1;
  margin: 14px 0 2px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #718096;
}
.mc-seq-field-btn { grid-column: 1 / -1; }
.mc-seq-pip-corners {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  grid-column: 1 / -1;
}
.mc-seq-pip-corner {
  aspect-ratio: 16 / 9;
  border: 1px solid #2d3748;
  border-radius: 6px;
  background: #141720;
  cursor: pointer;
  position: relative;
}
.mc-seq-pip-corner::after {
  content: "";
  position: absolute;
  width: 28%;
  height: 28%;
  background: var(--accent);
  border-radius: 2px;
}
.mc-seq-pip-nw::after { top: 12%; left: 12%; }
.mc-seq-pip-ne::after { top: 12%; right: 12%; }
.mc-seq-pip-sw::after { bottom: 12%; left: 12%; }
.mc-seq-pip-se::after { bottom: 12%; right: 12%; }
.mc-seq-pip-corner:hover { border-color: var(--accent); }

/* ---- Deleting library assets --------------------------------------------
   One armed-state treatment for every delete button in the app, so the second
   click looks the same wherever it is. The class comes from
   asset-delete.js's makeArmedDeleteButton. */
.mc-asset-delete, .mc-thumb-delete, .mc-seq-lut-delete, .mc-seq-delete {
  color: #fc8181; border-color: #5a2b32;
}
.mc-asset-delete:hover, .mc-thumb-delete:hover,
.mc-seq-lut-delete:hover, .mc-seq-delete:hover {
  background: #2a1619; border-color: #7a3a43;
}
.mc-asset-delete.mc-armed, .mc-thumb-delete.mc-armed,
.mc-seq-lut-delete.mc-armed, .mc-seq-delete.mc-armed,
.mc-seq-thumb-delete.mc-armed {
  background: #fc8181; border-color: #fc8181; color: #1a1014;
}
.mc-asset-delete[disabled], .mc-thumb-delete[disabled],
.mc-seq-lut-delete[disabled], .mc-seq-delete[disabled] {
  opacity: 0.55; cursor: default;
}

/* Messages carry the server's 409, which names what still depends on the
   asset. 14px is the fine-print floor; these are sentences, not labels. */
.mc-thumb-msg, .mc-seq-lut-msg {
  font-size: 14px; line-height: 1.5; color: #fc8181; margin: 6px 0 0; width: 100%;
}
.mc-thumb-msg[hidden], .mc-seq-lut-msg[hidden] { display: none; }

/* The audio tile's delete sits on top of the tile, whose own click ADDS the
   track. Small, and only obvious on hover or once armed. */
.mc-seq-thumb-label { display: block; padding: 6px; }
.mc-seq-thumb-delete {
  position: absolute; top: 2px; right: 2px;
  width: 18px; height: 18px; line-height: 1;
  padding: 0; border-radius: 4px;
  background: rgba(10, 12, 20, 0.72); border: 1px solid #3d2932;
  color: #fc8181; font-size: 13px; cursor: pointer;
  opacity: 0; transition: opacity 140ms ease-out;
}
.mc-seq-thumb:hover .mc-seq-thumb-delete,
.mc-seq-thumb-delete:focus-visible,
.mc-seq-thumb-delete.mc-armed { opacity: 1; }
.mc-seq-thumb-delete:hover { background: #2a1619; border-color: #7a3a43; }

@media (prefers-reduced-motion: reduce) {
  .mc-seq-thumb-delete { transition: none; }
}

/* Deleting a saved design. The card itself is clickable and opens the project,
   so the control stays quiet until the card is hovered or the button is
   focused or armed -- a permanently visible Delete on every tile invites the
   click it is trying to guard against. It is never hidden from keyboard users,
   who reach it by focus rather than by hover. */
.mc-project-delete {
  margin-top: 8px; width: 100%;
  color: #fc8181; border-color: #5a2b32; font-size: 14px;
  opacity: 0; transition: opacity 140ms ease-out;
}
.mc-project-card:hover .mc-project-delete,
.mc-project-delete:focus-visible,
.mc-project-delete.mc-armed { opacity: 1; }
.mc-project-delete:hover { background: #2a1619; border-color: #7a3a43; }
.mc-project-msg { font-size: 14px; line-height: 1.5; color: #fc8181; margin: 6px 0 0; }
.mc-project-msg[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) {
  .mc-project-delete { transition: none; }
}

/* Touch devices have no hover, so a control revealed only by :hover is
   unreachable on a phone or tablet -- it is not subtle there, it is missing.
   Both delete controls that hide at rest get shown unconditionally where the
   pointer cannot hover. `any-hover` rather than `hover` so a tablet with a
   keyboard-and-trackpad attached keeps the quieter treatment. */
@media (any-hover: none) {
  .mc-project-delete,
  .mc-seq-thumb-delete { opacity: 1; }
}
