:root {
  --bg: #f7f7fa;
  --panel: #ffffff;
  --text: #1f2430;
  --muted: #6b7280;
  --border: #e2e4ea;
  --accent: #2563eb;
  --accent-2: #f59e0b;
  --danger: #ef4444;
  --waveform-color: #2563eb;
  --waveform-mid: rgba(107, 114, 128, 0.35);
  --shade: rgba(15, 23, 42, 0.10);
  /* Lightens (rather than darkens) the waveform in regions not claimed by
     any segment, to read as "faded out / excluded" rather than just
     "inactive" (that's what --shade is for). Matches --panel's own color
     per theme so it reads as a wash, not a mismatched tint. */
  --gap-shade: rgba(255, 255, 255, 0.6);
  --playcursor: #10b981;
  /* Deliberately red (DaVinci Resolve keyframe-diamond convention), but a
     distinct rose shade from --danger so a marker is never mistaken for an
     error/delete affordance. */
  --effect: #e11d48;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #14161c;
    --panel: #1c1f27;
    --text: #e6e8ee;
    --muted: #9aa0ae;
    --border: #2a2e38;
    --accent: #5b8def;
    --waveform-color: #5b8def;
    --waveform-mid: rgba(154, 160, 174, 0.35);
    --shade: rgba(255, 255, 255, 0.08);
    --gap-shade: rgba(28, 31, 39, 0.6);
    --playcursor: #34d399;
    --effect: #fb7185;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, "Hiragino Kaku Gothic ProN", "Yu Gothic", system-ui, sans-serif;
}

.app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  border-bottom: 1px solid var(--border);
  background: var(--panel);
}
.app-header h1 { font-size: 18px; margin: 0; }
.brand-link { color: inherit; text-decoration: none; }
.brand-link:hover { text-decoration: underline; }

.header-left { display: flex; align-items: center; gap: 20px; }

.mode-switch {
  display: flex;
  gap: 4px;
  padding: 3px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  position: relative;
}
/* Sliding thumb behind the tabs: moves between the two slots instead of
   the active background snapping from one button to the other. */
.mode-switch::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 28px;
  height: 28px;
  border-radius: 6px;
  background: var(--accent);
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: none;
}
.mode-switch:has(.mode-tab:nth-child(2).active)::before {
  transform: translateX(32px);
}
.mode-tab {
  position: relative;
  transition: color 0.25s;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  background: transparent;
  border-radius: 6px;
  cursor: pointer;
  color: var(--muted);
}
/* Only color/background differ between states — width/height/padding/border
   stay identical so the switch never resizes when toggling modes. */
.mode-tab.active {
  color: #fff;
}

/* Pure-CSS hover/focus dropdown. The trigger and list sit flush (list's
   top is exactly the trigger's bottom, no margin) with the visual gap
   done as transparent padding-top on the list itself, so the pointer
   never crosses a dead zone between them while moving from one to the
   other — a real gap there would drop :hover mid-transition and flicker
   the menu shut. */
.tools-menu { position: relative; }
.tools-menu-trigger {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: none;
  border: none;
  padding: 4px 2px;
  font: inherit;
  font-size: 13px;
  color: var(--muted);
  cursor: pointer;
}
.tools-menu-trigger::after {
  content: "";
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  margin-top: -3px;
}
.tools-menu-trigger:hover,
.tools-menu:focus-within .tools-menu-trigger { color: var(--text); }
.tools-menu-list {
  position: absolute;
  top: 100%;
  left: 0;
  padding-top: 8px;
  min-width: 170px;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
  z-index: 20;
}
.tools-menu:hover .tools-menu-list,
.tools-menu:focus-within .tools-menu-list {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.tools-menu-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.16);
  padding: 6px;
}
.tools-menu-card a {
  display: block;
  padding: 8px 10px;
  border-radius: 5px;
  font-size: 13px;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
}
.tools-menu-card a:hover { background: var(--bg); }

.upload-btn {
  background: var(--accent);
  color: #fff;
  padding: 8px 14px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
}

