:root {
  /* === SURFACE elevation scale ============================================
     Used to layer panels-on-bg-on-card-on-popover. Higher index = closer to
     the user. The forged-plate cards live at --surface-card; the choice/
     track panels at --surface-base; the page bg at --surface-deep. */
  --surface-deep:     #040607;                    /* page background, deepest */
  --surface-base:     rgba(10, 13, 16, 0.9);      /* dashboard panels (legacy --panel) */
  --surface-strong:   rgba(14, 18, 21, 0.96);     /* legacy --panel-strong */
  --surface-card:     #06080b;                    /* harmony cards / track items */
  --surface-elevated: rgba(19, 24, 29, 0.94);     /* popover / overlay style (legacy --panel-elevated) */
  --surface-overlay:  rgba(8, 11, 13, 0.92);      /* toast, dropdown panel */

  /* Backwards-compat aliases. Existing rules still reference these. */
  --bg:              var(--surface-deep);
  --bg-soft:         #0a0d10;
  --panel:           var(--surface-base);
  --panel-strong:    var(--surface-strong);
  --panel-elevated:  var(--surface-elevated);

  /* === LINE / divider tints =============================================== */
  --line:        rgba(219, 229, 233, 0.12);
  --line-strong: rgba(219, 229, 233, 0.20);
  --line-faint:  rgba(219, 229, 233, 0.06);

  /* === TEXT hierarchy =====================================================
     Five tiers, brightest → dimmest. Most copy uses --text; section headings
     bump to --text-strong; secondary metadata to --text-muted; eyebrows and
     labels to --text-faint; disabled controls / empty hints to --text-disabled. */
  --text-strong:   #f8fbfa;   /* h1/h2-style hero copy, high-emphasis numerics */
  --text:          #edf3f1;   /* default body */
  --text-muted:    #a5afb2;   /* secondary lines, descriptions */
  --text-faint:    #6d767a;   /* eyebrows, labels, hints */
  --text-disabled: #4a5054;   /* disabled buttons, empty-slot copy */

  /* Backwards-compat aliases. */
  --muted: var(--text-muted);
  --faint: var(--text-faint);

  /* === ACCENT hue palette =================================================
     Base hue tokens (one per family). Use semantic intents below for state-
     driven UI — these raw hue tokens stay for places where the hue itself
     carries meaning (mood-tag chips, energy-tier accents, brand glints). */
  --mint:   #9fe3b1;   /* Recommended / Melodic mood */
  --toxic:  #8ef0a1;   /* Active selection, brighter mint */
  --blue:   #8ebfe3;   /* Atmospheric / Contrast tone */
  --amber:  #d8a04b;   /* Driving / Warning / Repeat-Variation */
  --violet: #8f84b8;   /* Dark-mood / Neutral status */
  --fire:   #d86a4c;   /* Risky / Heavy / Danger */

  /* === SEMANTIC intent tokens ============================================
     Each intent ships a 6-piece kit so callers don't reinvent the wash:
       fg          — text/icon colour ON intent surface
       bg-soft     — subtle wash for chips, badges (~10–14% alpha)
       bg-strong   — saturated wash for active/pressed states (~20–28%)
       border      — default border at rest (~30–40%)
       border-strong — emphasized border (hover/focus, ~50–60%)
       glow        — outer-shadow tint for box-shadow effects (~10–18%)
     Replaces dozens of scattered rgba(...) literals across cards, callouts,
     status badges, next-move and toast surfaces. */

  /* GOOD — recommended, success, safe */
  --intent-good-fg:            var(--mint);
  --intent-good-bg-soft:       rgba(159, 227, 177, 0.12);
  --intent-good-bg-strong:     rgba(159, 227, 177, 0.22);
  --intent-good-border:        rgba(159, 227, 177, 0.36);
  --intent-good-border-strong: rgba(159, 227, 177, 0.55);
  --intent-good-glow:          rgba(159, 227, 177, 0.14);

  /* WARN — caution, repeat-variation, soft alert */
  --intent-warn-fg:            var(--amber);
  --intent-warn-bg-soft:       rgba(216, 160, 75, 0.12);
  --intent-warn-bg-strong:     rgba(216, 160, 75, 0.22);
  --intent-warn-border:        rgba(216, 160, 75, 0.34);
  --intent-warn-border-strong: rgba(216, 160, 75, 0.55);
  --intent-warn-glow:          rgba(216, 160, 75, 0.16);

  /* DANGER — risky, destructive, error */
  --intent-danger-fg:            var(--fire);
  --intent-danger-bg-soft:       rgba(216, 106, 76, 0.14);
  --intent-danger-bg-strong:     rgba(216, 106, 76, 0.26);
  --intent-danger-border:        rgba(216, 106, 76, 0.4);
  --intent-danger-border-strong: rgba(216, 106, 76, 0.6);
  --intent-danger-glow:          rgba(216, 106, 76, 0.16);

  /* INFO — atmospheric, contrast, neutral progress */
  --intent-info-fg:            var(--blue);
  --intent-info-bg-soft:       rgba(142, 191, 227, 0.12);
  --intent-info-bg-strong:     rgba(142, 191, 227, 0.22);
  --intent-info-border:        rgba(142, 191, 227, 0.34);
  --intent-info-border-strong: rgba(142, 191, 227, 0.5);
  --intent-info-glow:          rgba(142, 191, 227, 0.12);

  /* NEUTRAL — possible, unmarked, "not yet decided" */
  --intent-neutral-fg:            var(--violet);
  --intent-neutral-bg-soft:       rgba(143, 132, 184, 0.14);
  --intent-neutral-bg-strong:     rgba(143, 132, 184, 0.24);
  --intent-neutral-border:        rgba(143, 132, 184, 0.32);
  --intent-neutral-border-strong: rgba(143, 132, 184, 0.5);
  --intent-neutral-glow:          rgba(143, 132, 184, 0.12);

  /* === SECTION identity colors ============================================
     One signature hue per song-section type. Used in track-item accent rail
     and section-tag chips so the user can pick out "where's the chorus?" by
     colour at a glance. Hues are warm, earthy and slightly muted — they read
     as a forge palette (bronze / gold / brick) rather than candy primaries,
     which suits the metal aesthetic of the rest of the app.
     Soft / border tints derive from these via color-mix() in the rules below. */
  --section-intro:     #8aa1b8;  /* cool steel blue — atmospheric opener */
  --section-verse:     #c9a070;  /* warm bronze — grounded body */
  --section-prechorus: #b08fce;  /* lavender — climbing tension */
  --section-chorus:    #e8c468;  /* aged gold — payoff, the main reveal */
  --section-bridge:    #6cb8b0;  /* teal — cool contrast / breath */
  --section-solo:      #d97aa6;  /* rose — dramatic lead */
  --section-breakdown: #b85040;  /* deep brick — heavy crush */
  --section-outro:     #908578;  /* warm grey — sunset close */

  /* === Shadow / depth ===================================================== */
  --shadow:        0 30px 70px rgba(0, 0, 0, 0.52);
  --shadow-card:   0 18px 40px rgba(0, 0, 0, 0.5), 0 5px 12px rgba(0, 0, 0, 0.32);
  --shadow-lifted: 0 22px 54px rgba(0, 0, 0, 0.5), 0 5px 12px rgba(0, 0, 0, 0.34);

  /* === Radius scale ======================================================= */
  --radius-xl: 22px;
  --radius-lg: 16px;
  --radius-md: 12px;
  --radius-sm: 9px;

  /* === Type ============================================================== */
  --font-display: "Bahnschrift SemiCondensed", "Bahnschrift Condensed", "Arial Narrow", "Segoe UI", sans-serif;
  --font-body:    "Trebuchet MS", "Segoe UI", Arial, sans-serif;
  --font-ui:      "Bahnschrift SemiCondensed", "Segoe UI", Arial, sans-serif;
}

* {
  box-sizing: border-box;
}

html {
  min-height: 100%;
  background: var(--bg);
}

body {
  min-height: 100vh;
  margin: 0;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 15px;
  letter-spacing: 0.01em;
  background:
    radial-gradient(circle at 18% 12%, rgba(134, 189, 168, 0.08), transparent 24%),
    radial-gradient(circle at 78% 14%, rgba(122, 144, 164, 0.08), transparent 26%),
    radial-gradient(circle at 60% 80%, rgba(115, 90, 53, 0.08), transparent 22%),
    linear-gradient(180deg, #020304 0%, #07090b 40%, #030506 100%);
  overflow: hidden;
}

body::before,
body::after {
  position: fixed;
  inset: 0;
  content: "";
  pointer-events: none;
}

body::before {
  opacity: 0.2;
  background:
    linear-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
  background-size: 88px 88px;
  mask-image: radial-gradient(circle at center, #000 28%, transparent 90%);
}

body::after {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.02), transparent 14%, transparent 80%, rgba(0, 0, 0, 0.3)),
    linear-gradient(90deg, rgba(0, 0, 0, 0.36), transparent 9%, transparent 91%, rgba(0, 0, 0, 0.36));
}

button,
select,
input {
  font: inherit;
  font-family: var(--font-ui);
}

button,
select {
  color: var(--text);
}

button {
  cursor: pointer;
}

.app-shell {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-rows: 68px minmax(0, 1fr) 90px;
  gap: 8px;
  width: min(1880px, 100vw);
  height: 100vh;
  margin: 0 auto;
  padding: 8px;
}