.app-main {
  max-width: 960px;
  margin: 16px auto;
  padding: 0 16px 28px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
/* A class-based `display` rule otherwise beats the UA [hidden]{display:none}
   rule (same specificity, author stylesheet wins), so hidden elements with
   their own display value need an explicit override here. */
.app-main[hidden] { display: none; }

/* Empty-state drag & drop target, shown before any file is loaded. */
.drop-zone {
  max-width: 960px;
  margin: 16px auto 40px;
  padding: 64px 24px;
  background: var(--panel);
  border: 1.5px dashed var(--border);
  border-radius: 16px;
  text-align: center;
}
.drop-zone[hidden] { display: none; }
.drop-zone.drag-active {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--panel) 90%, var(--accent) 10%);
}
.drop-zone-icon {
  width: 40px;
  height: 40px;
  color: var(--muted);
  margin-bottom: 16px;
}
.drop-zone-text {
  font-size: 16px;
  font-weight: 600;
  margin: 0 0 4px;
}
.drop-zone-sub {
  font-size: 12px;
  color: var(--muted);
  margin: 0 0 14px;
}
.drop-zone-btn {
  display: inline-block;
  background: var(--accent);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  padding: 10px 22px;
  border-radius: 8px;
  cursor: pointer;
}
.drop-zone-btn:hover { opacity: 0.92; }
/* Upload in progress: swap the upload arrow for a spinner + "読み込み中…" and
   hide the pick-a-file controls so a second upload can't be started. */
.drop-zone-spinner,
.drop-zone-loading-text { display: none; }
.drop-zone-spinner {
  width: 40px;
  height: 40px;
  color: var(--accent);
  margin-bottom: 16px;
  animation: drop-zone-spin 0.9s linear infinite;
}
.drop-zone-loading-text {
  font-size: 16px;
  font-weight: 600;
  margin: 0;
}
.drop-zone.loading .drop-zone-spinner { display: inline-block; }
.drop-zone.loading .drop-zone-loading-text { display: block; }
.drop-zone.loading .drop-zone-icon,
.drop-zone.loading .drop-zone-text,
.drop-zone.loading .drop-zone-sub,
.drop-zone.loading .drop-zone-btn,
.drop-zone.loading .drop-zone-formats { display: none; }
@keyframes drop-zone-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .drop-zone-spinner { animation-duration: 3s; }
}
.drop-zone-formats {
  margin: 14px 0 0;
  font-size: 12px;
  color: var(--muted);
}

.toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
}

.toolbar-tools {
  display: flex;
  align-items: center;
  gap: 12px;
}
.toolbar-tools[hidden] { display: none; }

.tool-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text);
  border-radius: 6px;
  cursor: pointer;
}
.tool-btn.active {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}

/* min-width:0 overrides the flex-item default (min-width:auto), which
   would otherwise stop this from ever shrinking below its text's natural
   width — without it, overflow/text-overflow below would never engage no
   matter how long the filename is. The name itself is also middle-
   truncated in JS (fmtMeta) as the primary defense; this is the fallback
   for whatever's left. */
.file-meta {
  font-size: 12px;
  color: var(--muted);
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.status-msg { font-size: 12px; color: var(--danger); }
.toolbar-export-btn { margin-left: auto; flex-shrink: 0; }

.waveform-row {
  display: flex;
  align-items: stretch;
  gap: 12px;
}

.waveform-wrap {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  /* Scales down on shorter windows instead of always claiming a fixed
     220px, which is what was pushing the page past viewport height (and
     triggering a scrollbar) once #app became visible after loading a file. */
  height: clamp(140px, 26vh, 220px);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--panel);
  touch-action: none;
  user-select: none;
}