.glass-panel {
  border: 1px solid var(--line);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.01)),
    var(--panel);
  box-shadow: var(--shadow), inset 0 1px 0 rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(18px);
}

.app-header,
.track-panel,
.choice-panel,
.bottom-dock {
  border-radius: var(--radius-xl);
}

.app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 8px 14px;
  border: 1px solid rgba(230, 236, 239, 0.1);
  background:
    linear-gradient(180deg, rgba(17, 21, 24, 0.96), rgba(8, 10, 12, 0.94)),
    #060809;
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.46), inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.brand-block,
.brand-copy,
.header-meta {
  display: flex;
  align-items: center;
}

.brand-block {
  gap: 14px;
  min-width: 0;
}

.brand-logo {
  display: block;
  width: auto;
  height: 92px;
  max-width: min(340px, 32vw);
  object-fit: contain;
  flex: 0 0 auto;
}

.brand-copy {
  gap: 0;
  min-width: 0;
}

.brand-title,
.panel-heading h1,
.choice-copy h2 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.18em;
}

.brand-subtitle {
  position: relative;
  color: var(--muted);
  font-size: 0.84rem;
  white-space: nowrap;
}

.brand-subtitle::before {
  display: inline-block;
  width: 1px;
  height: 28px;
  margin-right: 16px;
  vertical-align: middle;
  background: var(--line-strong);
  content: "";
}

.header-meta {
  gap: 6px;
}

.tuning-chip {
  margin-right: 10px;
  padding-right: 14px;
  border-right: 1px solid rgba(255, 255, 255, 0.1);
  color: #d4dada;
  font-size: 0.9rem;
  white-space: nowrap;
}

.tuning-chip span {
  color: var(--faint);
}

.icon-button,
.avatar-button,
.square-button {
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.015));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
}

.icon-button {
  width: 40px;
  height: 40px;
  border-radius: 11px;
}

.icon-button svg {
  width: 20px;
  height: 20px;
  fill: #abb4b7;
}

/* Language toggle button — sits next to the help icon in the header.
   Shows EN / UK labels; the active locale gets a brighter colour. */
.lang-toggle {
  width: auto;
  min-width: 56px;
  padding: 0 10px;
  gap: 0;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--text-faint);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
  transition: border-color 0.15s;
}
.lang-toggle:hover {
  border-color: var(--line-strong);
  color: var(--text);
}
.lang-sep {
  color: var(--line-strong);
  font-weight: 400;
}
.lang-option {
  transition: color 0.15s;
}
.lang-option.is-active {
  color: var(--text);
}

.avatar-button {
  width: 42px;
  height: 42px;
  border-radius: 50%;
}

.avatar-button span {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 32%, rgba(255, 255, 255, 0.84) 0 6%, transparent 7%),
    radial-gradient(circle at 37% 47%, #000 0 5%, transparent 6%),
    radial-gradient(circle at 63% 47%, #000 0 5%, transparent 6%),
    radial-gradient(circle at 50% 74%, rgba(0, 0, 0, 0.76) 0 11%, transparent 12%),
    linear-gradient(135deg, #c3cbcf, #414b51 54%, #12171c);
}

.dashboard-grid {
  display: grid;
  grid-template-columns: minmax(330px, 350px) minmax(0, 1fr);
  gap: 8px;
  min-height: 0;
}

.track-panel,
.choice-panel {
  min-height: 0;
}

.track-panel {
  display: flex;
  flex-direction: column;
  padding: 12px 12px 12px 20px;
  background:
    radial-gradient(circle at 12% 10%, rgba(122, 193, 150, 0.08), transparent 28%),
    linear-gradient(180deg, rgba(16, 20, 24, 0.97), rgba(8, 10, 12, 0.95));
}

.choice-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 13px 22px 14px 26px;
  overflow-x: hidden;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(159, 227, 177, 0.34) rgba(255, 255, 255, 0.04);
  background:
    radial-gradient(circle at 36% 6%, rgba(142, 191, 227, 0.07), transparent 26%),
    radial-gradient(circle at 84% 88%, rgba(159, 127, 81, 0.05), transparent 24%),
    linear-gradient(180deg, rgba(18, 23, 27, 0.91), rgba(9, 11, 13, 0.90)),
    url("backgrounds/29.png") center / cover no-repeat;
}

.choice-panel::-webkit-scrollbar {
  width: 10px;
}

.choice-panel::-webkit-scrollbar-track {
  margin: 14px 0;
  border-left: 1px solid rgba(255, 255, 255, 0.04);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.025), rgba(255, 255, 255, 0.01));
}

.choice-panel::-webkit-scrollbar-thumb {
  border: 2px solid rgba(8, 10, 12, 0.92);
  border-radius: 999px;
  background:
    linear-gradient(180deg, rgba(173, 233, 189, 0.46), rgba(92, 127, 105, 0.34)),
    rgba(159, 227, 177, 0.24);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 0 14px rgba(159, 227, 177, 0.08);
}

.choice-panel::-webkit-scrollbar-thumb:hover {
  background:
    linear-gradient(180deg, rgba(190, 239, 203, 0.56), rgba(109, 147, 123, 0.42)),
    rgba(159, 227, 177, 0.3);
}

.choice-panel::before {
  position: absolute;
  inset: 0;
  content: "";
  pointer-events: none;
  opacity: 0.2;
  background:
    linear-gradient(122deg, transparent 0 35%, rgba(255, 255, 255, 0.035) 35.2% 35.5%, transparent 35.7%),
    linear-gradient(24deg, transparent 0 64%, rgba(255, 255, 255, 0.03) 64.2% 64.45%, transparent 64.7%);
}

.choice-panel > * {
  position: relative;
  z-index: 1;
}

.panel-heading,
.choice-topline {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
}

/* === Generate Track block — quiet shortcut in the topline =================
   Subdued ghost-button style: thin neutral border, no bg fill, no gradient.
   Reads as "secondary action" rather than competing with the choice-copy.
   The tagline below ("For the lazy ones") is the wink — tells the user this
   isn't the intended primary path, just a fast escape. */
.generate-track-block {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  flex-shrink: 0;
  margin-top: 4px;
}

.generate-track-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 12px 6px 11px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  font-family: var(--font-ui);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.18s ease;
}

.generate-track-btn:hover {
  border-color: var(--intent-good-border);
  color: var(--text);
  background: var(--intent-good-bg-soft);
}

.generate-track-btn:active {
  background: var(--intent-good-bg-strong);
}

.generate-track-btn:focus-visible {
  outline: none;
  border-color: var(--intent-good-border-strong);
  box-shadow: 0 0 0 3px var(--intent-good-glow);
}

.generate-track-icon {
  color: var(--intent-good-fg);
  font-size: 0.9rem;
  line-height: 1;
}

.generate-track-tagline {
  color: var(--text-faint);
  font-family: var(--font-body);
  font-size: 0.68rem;
  font-style: italic;
  letter-spacing: 0.02em;
  user-select: none;
}

.panel-heading h1 {
  font-size: 1.26rem;
}

.choice-copy h2 {
  font-size: clamp(1.18rem, 1.5vw, 1.52rem);
}

.eyebrow,
.control-block span:first-child {
  margin: 0;
  color: #8f999d;
  font-family: var(--font-display);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.square-button {
  width: 34px;
  height: 34px;
  border-radius: 9px;
  color: #dce4e3;
  font-size: 1.35rem;
  line-height: 1;
}

.track-list {
  display: flex;
  flex-direction: column;
  flex: 1 1 0;           /* fill remaining height in .track-panel flex column */
  gap: 8px;
  min-height: 0;
  margin-top: 14px;
  padding-left: 0;
  padding-right: 3px;
  overflow: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(159, 227, 177, 0.3) transparent;
}

.track-empty {
  border: 1px solid rgba(221, 231, 233, 0.12);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.025);
}

.track-empty {
  padding: 22px 18px 20px;
  text-align: center;
  color: var(--muted);
  line-height: 1.5;
}

.track-empty-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: 0 auto 10px;
  border: 1px solid rgba(159, 227, 177, 0.34);
  border-radius: 50%;
  color: var(--mint);
  background: rgba(159, 227, 177, 0.06);
  font-size: 1.4rem;
}

.track-empty-title {
  margin: 0 0 4px;
  color: var(--text);
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.track-empty-hint {
  margin: 0 0 6px;
  font-size: 0.78rem;
}

.track-empty-secondary {
  margin: 0;
  color: var(--faint);
  font-size: 0.72rem;
  line-height: 1.4;
}

/* Track item — quieter sibling of the harmony-card forged-plate aesthetic.
   Same brushed hairlines + corner glint + bevel, but smaller drop shadow
   and lighter border so dense rows don't read like a wall of lifted plates. */
.track-item {
  position: relative;
  display: grid;
  /* drag handle | track number | accent rail | content | actions */
  grid-template-columns: 18px 30px 3px minmax(0, 1fr) auto;
  gap: 8px;
  align-items: stretch;
  flex-shrink: 0;   /* never compress inside the flex-column .track-list */
  min-height: 90px;
  padding: 10px 9px 11px 6px;
  border: 1px solid rgba(176, 188, 192, 0.16);
  border-radius: 12px;
  background:
    radial-gradient(ellipse 60% 45% at 0% 0%, rgba(255, 255, 255, 0.04), transparent 65%),
    repeating-linear-gradient(180deg,
      rgba(255, 255, 255, 0.012) 0,
      rgba(255, 255, 255, 0.012) 1px,
      transparent 1px,
      transparent 4px),
    linear-gradient(168deg, #0c0f12 0%, #06080b 60%, #080b0e 100%);
  background-color: #07090c;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.05),
    inset 0 -1px 0 rgba(0, 0, 0, 0.5),
    0 6px 14px rgba(0, 0, 0, 0.32);
  cursor: default;
  transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}

.track-item:hover {
  transform: translateX(2px);
  border-color: rgba(159, 227, 177, 0.36);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    inset 0 -1px 0 rgba(0, 0, 0, 0.5),
    0 8px 18px rgba(0, 0, 0, 0.36);
}

.track-item.is-active {
  /* Active border + glow now ride the section tone — a chorus row glows gold,
     a verse row glows bronze, etc. Falls back to mint-green when no tone is
     set (legacy markup). */
  border-color: color-mix(in srgb, var(--section-tone, var(--intent-good-fg)) 60%, transparent);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    inset 0 -1px 0 rgba(0, 0, 0, 0.5),
    0 0 0 1px color-mix(in srgb, var(--section-tone, var(--intent-good-fg)) 18%, transparent),
    0 6px 24px color-mix(in srgb, var(--section-tone, var(--intent-good-fg)) 18%, transparent);
}

.track-item.is-active::before {
  position: absolute;
  left: -1px;
  top: 12%;
  bottom: 12%;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--section-tone, var(--toxic));
  box-shadow: 0 0 12px color-mix(in srgb, var(--section-tone, var(--toxic)) 55%, transparent);
  content: "";
  /* Subtle 2.4s breathing loop reinforces "this row is selected" without
     screaming for attention. Disabled by reduced-motion override below. */
  animation: rail-breathe 2.4s ease-in-out infinite;
  transform-origin: 50% 50%;
}

.track-item.is-entering {
  animation: track-entry 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Drag interactions */
.track-item.is-dragging {
  opacity: 0.45;
  transform: scale(0.99);
  border-color: rgba(159, 227, 177, 0.5);
  cursor: grabbing;
}

.track-item.is-drop-target {
  position: relative;
}

.track-item.is-drop-target.is-drop-before::before,
.track-item.is-drop-target.is-drop-after::after {
  position: absolute;
  left: 6px;
  right: 6px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--toxic) 20%, var(--toxic) 80%, transparent);
  box-shadow: 0 0 12px rgba(142, 240, 161, 0.6);
  content: "";
}

.track-item.is-drop-target.is-drop-before::before {
  top: -5px;
}

.track-item.is-drop-target.is-drop-after::after {
  bottom: -5px;
}

/* Drag handle — replaces the old decorative .drag-dots */
.drag-handle {
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--faint);
  cursor: grab;
  opacity: 0.55;
  transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.drag-handle:hover {
  opacity: 1;
  color: var(--mint);
  background: rgba(159, 227, 177, 0.08);
}

.drag-handle:active,
.track-item.is-dragging .drag-handle {
  cursor: grabbing;
  opacity: 1;
}

.drag-handle span {
  display: block;
  width: 8px;
  height: 28px;
  background-image: radial-gradient(circle, currentColor 1.2px, transparent 1.3px);
  background-size: 4px 7px;
  background-position: center;
}

/* When the row is hovered, dots subtly scroll downward — a one-cell shift
   per loop, looking like the handle is "running" and ready to be grabbed.
   Stops the moment hover leaves. */
.track-item:hover .drag-handle span {
  animation: drag-dots-flow 1.4s linear infinite;
}

.track-item.is-active .drag-handle {
  color: var(--toxic);
  opacity: 0.85;
}

.track-number {
  align-self: center;
  color: #d7dede;
  font-family: var(--font-display);
  font-size: 1.2rem;
  letter-spacing: 0.08em;
}

.track-item.is-active .track-number {
  /* Section-tinted, matching the active rail. Falls back to mint if no
     section tone was set by the renderer (e.g. legacy markup). */
  color: var(--section-tone, var(--toxic));
  text-shadow: 0 0 12px color-mix(in srgb, var(--section-tone, var(--toxic)) 50%, transparent);
}

/* Track-item accent rail — driven by section identity (intro / verse / chorus
   / etc), not energy. Energy is shown in the pill in the header line, so we
   freed this surface to encode something the user actually navigates by:
   "where's the chorus?" is now answered at a glance by the rail colour. */
.track-accent {
  height: calc(100% - 8px);
  align-self: center;
  border-radius: 99px;
  background: var(--section-tone, var(--text-faint));
  box-shadow: 0 0 12px color-mix(in srgb, var(--section-tone, var(--text-faint)) 40%, transparent);
}

.track-content {
  display: grid;
  align-content: start;
  gap: 3px;
  min-width: 0;
  padding-bottom: 1px;
}

.track-section-line {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
  min-width: 0;
}

/* h2 takes available space so play + energy-pill sit pinned to the right. */
.track-section-line h2 {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* === Track-item Play button — preview the part right from the row =========
   Sits inline with the section title so users can re-hear an added part
   without re-entering the cards step. Mint accent on hover marks it as a
   preview/good action, distinct from the edit-actions group on the right. */
.track-play {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--text-muted);
  background: transparent;
  font-size: 0.7rem;
  line-height: 1;
  cursor: pointer;
  flex-shrink: 0;
  transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}

.track-play:hover {
  color: var(--intent-good-fg);
  background: var(--intent-good-bg-soft);
  border-color: var(--intent-good-border);
}

.track-play:focus-visible {
  outline: none;
  border-color: var(--intent-good-border-strong);
  box-shadow: 0 0 0 2px var(--intent-good-glow);
}

.track-play.is-playing {
  color: var(--intent-good-fg);
  background: var(--intent-good-bg-strong);
  border-color: var(--intent-good-border-strong);
}

.track-content h2,
.harmony-card h3 {
  margin: 0;
  color: var(--text-strong);
  line-height: 1.08;
  font-weight: 700;
}

.track-content h2 {
  font-size: 0.92rem;
}

.track-note-row {
  margin-top: 1px;
}

.note-row {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
}

.note-row span {
  display: inline-grid;
  place-items: center;
  min-width: 22px;
  height: 19px;
  padding: 0 6px;
  border: 1px solid rgba(236, 241, 242, 0.14);
  border-radius: 6px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.02));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
  font-size: 0.72rem;
  font-weight: 700;
}

.note-row.large span {
  min-width: 36px;
  height: 31px;
  border-radius: 8px;
  font-size: 1rem;
}

.progression-name,
.track-role,
.choice-hint,
.harmony-card p,
.micro-tip {
  color: var(--muted);
}

.progression-name,
.track-role {
  display: block;
  margin: 0;
  font-size: 0.71rem;
  line-height: 1.24;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.track-role b {
  color: var(--mint);
}

.track-item[data-energy="4"] .track-role b { color: var(--amber); }
.track-item[data-energy="5"] .track-role b { color: var(--fire); }

/* ── Track form: bars / feel / pause controls ──────────────────────────────── */
.track-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  margin-top: 5px;
}

.track-form-field {
  display: flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
}

.track-form-label {
  font-size: 0.62rem;
  color: var(--text-dim, #888);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  user-select: none;
}

.track-bar-select,
.track-feel-select {
  appearance: none;
  -webkit-appearance: none;
  background: var(--surface-raised, #1a1a1a);
  color: var(--text-primary, #e0e0e0);
  border: 1px solid var(--border-subtle, #333);
  border-radius: 4px;
  padding: 1px 18px 1px 5px;
  font-size: 0.66rem;
  line-height: 1.5;
  cursor: pointer;
  outline: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23888'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 4px center;
  background-size: 7px 4px;
  min-width: 40px;
  transition: border-color 0.15s;
}

.track-bar-select:focus,
.track-feel-select:focus {
  border-color: var(--accent, #7b5ea7);
}

.track-form-field--pause {
  gap: 5px;
}

.track-pause-toggle {
  width: 12px;
  height: 12px;
  accent-color: var(--accent, #7b5ea7);
  cursor: pointer;
  flex-shrink: 0;
}

/* All four actions live in a fixed 2x2 grid so layout never shifts on hover.
   Width is locked at ~54px (2 buttons + gap) instead of animating between 2 and 5
   buttons in a single row, which used to squeeze the content column and cause
   the note row to wrap on hover. */
.track-actions {
  display: grid;
  grid-template-columns: 26px 26px;
  grid-template-rows: 26px 26px;
  gap: 2px;
  align-self: center;
  justify-self: end;
  padding: 0 2px;
}

.track-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 7px;
  color: #aab2b6;
  background: rgba(255, 255, 255, 0.02);
  font-size: 0.82rem;
  line-height: 1;
  cursor: pointer;
  transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;
}

/* Idle: secondary buttons (Up / Down) sit slightly recessed so the visual
   hierarchy still reads as "Repeat / Delete are primary, arrows are reorder". */
.track-action--up,
.track-action--down {
  color: var(--faint);
  background: transparent;
}

.track-item:hover .track-action--up,
.track-item:hover .track-action--down,
.track-item.is-active .track-action--up,
.track-item.is-active .track-action--down {
  color: #aab2b6;
  background: rgba(255, 255, 255, 0.02);
}

.track-action:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.08);
}

.track-action:focus-visible {
  outline: none;
  border-color: rgba(159, 227, 177, 0.55);
  box-shadow: 0 0 0 2px rgba(159, 227, 177, 0.18);
}

.track-action--repeat:hover {
  color: var(--intent-good-fg);
  background: var(--intent-good-bg-soft);
}

.track-action--replace:hover {
  color: var(--intent-warn-fg);
  background: var(--intent-warn-bg-soft);
}

.track-action--delete:hover {
  color: var(--intent-danger-fg);
  background: var(--intent-danger-bg-soft);
}

/* Disable Up on the first item and Down on the last — there's nowhere to move. */
.track-action--up[disabled],
.track-action--down[disabled] {
  opacity: 0.25;
  cursor: not-allowed;
  pointer-events: none;
}

/* Energy pill in the section line — replaces "Energy 2/5" prose at end of track-role */
.energy-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  height: 18px;
  padding: 0 6px;
  border: 1px solid rgba(221, 231, 233, 0.16);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--muted);
  font-family: var(--font-ui);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  white-space: nowrap;
  flex-shrink: 0;
}

.energy-pill--mint   { border-color: rgba(159, 227, 177, 0.4); color: var(--mint);   background: rgba(159, 227, 177, 0.08); }
.energy-pill--toxic  { border-color: rgba(142, 240, 161, 0.5); color: var(--toxic);  background: rgba(142, 240, 161, 0.1); }
.energy-pill--blue   { border-color: rgba(142, 191, 227, 0.4); color: var(--blue);   background: rgba(142, 191, 227, 0.08); }
.energy-pill--amber  { border-color: rgba(216, 160, 75, 0.5);  color: var(--amber);  background: rgba(216, 160, 75, 0.1); }
.energy-pill--violet { border-color: rgba(143, 132, 184, 0.5); color: var(--violet); background: rgba(143, 132, 184, 0.1); }
.energy-pill--fire   { border-color: rgba(216, 106, 76, 0.55); color: var(--fire);   background: rgba(216, 106, 76, 0.12); }

.structure-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 7px;
  margin-top: 10px;
}