.mixer {
  display: flex;
  flex: 0 0 auto;
  gap: 18px;
  padding: 14px 18px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--panel) 96%, black 4%), var(--panel));
}
.mixer-channel {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.mixer-value {
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  letter-spacing: 0.02em;
}
.mixer-label {
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
}

/* Custom hardware-style vertical fader (built by mixer.js), not a native
   <input type=range> — gives full control over the recessed track, tick
   marks, unity-gain notch, and a cap with a "real fader" gradient/shadow. */
.fader {
  position: relative;
  width: 40px;
  height: 140px;
  outline: none;
  touch-action: none;
  cursor: default;
  -webkit-tap-highlight-color: transparent;
}
.fader-track {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 6px;
  margin-left: -3px;
  border-radius: 3px;
  background: linear-gradient(180deg, var(--bg), var(--panel) 55%, var(--bg));
  box-shadow:
    inset 0 1px 3px rgba(0, 0, 0, 0.35),
    inset 0 -1px 1px rgba(255, 255, 255, 0.05);
  cursor: pointer;
}
.fader-fill {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  border-radius: 3px;
  background: linear-gradient(180deg, var(--accent), color-mix(in srgb, var(--accent) 40%, transparent));
  opacity: 0.6;
  pointer-events: none;
}
.fader-tick {
  position: absolute;
  left: -5px;
  width: 4px;
  height: 1px;
  margin-bottom: -0.5px;
  background: var(--muted);
  opacity: 0.45;
  pointer-events: none;
}
.fader-tick-unity {
  left: -7px;
  width: 6px;
  height: 2px;
  margin-bottom: -1px;
  background: var(--accent-2);
  opacity: 0.9;
}
.fader-cap {
  position: absolute;
  left: 50%;
  width: 22px;
  height: 26px;
  margin-left: -11px;
  border-radius: 3px;
  background: linear-gradient(180deg, #eef1f6 0%, #ccd2dc 44%, #a9b0bf 46%, #e2e6ec 100%);
  box-shadow:
    0 1px 3px rgba(0, 0, 0, 0.5),
    0 0 0 1px rgba(0, 0, 0, 0.25),
    inset 0 1px 0 rgba(255, 255, 255, 0.6);
  pointer-events: none;
}
.fader-cap::after {
  content: '';
  position: absolute;
  left: 4px;
  right: 4px;
  top: 50%;
  height: 2px;
  margin-top: -1px;
  background: rgba(0, 0, 0, 0.55);
  border-radius: 1px;
}
.fader:focus-visible .fader-cap {
  box-shadow:
    0 0 0 2px var(--accent),
    0 1px 3px rgba(0, 0, 0, 0.5),
    inset 0 1px 0 rgba(255, 255, 255, 0.6);
}
.waveform-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
.waveform-overlay {
  position: absolute;
  inset: 0;
}
.waveform-wrap.cut-mode { cursor: crosshair; }
.waveform-wrap.marker-add-mode { cursor: crosshair; }

.zoom-indicator {
  margin-top: -6px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  color: var(--accent-2);
}
.zoom-indicator[hidden] { display: none; }
.zoom-indicator-track {
  position: relative;
  flex: 1;
  height: 6px;
  background: var(--border);
  border-radius: 3px;
  overflow: hidden;
}
.zoom-indicator-window {
  position: absolute;
  top: 0;
  bottom: 0;
  min-width: 3px;
  background: var(--accent-2);
  border-radius: 3px;
}
.zoom-indicator-label { white-space: nowrap; }

.seg-shade {
  position: absolute;
  top: 0;
  bottom: 0;
  background: var(--shade);
  pointer-events: none;
}
.gap-shade {
  position: absolute;
  top: 0;
  bottom: 0;
  background: var(--gap-shade);
  pointer-events: none;
}
.seg-boundary {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--muted);
  opacity: 0.6;
  pointer-events: none;
}

/* Hit area is intentionally widened toward the OUTSIDE of the kept region
   (away from the selection) so it doesn't compete with the fade triangle,
   which now sits just inside the same bar. The thin line + grip stay
   visually centered on the true crop time regardless of this padding. */
.crop-bar {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 26px;
  cursor: ew-resize;
  touch-action: none;
}
.crop-bar[data-role="crop-start"] { margin-left: -21px; }
.crop-bar[data-role="crop-end"] { margin-left: -5px; }
.crop-bar::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--accent);
}
.crop-bar[data-role="crop-start"]::after { left: 21px; }
.crop-bar[data-role="crop-end"]::after { left: 5px; }
.crop-bar .grip {
  position: absolute;
  top: 50%;
  width: 8px;
  height: 30px;
  margin-top: -15px;
  background: var(--accent);
  border-radius: 4px;
  box-shadow: 0 0 0 2px var(--panel);
}
/* The grip sits flush against the true crop line and protrudes only toward
   the kept (segment) side — start's kept side is to the right, end's is to
   the left — instead of straddling the line on both sides. Same total
   width as before (8px), just kept to one side rather than centered on it.
   The invisible hit-area stays biased the other way (outward) as before;
   only the visible bump's side changes. */
/* Square off the edge that sits flush against the true crop line (so it
   reads as "attached" to it); keep the outer edge rounded. */
.crop-bar[data-role="crop-start"] .grip { left: 21px; margin-left: 0; border-radius: 0 4px 4px 0; }
.crop-bar[data-role="crop-end"] .grip { left: 5px; margin-left: -8px; border-radius: 4px 0 0 4px; }
.crop-bar.zooming .grip { background: var(--accent-2); }