.structure-button {
  min-height: 40px;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  color: #dce4e3;
  background: rgba(255, 255, 255, 0.02);
  font-weight: 700;
  letter-spacing: 0.04em;
}

.structure-button.primary {
  border-color: rgba(216, 160, 75, 0.56);
  color: #171007;
  background: linear-gradient(180deg, #e6bb72, #d8a04b);
}

/* Single safety-net warning chip — replaces the 3-4 stacked structure-hints
   block. Renders only when structureHealth.score < 60 (e.g. "Add a verse",
   "Add a chorus to give the song a payoff"). When the form is healthy this
   element stays hidden and gives back ~140px of vertical space to the track-list. */
.track-warning {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: 10px;
  padding: 8px 12px;
  border: 1px solid var(--intent-warn-border);
  border-radius: 9px;
  background: var(--intent-warn-bg-soft);
  color: var(--text);
  font-size: 0.78rem;
  line-height: 1.4;
}

.track-warning::before {
  content: "⚠";
  flex-shrink: 0;
  color: var(--intent-warn-fg);
  font-size: 0.95rem;
  line-height: 1.4;
}

.track-warning[hidden] {
  display: none;
}

@keyframes track-entry {
  0% {
    opacity: 0;
    transform: translateY(10px) scale(0.985);
    box-shadow: 0 0 0 1px rgba(142, 240, 161, 0.08), 0 0 0 rgba(142, 240, 161, 0);
  }
  55% {
    opacity: 1;
    transform: translateY(-1px) scale(1);
    box-shadow: 0 0 0 1px rgba(142, 240, 161, 0.12), 0 0 28px rgba(142, 240, 161, 0.12);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes hint-refresh {
  0% {
    opacity: 0.58;
    transform: translateY(8px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes card-add-pulse {
  0% {
    transform: translateY(0) scale(1);
    border-color: rgba(159, 227, 177, 0.22);
    box-shadow: 0 18px 42px rgba(0, 0, 0, 0.26), inset 0 1px 0 rgba(255, 255, 255, 0.04);
  }
  50% {
    transform: translateY(-3px) scale(1.01);
    border-color: rgba(159, 227, 177, 0.62);
    box-shadow: 0 24px 58px rgba(0, 0, 0, 0.34), 0 0 0 1px rgba(159, 227, 177, 0.12), 0 0 32px rgba(159, 227, 177, 0.16);
  }
  100% {
    transform: translateY(0) scale(1);
    border-color: rgba(159, 227, 177, 0.3);
    box-shadow: 0 22px 52px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(159, 227, 177, 0.06);
  }
}

/* === New animation primitives (Phase: animations) ===
   All animations are gated on `prefers-reduced-motion: no-preference` later
   in the file so reduced-motion users get instant state changes. */

/* Card grid reveal — every harmony / next-step / root / review card eases in
   from a small Y offset. Per-card staggering is driven by --card-index set
   inline by the renderers, capped at index 11 so a long grid doesn't take
   forever to settle. */
@keyframes card-fade-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Active track-item rail breathing — gentle 2.4s loop. Subtle so it doesn't
   compete for attention; drives a sense of "this row is alive / selected". */
@keyframes rail-breathe {
  0%, 100% { opacity: 1;   transform: scaleY(1);    }
  50%      { opacity: 0.78; transform: scaleY(0.94); }
}

/* Drag-dots flow on hover — dots appear to scroll downward, suggesting the
   handle is grabbable. Only runs when the row is hovered. The 7px shift is
   exactly one dot pitch (4px size + 3px gap from the existing pattern). */
@keyframes drag-dots-flow {
  from { background-position-y: 0; }
  to   { background-position-y: 7px; }
}

/* Chip pop — mood-chip / filter-chip get a crisp bounce when they receive
   `.is-active`. Replays naturally each time a different chip becomes active
   because CSS animations re-trigger when an animated class is added fresh. */
@keyframes chip-pop {
  0%   { transform: scale(1);    }
  45%  { transform: scale(1.06); }
  100% { transform: scale(1);    }
}

.choice-lead {
  margin: 5px 0 0;
  color: #eff4f2;
  font-size: 0.95rem;
  line-height: 1.3;
  max-width: 680px;
}

.choice-hint {
  margin: 3px 0 0;
  max-width: 700px;
  font-size: 0.8rem;
  line-height: 1.4;
}

.cards-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(220px, 1fr));
  gap: 14px;
  margin-top: 12px;
}

/* === Harmony card — forged-plate aesthetic ===
   Reads as a metal plate sitting on the panel rather than fading into it:
     • Base: significantly darker than panel (~#06080b vs panel ~#15191c).
     • Brushed-metal horizontal hairlines via repeating-linear-gradient.
     • Top-left chrome glint via radial-gradient (plate "catches" light).
     • Inset bevel (top white hairline + bottom black hairline) for hammered depth.
     • Outer drop shadow gives the plate weight.
   Tone overlays (recommended / risky / contrast / finish) layer on top via
   ::before so the base metal stays consistent across all variants. */
.harmony-card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 214px;
  border: 1px solid rgba(176, 188, 192, 0.18);
  border-radius: var(--radius-lg);
  overflow: hidden;
  --card-bg-img: url("backgrounds/harmony-card/32.png");
  background:
    /* top-left chrome glint */
    radial-gradient(ellipse 70% 50% at 0% 0%, rgba(255, 255, 255, 0.05), transparent 62%),
    /* faint brushed-metal hairlines */
    repeating-linear-gradient(180deg,
      rgba(255, 255, 255, 0.014) 0,
      rgba(255, 255, 255, 0.014) 1px,
      transparent 1px,
      transparent 4px),
    /* semi-transparent iron overlay — lets the photo texture breathe */
    linear-gradient(168deg, rgba(12, 15, 18, 0.72) 0%, rgba(5, 7, 9, 0.68) 55%, rgba(8, 11, 14, 0.70) 100%),
    /* status-tinted photo background — overridden per card class below */
    var(--card-bg-img) center / cover no-repeat;
  background-color: #06080b;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    inset 0 -1px 0 rgba(0, 0, 0, 0.6),
    0 18px 40px rgba(0, 0, 0, 0.5),
    0 5px 12px rgba(0, 0, 0, 0.32);
  transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
  /* Staggered fade-in — see card-fade-in keyframes. --card-index is set by
     the renderers; clamping to 11 keeps a 12-card grid below ~480ms total. */
  animation: card-fade-in 0.36s ease-out both;
  animation-delay: calc(min(var(--card-index, 0), 11) * 40ms);
}

/* Status-tinted photo backgrounds: each image was pre-graded for its role. */
.harmony-card.choice-recommended { --card-bg-img: url("backgrounds/harmony-card/30.png"); }
.harmony-card.choice-contrast     { --card-bg-img: url("backgrounds/harmony-card/31.png"); }
/* Alt Pick (no class) already uses 32.png from the base rule above.         */
.harmony-card.choice-finish       { --card-bg-img: url("backgrounds/harmony-card/30.png"); }
.harmony-card.choice-risky        { --card-bg-img: url("backgrounds/harmony-card/33.png"); }

/* Top-edge sheen — sharper than before to read as a polished bevel rather
   than a soft glow. Tone variants override the gradient list to layer in a
   tinted accent without redefining the metal base on each tone class. */
.harmony-card::before {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 38%;
  content: "";
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.055) 0%,
    rgba(255, 255, 255, 0.012) 40%,
    transparent 100%);
}

.harmony-card:hover,
.harmony-card.is-selected {
  /* Stronger lift + tighter accent ring so hover reads as "pickable", not
     just decorative. Bevel insets preserved so the plate doesn't deflate. */
  transform: translateY(-3px);
  border-color: rgba(159, 227, 177, 0.6);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    inset 0 -1px 0 rgba(0, 0, 0, 0.62),
    0 26px 60px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(159, 227, 177, 0.18),
    0 0 38px rgba(159, 227, 177, 0.16);
}

/* Brighter top sheen on hover — the "plate catches more light" effect that
   reinforces the lift transform without screaming for attention. */
.harmony-card:hover::before,
.harmony-card.is-selected::before {
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.085) 0%,
    rgba(255, 255, 255, 0.02) 45%,
    transparent 100%);
}

.harmony-card.is-playing {
  border-color: var(--intent-warn-border-strong);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.085),
    inset 0 -1px 0 rgba(0, 0, 0, 0.62),
    0 22px 54px rgba(0, 0, 0, 0.5),
    0 0 34px var(--intent-warn-glow);
}

.harmony-card.is-focused {
  border-color: var(--intent-good-border-strong);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.09),
    inset 0 -1px 0 rgba(0, 0, 0, 0.62),
    0 22px 54px rgba(0, 0, 0, 0.5),
    0 0 0 2px var(--intent-good-bg-strong),
    0 0 38px var(--intent-good-glow);
}

.harmony-card.is-adding {
  animation: card-add-pulse 0.22s ease;
}

.harmony-card.repeat-safe {
  border-color: var(--intent-good-border-strong);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.075),
    inset 0 -1px 0 rgba(0, 0, 0, 0.6),
    0 22px 54px rgba(0, 0, 0, 0.5),
    0 0 0 1px var(--intent-good-bg-soft),
    0 0 28px var(--intent-good-glow);
}

.harmony-card.repeat-variation {
  border-color: var(--intent-warn-border);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.075),
    inset 0 -1px 0 rgba(0, 0, 0, 0.6),
    0 22px 54px rgba(0, 0, 0, 0.5),
    0 0 0 1px var(--intent-warn-bg-soft),
    0 0 24px var(--intent-warn-glow);
}

.harmony-card.repeat-contrast {
  border-color: var(--intent-info-border);
}

/* Tone variants — accent enters via the ::before sheen layer + outer glow.
   Bevel insets (top highlight + bottom shadow) preserved across all tones so
   the plate effect doesn't deflate when a card is recommended/risky/etc. */
.harmony-card.choice-recommended {
  border-color: var(--intent-good-border-strong);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.075),
    inset 0 -1px 0 rgba(0, 0, 0, 0.6),
    0 22px 54px rgba(0, 0, 0, 0.5),
    0 0 26px var(--intent-good-glow);
}

/* Best Fit "spotlight" — bright mint glint on the top-left in addition to the
   regular top-right tone overlay. Reads as the plate catching extra light and
   draws the eye to primary recommendations. Layered as the FIRST gradient in
   the ::before stack (rendered last → on top), so the corner glint sits over
   the rest of the sheen. */
.harmony-card.choice-recommended::before {
  background:
    radial-gradient(ellipse 60% 80% at 12% 16%, rgba(159, 227, 177, 0.22), transparent 72%),
    radial-gradient(ellipse 70% 60% at 100% 0%, var(--intent-good-bg-strong), transparent 65%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.06) 0%, rgba(255, 255, 255, 0.014) 40%, transparent 100%);
}

.harmony-card.choice-risky {
  border-color: var(--intent-danger-border-strong);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.075),
    inset 0 -1px 0 rgba(0, 0, 0, 0.6),
    0 22px 54px rgba(0, 0, 0, 0.5),
    0 0 24px var(--intent-danger-glow);
}

.harmony-card.choice-risky::before {
  background:
    radial-gradient(ellipse 70% 60% at 100% 0%, var(--intent-danger-bg-strong), transparent 65%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.055) 0%, rgba(255, 255, 255, 0.012) 40%, transparent 100%);
}

.harmony-card.choice-contrast {
  border-color: var(--intent-info-border);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.075),
    inset 0 -1px 0 rgba(0, 0, 0, 0.6),
    0 22px 54px rgba(0, 0, 0, 0.5),
    0 0 22px var(--intent-info-glow);
}

.harmony-card.choice-contrast::before {
  background:
    radial-gradient(ellipse 70% 60% at 100% 0%, var(--intent-info-bg-soft), transparent 65%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.055) 0%, rgba(255, 255, 255, 0.012) 40%, transparent 100%);
}

.harmony-card.choice-finish {
  border-color: rgba(218, 189, 112, 0.54);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.085),
    inset 0 -1px 0 rgba(0, 0, 0, 0.6),
    0 22px 54px rgba(0, 0, 0, 0.5),
    0 0 32px rgba(218, 189, 112, 0.14);
}

.harmony-card.choice-finish::before {
  background:
    radial-gradient(ellipse 80% 70% at 100% 0%, rgba(218, 189, 112, 0.18), transparent 65%),
    radial-gradient(ellipse 50% 40% at 0% 0%, rgba(218, 189, 112, 0.1), transparent 55%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.06) 0%, rgba(255, 255, 255, 0.014) 40%, transparent 100%);
}

.harmony-card.choice-finish h3 {
  color: #f2dfac;
}

/* === Custom-harmony card — user's own progression input ====================
   Always sits first in the cards-grid. Spans 2 columns at the default 3-col
   grid so the slot-picker UI breathes; collapses naturally at narrower
   breakpoints because grid handles `span 2` gracefully when only 1-2 cols
   exist. Distinct dashed amber border + warm tint background reads as a
   "sketch zone" — clearly different from auto-generated cards. */
.harmony-card--custom {
  grid-column: span 2;
  border-style: dashed;
  border-color: var(--intent-warn-border-strong);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    inset 0 -1px 0 rgba(0, 0, 0, 0.6),
    0 18px 40px rgba(0, 0, 0, 0.5),
    0 0 28px var(--intent-warn-glow);
}

.harmony-card--custom::before {
  background:
    radial-gradient(ellipse 80% 70% at 100% 0%, var(--intent-warn-bg-soft), transparent 65%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.06) 0%, rgba(255, 255, 255, 0.014) 40%, transparent 100%);
}

.card-fit-row--custom {
  justify-content: space-between;
}

.card-status--custom {
  color: var(--intent-warn-fg);
  background: var(--intent-warn-bg-soft);
  border-color: var(--intent-warn-border-strong);
}

/* Custom-card visibility trigger — shown at the bottom of the cards grid
   when showCustomCard is false. Visually distinct from harmony cards:
   dashed border, muted amber tint, smaller footprint. */
.custom-card-trigger {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 12px 18px;
  background: rgba(218, 189, 112, 0.04);
  border: 1px dashed var(--intent-warn-border-strong);
  border-radius: var(--radius-card);
  color: var(--intent-warn-fg);
  font-size: 0.85rem;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
  opacity: 0.72;
}
.custom-card-trigger:hover {
  background: rgba(218, 189, 112, 0.09);
  border-color: var(--intent-warn-fg);
  opacity: 1;
}
.custom-card-trigger-icon {
  font-size: 1.1rem;
  flex-shrink: 0;
}
.custom-card-trigger-label {
  font-weight: 500;
}

/* Close button on the custom card — top-right corner, small ×. */
.custom-card-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--intent-warn-border-strong);
  border-radius: 50%;
  color: var(--text-faint);
  font-size: 0.8rem;
  cursor: pointer;
  opacity: 0.6;
  transition: opacity 0.15s, background 0.15s;
  z-index: 2;
}
.custom-card-close:hover {
  opacity: 1;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
}

.custom-hint {
  color: var(--text-faint);
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-style: italic;
  letter-spacing: 0.01em;
}

.custom-input {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 12px 0 10px;
  padding: 12px;
  border: 1px solid rgba(221, 231, 233, 0.08);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.018);
}

.custom-slots {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.custom-slot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 38px;
  padding: 0 10px;
  border: 1px solid rgba(221, 231, 233, 0.18);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--text);
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease, transform 0.12s ease;
}

.custom-slot:hover {
  border-color: var(--intent-warn-border-strong);
  background: rgba(255, 255, 255, 0.06);
}

.custom-slot.is-active {
  border-color: var(--intent-warn-fg);
  background: var(--intent-warn-bg-strong);
  color: #1a1308;
  box-shadow: 0 0 0 2px var(--intent-warn-glow);
}

.custom-slot:focus-visible {
  outline: none;
  border-color: var(--intent-warn-border-strong);
  box-shadow: 0 0 0 3px var(--intent-warn-glow);
}

.custom-slot-control {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  margin-left: 4px;
  padding: 0;
  border: 1px solid rgba(221, 231, 233, 0.14);
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}

.custom-slot-control:hover {
  border-color: var(--intent-warn-border-strong);
  color: var(--text);
}

.custom-slot-control[disabled] {
  opacity: 0.3;
  cursor: not-allowed;
  pointer-events: none;
}

.custom-note-row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding-top: 10px;
  border-top: 1px solid rgba(221, 231, 233, 0.08);
}

.custom-note {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 38px;
  height: 32px;
  padding: 0 8px;
  border: 1px solid rgba(221, 231, 233, 0.12);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--text-muted);
  font-family: var(--font-display);
  font-size: 0.84rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease, transform 0.1s ease;
}