/* Playback-start marker: click the waveform or drag this to choose where
   the next Play starts from. Its grip sits at the bottom (crop-bar grips
   are vertically centered, fade handles sit near the top) so the three
   handle types stay visually distinct and easy to tell apart at a glance. */
.play-cursor-bar {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 16px;
  margin-left: -8px;
  cursor: ew-resize;
  touch-action: none;
}
.play-cursor-bar::after {
  content: '';
  position: absolute;
  left: 7px;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--playcursor);
}
.play-cursor-bar .grip {
  position: absolute;
  left: 2px;
  bottom: 3px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--playcursor);
  box-shadow: 0 0 0 2px var(--panel);
}

.fade-triangle {
  position: absolute;
  top: 10px;
  width: 16px;
  height: 16px;
  cursor: grab;
  touch-action: none;
  background: rgba(245, 158, 11, 0.9);
  opacity: 0.6;
  transition: opacity 0.12s ease;
}
.fade-triangle:active { cursor: grabbing; }
.fade-triangle.active { opacity: 1; }

.fade-zone {
  position: absolute;
  top: 0;
  bottom: 0;
  pointer-events: none;
}
.fade-zone.fade-zone-in {
  background: linear-gradient(to right, rgba(120, 120, 120, 0.55), rgba(120, 120, 120, 0));
}
.fade-zone.fade-zone-out {
  background: linear-gradient(to right, rgba(120, 120, 120, 0), rgba(120, 120, 120, 0.55));
}

.playhead {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--danger);
  pointer-events: none;
}

/* Hover preview while the cut tool is armed: shows exactly where a click
   would split, including magnet snapping — non-interactive so it never
   steals the click meant for the waveform underneath. */
.cut-preview-line {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  margin-left: -1px;
  background: var(--accent);
  pointer-events: none;
}

/* Markers (Effect mode's waveform overlay): a thin vertical line at the
   marker's time, with a small draggable handle at the top — only the
   active effect's markers are shown (see ui.js renderOverlay), in a
   distinct color (--effect) so it's never confused with crop bars/fades
   when switching tabs. The line itself doesn't intercept clicks (so
   clicking through it still hits the waveform to place new markers); only
   the handle is draggable. */
.marker-line {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  margin-left: -1px;
  background: var(--effect);
  opacity: 0.7;
  pointer-events: none;
}
.marker-line.active {
  opacity: 1;
}
/* DaVinci Resolve-style keyframe diamond: a rotated square. Positioned at a
   small POSITIVE top offset (not flush with 0) because .waveform-wrap
   clips overflow — a negative offset here would have its top sliced off by
   that clip, shrinking both the visible diamond and its clickable area. */
.marker-handle {
  position: absolute;
  top: 4px;
  left: 50%;
  width: 12px;
  height: 12px;
  margin-left: -6px;
  transform: rotate(45deg);
  border-radius: 2px;
  background: var(--effect);
  box-shadow: 0 0 0 2px var(--panel);
  cursor: ew-resize;
  touch-action: none;
  pointer-events: auto;
}
.marker-line.active .marker-handle {
  box-shadow: 0 0 0 2px var(--panel), 0 0 0 4px var(--effect);
}

/* Class-based `display: flex` below otherwise beats the UA [hidden]{display:
   none} rule (author styles always win over UA styles), so #effectControlRow
   / #fadeControlRow never actually collapsed when their `hidden` attribute
   was toggled by setMode — same gotcha already worked around for .app-main
   etc. above. */
.control-row[hidden] { display: none; }

.control-row {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: 12px 16px;
  align-items: flex-end;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 16px;
}

.time-fields {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 16px;
  align-items: flex-end;
}

/* Vertical rule between the start/end time fields and the playback
   controls; stretches the row's full height regardless of .control-row's
   own (bottom-aligned) cross-axis alignment. */
.row-divider {
  width: 1px;
  align-self: stretch;
  background: var(--border);
}

.num-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: var(--muted);
}
.num-field input {
  width: 110px;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
}

.primary-btn,
.dialog-buttons button {
  padding: 8px 16px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
  font-size: 14px;
}
.primary-btn {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}