.custom-note:hover {
  border-color: var(--intent-warn-border-strong);
  background: var(--intent-warn-bg-soft);
  color: var(--intent-warn-fg);
}

.custom-note:active {
  transform: translateY(1px);
}

.custom-note:focus-visible {
  outline: none;
  border-color: var(--intent-warn-border-strong);
  box-shadow: 0 0 0 2px var(--intent-warn-glow);
}

.harmony-card > :not(.card-actions) {
  padding-left: 16px;
  padding-right: 16px;
}

.favorite-button {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 26px;
  height: 26px;
  border: 0;
  border-radius: 9px;
  color: #aeb7ba;
  background: transparent;
  font-size: 1.15rem;
  z-index: 1;
}

.favorite-button:hover,
.favorite-button.is-active {
  color: var(--amber);
}

/* === Card "fit indicator" row — fit-bar + status badge ===
   Replaces the cluttered tag-row that used to mix mood, status and repeat
   chips together. Now status lives in its own visually heavier badge with
   a small horizontal fit-bar showing how strongly the card suits this slot. */
.card-fit-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
  margin-right: 36px; /* leave room for the absolute favorite-button */
}

/* Choice cards (section picker, root picker) have no favorite-button,
   so remove the reserved margin. */
.choice-card .card-fit-row {
  margin-right: 0;
}

.fit-bar {
  position: relative;
  flex: 1;
  height: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  overflow: hidden;
}

.fit-bar > span {
  display: block;
  height: 100%;
  border-radius: 999px;
  transition: width 0.25s ease;
}

.fit-bar--good > span    { background: linear-gradient(90deg, var(--intent-good-fg),    var(--toxic)); }
.fit-bar--cool > span    { background: linear-gradient(90deg, var(--intent-info-border-strong), var(--intent-info-fg)); }
.fit-bar--neutral > span { background: linear-gradient(90deg, var(--intent-neutral-border-strong), var(--intent-neutral-fg)); }
.fit-bar--danger > span  { background: linear-gradient(90deg, var(--intent-danger-border-strong), var(--intent-danger-fg)); }

.card-status {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border: 1px solid rgba(221, 231, 233, 0.16);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.02);
  color: var(--muted);
  font-family: var(--font-display);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  flex-shrink: 0;
}

.card-status--good    { color: var(--intent-good-fg);    background: var(--intent-good-bg-soft);    border-color: var(--intent-good-border); }
.card-status--cool    { color: var(--intent-info-fg);    background: var(--intent-info-bg-soft);    border-color: var(--intent-info-border); }
.card-status--neutral { color: var(--intent-neutral-fg); background: var(--intent-neutral-bg-soft); border-color: var(--intent-neutral-border); }
.card-status--danger  { color: var(--intent-danger-fg);  background: var(--intent-danger-bg-soft);  border-color: var(--intent-danger-border); }

.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}

.tag {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 3px 8px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
  font-size: 0.72rem;
}