/* Transport controls (replay / skip-to-edit-point / play-or-stop toggle /
   play-all) live inside the start/end control-row, in their own bracketed
   sub-region between two dividers. The trio is centered via plain
   `justify-content: center` on .playback-controls — this works reliably
   (no absolute-position/pixel-offset hacks needed, unlike an earlier
   attempt across the *whole* row) because replay and play-all are both the
   same width, so they flank the trio symmetrically by construction: equal
   flanks + a centered flex group is trivially centered, no math required.
   flex:1 lets this claim the row's remaining width so centering has a
   region to work within instead of shrink-wrapping to its own content. */
.playback-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  flex: 1;
  min-width: 0;
}

.transport-center {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Mirrors .row-divider on the other side of the playback controls, sized
   to match .time-fields' own rendered width (two 110px .num-field inputs +
   16px gap = 236px — keep in sync if either changes) — so the two flanks
   around .playback-controls are equal, which is what puts the play button
   at the row's true horizontal center (see .playback-controls above). */
.history-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 236px;
  align-self: center;
}

.transport-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
  font-size: 15px;
}
.transport-btn:disabled { opacity: 0.4; cursor: default; }
.transport-btn-history {
  width: 42px;
  height: 42px;
}
/* Persistent transport toggles (通し再生/ループ再生) — shared active styling
   so any future toggle in this row stays visually consistent. */
#playAllBtn,
#loopBtn {
  transition: background-color 0.2s, border-color 0.2s, color 0.2s;
}
#playAllBtn.active,
#loopBtn.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.transport-btn-main {
  width: 48px;
  height: 48px;
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-size: 18px;
}
.transport-icon { display: inline-block; line-height: 1; }

.segment-section h2, .effect-section h2 { font-size: 14px; margin: 0 0 8px; color: var(--muted); }
.effect-hint { font-size: 12px; color: var(--muted); margin: 8px 0 0; }

/* "+" button below the effect list, opening a flyout to its right listing
   effect types to add — replaces the earlier toolbar "+" tool, which tested
   as unclear (looked like a generic drawing tool rather than "add a new
   effect"). JS-toggled (click, not hover) since the flyout must open on a
   tap, matching the .tools-menu-card look for visual consistency. */
.effect-add-wrap {
  position: relative;
  margin-top: 10px;
  display: inline-block;
}
.effect-add-btn {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text);
  border-radius: 6px;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}
.effect-add-btn[aria-expanded="true"] {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.effect-add-menu {
  position: absolute;
  top: 0;
  left: 100%;
  margin-left: 8px;
  min-width: 140px;
  z-index: 20;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.16);
  padding: 6px;
}
.effect-add-menu[hidden] { display: none; }
.effect-add-menu-item {
  display: block;
  width: 100%;
  padding: 8px 10px;
  border: none;
  border-radius: 5px;
  background: transparent;
  color: var(--text);
  font-size: 13px;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}
.effect-add-menu-item:hover { background: var(--bg); }
.segment-list { display: flex; flex-wrap: wrap; gap: 8px; }
/* The pill shape lives ONLY on this container (border-radius + overflow:
   hidden clip everything inside to it); children are plain rectangles, so
   there's no separate radius to keep in sync with the container's curve —
   that mismatch was why the background didn't follow the oval cleanly. */
.segment-item {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--panel);
  overflow: hidden;
}
.segment-item:has(.segment-chip.active) { border-color: var(--accent); }
.segment-chip {
  padding: 6px 14px;
  border: none;
  cursor: pointer;
  font-size: 13px;
  background: transparent;
  color: var(--text);
}
/* An effect with fewer than 2 markers is fully bypassed (no active range
   yet) — dim its chip so that's visible at a glance. */
.segment-chip.inactive {
  color: var(--muted);
  font-style: italic;
}
/* Effect whose active range doesn't overlap any current segment — it's a
   complete no-op given the present crop. Distinct from .inactive (not
   enough markers yet) since this is a "you probably didn't mean this"
   warning rather than a normal not-yet-configured state. */
.segment-chip.warning {
  color: var(--danger);
}
.segment-chip.active {
  background: var(--accent);
  color: #fff;
}
.segment-delete-btn {
  width: 24px;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font-size: 14px;
}
.segment-delete-btn:hover {
  background: var(--danger);
  color: #fff;
}


.export-dialog {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px;
  background: var(--panel);
  color: var(--text);
}
.export-dialog::backdrop { background: rgba(0, 0, 0, 0.4); }
.dialog-buttons { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