.tag.mint { color: #c7f5d0; background: rgba(159, 227, 177, 0.13); border-color: rgba(159, 227, 177, 0.24); }
.tag.dark { color: #d6d8e2; background: rgba(143, 132, 184, 0.11); border-color: rgba(143, 132, 184, 0.22); }
.tag.blue { color: #cee7f7; background: rgba(142, 191, 227, 0.12); border-color: rgba(142, 191, 227, 0.24); }
.tag.cold { color: #dae4ea; background: rgba(140, 165, 180, 0.11); border-color: rgba(140, 165, 180, 0.22); }
.tag.amber { color: #f3d39a; background: rgba(216, 160, 75, 0.14); border-color: rgba(216, 160, 75, 0.26); }
.tag.fire { color: #ffbeb5; background: rgba(201, 84, 64, 0.16); border-color: rgba(201, 84, 64, 0.34); }
.tag.violet { color: #ded7f0; background: rgba(143, 132, 184, 0.16); border-color: rgba(143, 132, 184, 0.28); }
.tag.steel { color: #cdd6de; background: rgba(140, 165, 180, 0.13); border-color: rgba(140, 165, 180, 0.26); }

/* Section-tinted tag — picks up its colour from a --section-tone CSS variable
   set inline on the tag (or on a parent). Same shape as the static colour
   tags above but driven by section identity rather than mood. */
.tag.tag--section {
  color: var(--section-tone, var(--text-muted));
  background: color-mix(in srgb, var(--section-tone, var(--text-muted)) 14%, transparent);
  border-color: color-mix(in srgb, var(--section-tone, var(--text-muted)) 36%, transparent);
}

.harmony-card h3 {
  margin-top: 12px;
  font-size: 1.3rem;
  letter-spacing: 0.02em;
}

.card-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 12px;
}

/* Legacy classes kept for any external markup that still uses them.
   New card markup uses .energy-pill (defined under .track-actions block). */
.energy {
  white-space: nowrap;
  font-size: 0.88rem;
}

.energy-3 { color: var(--mint); }
.energy-4 { color: var(--amber); }
.energy-5 { color: var(--fire); }

.harmony-card p {
  margin: 10px 0 8px;
  font-size: 0.86rem;
  line-height: 1.4;
}

.harmony-card .card-desc {
  margin: 10px 0 6px;
}

/* Compact callout stack — replaces the old .why-fit paragraphs that stacked
   three or four bolded prose lines at the bottom of every card. */
.card-callouts {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 10px 0 12px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}

.card-callout {
  display: grid;
  grid-template-columns: 16px 1fr;
  gap: 8px;
  margin: 0;
  padding: 0;
  font-size: 0.78rem;
  line-height: 1.4;
  color: var(--muted);
}

.card-callout > span:last-child {
  min-width: 0;
}

.card-callout b {
  font-weight: 700;
}

.card-callout-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 5px;
  font-size: 0.78rem;
  line-height: 1;
}

.card-callout--good .card-callout-icon    { color: var(--intent-good-fg);    background: var(--intent-good-bg-soft); }
.card-callout--good b                     { color: var(--intent-good-fg); }
.card-callout--cool .card-callout-icon    { color: var(--intent-info-fg);    background: var(--intent-info-bg-soft); }
.card-callout--cool b                     { color: var(--intent-info-fg); }
.card-callout--neutral .card-callout-icon { color: var(--intent-neutral-fg); background: var(--intent-neutral-bg-soft); }
.card-callout--neutral b                  { color: var(--intent-neutral-fg); }
/* "info" callout uses warn tone — semantically these are heads-up / caveat
   text ("Section rule:", "Why important:") rather than positive feedback. */
.card-callout--info .card-callout-icon    { color: var(--intent-warn-fg);    background: var(--intent-warn-bg-soft); }
.card-callout--info b                     { color: var(--intent-warn-fg); }
.card-callout--danger .card-callout-icon  { color: var(--intent-danger-fg);  background: var(--intent-danger-bg-soft); }
.card-callout--danger b                   { color: var(--intent-danger-fg); }
.card-callout--warn .card-callout-icon    { color: var(--intent-warn-fg);    background: var(--intent-warn-bg-soft); }
.card-callout--warn b                     { color: var(--intent-warn-fg); }

.choice-card {
  min-height: 232px;
}

/* Root-picker cards display the option title (e.g. "Return Theme") next to
   the root note. Used to abuse `.energy.energy-3` for this — now its own
   class with neutral styling so colour doesn't imply an energy level. */
.root-card-title {
  color: var(--muted);
  font-family: var(--font-display);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.review-card {
  min-height: 0;
}

.review-summary {
  grid-column: 1 / -1;
}

.review-suno {
  grid-column: 1 / -1;
  padding: 0; /* trigger handles its own padding */
}

.review-suno .suno-accordion-body {
  padding: 14px 16px 16px;
}

.review-verdict {
  margin: 4px 0 14px;
  padding: 10px 12px;
  border: 1px solid rgba(159, 227, 177, 0.16);
  border-radius: 10px;
  color: #dce8e2;
  background: rgba(159, 227, 177, 0.05);
}

.review-verdict strong {
  color: var(--mint);
}

.review-energy {
  border-color: rgba(216, 160, 75, 0.18);
  background:
    radial-gradient(circle at 84% 14%, rgba(216, 160, 75, 0.08), transparent 32%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.028), rgba(255, 255, 255, 0.01)),
    rgba(15, 19, 22, 0.9);
}

.review-list {
  display: grid;
  gap: 8px;
  margin: 4px 0 12px;
}

/* === Track structure flow — horizontal chip stream with arrows ===========
   Replaces the old vertical stack of full-width review-line cards. Each
   section becomes a compact chip; arrows between chips show the direction
   of motion through the song. flex-wrap lets long structures fall onto a
   second row naturally. */
.review-flow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 6px;
  margin: 6px 0 14px;
}

.review-chip {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  min-width: 96px;
  max-width: 220px;
  padding: 7px 11px 8px 13px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.025);
  /* Section-tone ribbon on the left edge — scans as a coloured timeline. */
  box-shadow: inset 3px 0 0 0 var(--section-tone, var(--text-faint));
}

.review-chip-num {
  color: var(--text-faint);
  font-family: var(--font-display);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.review-chip-name {
  color: var(--section-tone, var(--text-strong));
  font-family: var(--font-display);
  font-size: 0.92rem;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.review-chip-meta {
  color: var(--text-muted);
  font-size: 0.72rem;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.review-arrow {
  color: var(--text-faint);
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 400;
  line-height: 1;
  user-select: none;
  /* Sits centred between chips. flex-wrap will collapse a trailing arrow at
     the right edge of a row — that's intentional, it reads as "continues on
     the next line". */
  align-self: center;
}

.review-prompt-builder {
  margin: 10px 16px 18px;
  padding: 14px 14px 12px;
  border: 1px solid rgba(159, 227, 177, 0.12);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.03);
}

.review-prompt-field {
  display: grid;
  gap: 8px;
}

.review-prompt-label {
  color: var(--text-strong);
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.review-subgenre-select {
  width: 100%;
  min-height: 42px;
  padding: 0 14px;
  border: 1px solid rgba(221, 231, 233, 0.14);
  border-radius: 10px;
  color: var(--text);
  background: rgba(7, 12, 14, 0.92);
  font: inherit;
}

.review-subgenre-select:focus {
  outline: none;
  border-color: rgba(159, 227, 177, 0.42);
  box-shadow: 0 0 0 3px rgba(159, 227, 177, 0.12);
}

.review-prompt-hint {
  margin: 10px 0 0;
  color: var(--text-muted);
  font-size: 0.76rem;
  line-height: 1.45;
}

.review-prompt-preview {
  margin-top: 12px;
  display: grid;
  gap: 8px;
}

.review-prompt-preview-head {
  display: grid;
  gap: 3px;
}

.review-prompt-preview-head strong {
  color: var(--text-strong);
  font-family: var(--font-display);
  font-size: 0.76rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.review-prompt-preview-head span {
  color: var(--text-muted);
  font-size: 0.74rem;
  line-height: 1.4;
}

.review-prompt-meta {
  color: var(--text-faint);
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.review-prompt-output {
  width: 100%;
  min-height: 110px;
  padding: 14px;
  border: 1px solid rgba(221, 231, 233, 0.14);
  border-radius: 12px;
  color: #dfe7e4;
  background: rgba(7, 12, 14, 0.94);
  font-size: 0.8rem;
  line-height: 1.55;
  resize: vertical;
}

.review-prompt-output:focus {
  outline: none;
  border-color: rgba(159, 227, 177, 0.42);
  box-shadow: 0 0 0 3px rgba(159, 227, 177, 0.12);
}

.review-prompt-output--negative {
  min-height: 80px;
}

.review-prompt-output--structure {
  min-height: 160px;
}

.review-prompt-actions {
  grid-template-columns: 1.2fr 1fr;
  margin-top: 12px;
  border-top: 0;
  border-radius: 12px;
  overflow: hidden;
}

.review-prompt-actions--single {
  grid-template-columns: 1fr;
}

.review-list p {
  margin: 0;
  padding: 10px 12px;
  border: 1px solid rgba(221, 231, 233, 0.08);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.022);
}

.review-list p.review-warning {
  border-color: rgba(201, 84, 64, 0.22);
  background: rgba(201, 84, 64, 0.06);
}

.review-actions button {
  font-weight: 700;
}

.card-actions {
  display: grid;
  grid-template-columns: 1.7fr 1.1fr 0.6fr;
  margin-top: auto;
  border-top: 1px solid rgba(221, 231, 233, 0.12);
}

.card-actions.single {
  grid-template-columns: 1fr;
}

.card-actions button {
  min-height: 44px;
  border: 0;
  border-right: 1px solid rgba(221, 231, 233, 0.12);
  color: #e6ecea;
  background: rgba(255, 255, 255, 0.02);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.16s ease, color 0.16s ease;
}

.card-actions button:last-child {
  border-right: 0;
}

.card-actions button:hover {
  background: var(--intent-good-bg-soft);
}

.card-actions button.primary {
  background: var(--intent-good-bg-soft);
  color: var(--text);
  font-weight: 700;
}

.card-actions button.primary:hover {
  background: var(--intent-good-bg-strong);
  color: #07120c;
}

.card-actions button.primary span {
  color: var(--intent-good-fg);
  font-weight: 700;
}

.card-actions button.primary:hover span {
  color: #07120c;
}

.card-actions button.icon-only {
  padding: 0;
  font-size: 0;
  color: var(--faint);
}

.card-actions button.icon-only span {
  margin: 0;
  font-size: 1.05rem;
}

.card-actions button.icon-only:hover {
  color: var(--text);
}

.card-actions button.is-playing {
  color: #08110b;
  background: var(--toxic);
}

.card-actions span {
  margin-right: 6px;
}

/* === Cards toolbar (favorites filter + keyboard shortcut hints) === */
.cards-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  /* Vertical rhythm: 18px above (breathing room from choice-topline /
     next-move callout), 14px below (gap to cards-grid). Padding removed —
     0 4px previously left the toolbar 4px inset relative to topline above
     and cards-grid below, which read as misalignment. */
  margin: 12px 0 10px;
  padding: 0;
  flex-wrap: wrap;
}

.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px 5px 8px;
  border: 1px solid rgba(221, 231, 233, 0.18);
  border-radius: 999px;
  background: rgba(8, 11, 13, 0.78);
  color: var(--muted);
  font-family: var(--font-ui);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: border-color 0.16s ease, color 0.16s ease, background 0.16s ease;
}

.filter-chip:hover {
  border-color: var(--intent-warn-border-strong);
  color: var(--text);
}

.filter-chip:focus-visible {
  outline: none;
  border-color: var(--intent-warn-border-strong);
  box-shadow: 0 0 0 3px var(--intent-warn-glow);
}

.filter-chip.is-active {
  border-color: var(--intent-warn-border-strong);
  background: var(--intent-warn-bg-soft);
  color: var(--text);
  animation: chip-pop 0.22s ease-out;
}

.filter-chip.is-disabled,
.filter-chip[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

.filter-chip-icon {
  color: var(--intent-warn-fg);
  font-size: 0.95rem;
}

.filter-chip-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 18px;
  margin-left: 4px;
  padding: 0 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-faint);
  font-size: 0.7rem;
  font-weight: 600;
}

.filter-chip.is-active .filter-chip-count {
  background: var(--intent-warn-bg-strong);
  color: #1a1308;
}

.cards-shortcuts {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--faint);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
}

.cards-shortcuts .shortcut {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.cards-shortcuts kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  padding: 2px 6px;
  border: 1px solid rgba(221, 231, 233, 0.16);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--muted);
  font-family: var(--font-ui);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.cards-empty {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 32px 16px;
  border: 1px dashed rgba(221, 231, 233, 0.16);
  border-radius: var(--radius-lg);
  color: var(--muted);
  text-align: center;
  font-size: 0.86rem;
}

.cards-empty-message {
  margin: 0;
  max-width: 420px;
}

.cards-empty-reset {
  padding: 8px 18px;
  border: 1px solid rgba(159, 227, 177, 0.32);
  border-radius: 999px;
  background: rgba(159, 227, 177, 0.10);
  color: #c7f5d0;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.cards-empty-reset:hover {
  background: rgba(159, 227, 177, 0.18);
  border-color: rgba(159, 227, 177, 0.5);
}

/* Mood chips that would show an empty deck for the current section */
.mood-chip.is-empty,
.mood-chip[disabled] {
  opacity: 0.35;
  cursor: not-allowed;
  pointer-events: none;
}

.micro-tip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: auto;
  padding-top: 18px;
  font-size: 0.9rem;
}

.micro-tip p {
  margin: 0;
}

.micro-tip span {
  color: var(--amber);
}

.bottom-dock {
  display: grid;
  grid-template-columns:
    minmax(146px, 1fr)        /* Section */
    minmax(108px, 0.72fr)     /* Root Note */
    auto                       /* divider */
    minmax(280px, 1.45fr)     /* Mood chips */
    auto                       /* divider */
    minmax(132px, 0.95fr)     /* Playback */
    minmax(118px, 0.82fr)     /* BPM */
    minmax(98px, 0.64fr)      /* Repeats */
    minmax(92px, 0.6fr)       /* Octave */
    minmax(150px, 1fr);       /* Preview Mix */
  gap: 6px;
  align-items: stretch;
  padding: 6px;
  background:
    linear-gradient(180deg, rgba(18, 22, 26, 0.96), rgba(8, 10, 12, 0.95)),
    #090b0d;
  box-shadow: 0 22px 54px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.dock-divider {
  align-self: stretch;
  width: 1px;
  margin: 6px 2px;
  background: linear-gradient(
    180deg,
    rgba(221, 231, 233, 0.0) 0%,
    rgba(221, 231, 233, 0.15) 30%,
    rgba(221, 231, 233, 0.15) 70%,
    rgba(221, 231, 233, 0.0) 100%
  );
}

.mood-chip-block {
  min-width: 0;
}

.mood-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
}

.mood-chip {
  padding: 5px 10px;
  border: 1px solid rgba(221, 231, 233, 0.14);
  border-radius: 999px;
  background: rgba(8, 11, 13, 0.72);
  color: var(--muted);
  font-family: var(--font-ui);
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: border-color 0.16s ease, color 0.16s ease, background 0.16s ease, transform 0.12s ease;
  white-space: nowrap;
}

.mood-chip:hover {
  border-color: var(--intent-good-border);
  color: var(--text);
}

.mood-chip:focus-visible {
  outline: none;
  border-color: var(--intent-good-border-strong);
  box-shadow: 0 0 0 3px var(--intent-good-glow);
}

.mood-chip.is-active {
  border-color: var(--intent-good-border-strong);
  background: var(--intent-good-bg-soft);
  color: var(--text);
  font-weight: 600;
  /* Crisp bounce when the chip becomes active. Browsers re-trigger this each
     time `.is-active` is freshly applied, so picking another chip animates
     the new winner. */
  animation: chip-pop 0.22s ease-out;
}

.mood-chip.is-active:hover {
  background: var(--intent-good-bg-strong);
}

.mood-chip:active {
  transform: translateY(1px);
}

.control-block {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  min-height: 58px;
  padding: 6px 8px;
  border: 1px solid rgba(221, 231, 233, 0.1);
  border-radius: 12px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.028), rgba(255, 255, 255, 0.01)),
    rgba(14, 18, 21, 0.82);
}

.control-block span:first-child {
  margin-bottom: 5px;
}

.control-block select {
  min-height: 32px;
  width: 100%;
  border: 1px solid rgba(221, 231, 233, 0.12);
  border-radius: 9px;
  padding: 0 9px;
  background: rgba(5, 8, 10, 0.74);
  outline: none;
  appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, rgba(237, 243, 241, 0.78) 50%),
    linear-gradient(135deg, rgba(237, 243, 241, 0.78) 50%, transparent 50%);
  background-position: calc(100% - 13px) 13px, calc(100% - 8px) 13px;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.control-block select:hover {
  border-color: rgba(159, 227, 177, 0.28);
}

.control-block select:focus {
  border-color: rgba(159, 227, 177, 0.5);
  box-shadow: 0 0 0 3px rgba(159, 227, 177, 0.08);
}

.control-block select option {
  color: var(--text);
  background: #05080a;
}

.control-block small {
  margin-top: 4px;
  color: var(--mint);
  font-size: 0.7rem;
}

.mix-block {
  min-width: 0;
}

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

.speaker {
  width: 18px;
  min-width: 18px;
  color: var(--mint);
  font-size: 1rem;
}

input[type="range"] {
  width: 100%;
  min-width: 0;
  accent-color: var(--mint);
}

.toast {
  position: fixed;
  right: 22px;
  bottom: 118px;
  z-index: 5;
  max-width: 340px;
  padding: 12px 14px;
  border: 1px solid rgba(159, 227, 177, 0.34);
  border-radius: 12px;
  color: #ebf7ee;
  background: rgba(9, 13, 15, 0.92);
  box-shadow: 0 20px 44px rgba(0, 0, 0, 0.38), 0 0 24px rgba(159, 227, 177, 0.08);
  opacity: 0;
  transform: translateY(10px);
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.toast.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.toast.is-clickable {
  cursor: pointer;
  border-color: rgba(216, 160, 75, 0.5);
  box-shadow: 0 20px 44px rgba(0, 0, 0, 0.42), 0 0 24px rgba(216, 160, 75, 0.18);
}

.toast.is-clickable.is-visible {
  pointer-events: auto;
}

.toast.is-clickable:hover {
  border-color: rgba(216, 160, 75, 0.85);
}

@media (max-width: 1440px) {
  .cards-grid {
    grid-template-columns: repeat(2, minmax(240px, 1fr));
  }

  .bottom-dock {
    overflow-x: auto;
    overflow-y: hidden;
  }
}

@media (max-width: 1160px) {
  body {
    overflow: auto;
  }

  .app-shell {
    height: auto;
    min-height: 100vh;
    grid-template-rows: auto auto auto;
  }

  .app-header,
  .brand-copy,
  .header-meta,
  .choice-topline {
    flex-wrap: wrap;
  }

  .brand-subtitle::before {
    display: none;
  }

  .dashboard-grid {
    grid-template-columns: 1fr;
  }

}

@media (max-width: 760px) {
  .app-shell {
    padding: 8px;
  }

  .app-header,
  .track-panel,
  .choice-panel,
  .bottom-dock {
    border-radius: 18px;
  }

  .brand-logo {
    height: 36px;
    max-width: min(260px, 58vw);
  }

  .tuning-chip {
    width: 100%;
    margin: 2px 0 0;
  }

  /* Touch-only viewport: native HTML5 drag is unreliable on mobile and the
     drag-handle would just steal space. Hide it; Up/Down buttons in the
     2x2 action grid handle reorder there. */
  .drag-handle {
    display: none;
  }

  .track-item {
    grid-template-columns: 34px 2px minmax(0, 1fr) auto;
  }

  .choice-panel {
    padding: 18px 14px 16px;
  }

  .cards-grid {
    grid-template-columns: 1fr;
  }

  /* On touch viewports keyboard hints aren't useful and just steal space */
  .cards-shortcuts {
    display: none;
  }

  .cards-toolbar {
    justify-content: flex-start;
  }

  /* Mood chips wrap nicely; just allow scroll on the dock so they don't get squeezed */
  .mood-chips {
    flex-wrap: wrap;
  }
}

/* === Reduced-motion accessibility override ==============================
   Users with motion sensitivity (vestibular disorders, migraines) or who've
   set "Reduce motion" at the OS level get instant, transition-less state
   changes for everything we just animated above. The !important is needed
   because some animations are applied via inline rules with their own
   timing values that we want to flatly override here. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================
   SECTION BACKGROUND IMAGES — choice-cards
   ============================================================ */

/* 1. Base: replace the forged-plate gradient with a section photo + dark
      overlay so text stays readable over the image. --choice-bg holds the
      URL and is overridden per [data-section] below. Root-picker cards that
      carry no data-section use the fallback image. */
.harmony-card.choice-card {
  --choice-bg: url("backgrounds/18.png");
  background-color: #040607;
  background-image:
    linear-gradient(180deg,
      rgba(4, 6, 7, 0.44) 0%,
      rgba(4, 6, 7, 0.66) 50%,
      rgba(4, 6, 7, 0.88) 100%),
    var(--choice-bg);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  background-attachment: scroll;
}

/* 2. Per-section background images (next-step choice cards). */
.harmony-card.choice-card[data-section="intro"]     { --choice-bg: url("backgrounds/10.png"); }
.harmony-card.choice-card[data-section="verse"]     { --choice-bg: url("backgrounds/11.png"); }
.harmony-card.choice-card[data-section="prechorus"] { --choice-bg: url("backgrounds/12.png"); }
.harmony-card.choice-card[data-section="chorus"]    { --choice-bg: url("backgrounds/13.png"); }
.harmony-card.choice-card[data-section="bridge"]    { --choice-bg: url("backgrounds/14.png"); }
.harmony-card.choice-card[data-section="solo"]      { --choice-bg: url("backgrounds/15.png"); }
.harmony-card.choice-card[data-section="breakdown"] { --choice-bg: url("backgrounds/16.png"); }
.harmony-card.choice-card[data-section="outro"]     { --choice-bg: url("backgrounds/17.png"); }

/* === Suno accordion =====================================================
   The Suno export card is optional and hidden by default so it doesn't
   crowd the review panel. A single toggle button reveals the full block. */

/* .suno-header is no longer used — the trigger IS the header row */

/* Full-width accordion trigger that acts as the entire card header */
.suno-accordion-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 10px 16px;
  border: none;
  border-radius: inherit;
  background: transparent;
  font: inherit;
  cursor: pointer;
  transition: background 0.15s;
  gap: 12px;
}

.suno-accordion-trigger:hover {
  background: rgba(159, 227, 177, 0.05);
}

/* Left cluster: "Optional Export" tag + "Suno AI" title */
.suno-trigger-left {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.suno-trigger-title {
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--text);
}

/* Right cluster: action label + chevron */
.suno-trigger-right {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--text-muted);
  font-size: 0.78rem;
  white-space: nowrap;
}

.suno-trigger-right:hover {
  color: var(--text);
}

.suno-chevron {
  font-size: 0.6rem;
  transition: transform 0.2s ease;
  display: inline-block;
  color: var(--text-muted);
}

.suno-chevron.is-open {
  transform: rotate(180deg);
}

.suno-accordion-body {
  padding: 0 16px;
  margin-top: 0;
  border-top: 1px solid rgba(176, 188, 192, 0.10);
}

.suno-accordion-body.is-hidden {
  display: none;
}

/* === Compact prompt blocks ==============================================
   Each of the three Suno output areas (style prompt, negative prompt,
   structure template) is wrapped in .prompt-block. The heading row
   carries a compact copy icon button on the right so there is no need
   for a separate row of action buttons below each textarea. */

.prompt-block {
  margin-top: 16px;
}

.prompt-block-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}

.prompt-block-title {
  display: block;
  color: var(--text-strong);
  font-family: var(--font-display);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.prompt-block-usage {
  display: block;
  color: var(--text-muted);
  font-size: 0.72rem;
  line-height: 1.4;
  margin-top: 2px;
}

.prompt-block-copy {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid rgba(221, 231, 233, 0.14);
  border-radius: 7px;
  color: var(--text-muted);
  background: transparent;
  font-size: 0.9rem;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}

.prompt-block-copy:hover {
  color: var(--text);
  border-color: rgba(159, 227, 177, 0.32);
  background: rgba(159, 227, 177, 0.06);
}

.prompt-block-meta {
  color: var(--text-faint);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-bottom: 4px;
}

/* Generate button — full width, sits between the subgenre select and the
   prompt blocks so the user sees it as the primary action trigger. */
.review-prompt-actions--generate {
  grid-template-columns: 1fr;
  margin-top: 14px;
}
