/* src/components/Knob.css */
.knob {
  cursor: grab;
  user-select: none;
  display: block;
  flex-shrink: 0;
}
.knob:active {
  cursor: grabbing;
}
.knob__bg {
  fill: rgba(255, 255, 255, 0.06);
  stroke: rgba(255, 255, 255, 0.4);
  stroke-width: 1.5;
  transition: stroke 0.12s, fill 0.12s;
}
.knob:hover .knob__bg {
  stroke: var(--c-accent);
  fill: rgba(174, 191, 214, 0.12);
}
.knob__indicator {
  stroke: var(--c-accent);
  stroke-width: 2;
  stroke-linecap: round;
  transition: stroke 0.12s;
}
.knob--unset .knob__indicator {
  stroke: var(--c-text3);
}
.knob--unset:hover .knob__indicator {
  stroke: var(--c-accent);
}
.knob--disabled {
  opacity: 0.35;
  cursor: not-allowed;
  pointer-events: none;
}

/* src/components/ConfirmModal.css */
.cm-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  font-family:
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    sans-serif;
}
.cm-card {
  background: var(--c-surface2);
  border: 1px solid var(--c-border2);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
  padding: 18px 20px 14px;
  max-width: 420px;
  width: calc(100% - 40px);
  color: var(--c-text);
}
.cm-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--c-text);
  margin-bottom: 8px;
}
.cm-body {
  font-size: 12px;
  color: var(--c-text2);
  line-height: 1.5;
  margin-bottom: 16px;
}
.cm-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
.cm-btn {
  font-size: 12px;
  padding: 6px 14px;
  border-radius: 5px;
  border: 1px solid var(--c-border2);
  background: var(--c-surface);
  color: var(--c-text2);
  transition:
    background 0.1s,
    color 0.1s,
    border-color 0.1s;
}
.cm-btn:hover {
  color: var(--c-text);
  border-color: var(--c-text3);
}
.cm-btn--ghost {
}
.cm-btn--primary {
  background: var(--c-accent);
  border-color: var(--c-accent2);
  color: var(--c-accent-ink);
}
.cm-btn--primary:hover {
  background: var(--c-accent2);
  border-color: var(--c-accent);
  color: var(--c-accent-ink);
}

/* src/components/DurationToggle.css */
.dur-toggle {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-start;
}
.dur-toggle__bars {
  display: flex;
  align-items: center;
  gap: 4px;
}
.dur-toggle__bar {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  border: 1px solid rgba(255, 255, 255, 0.45);
  background: rgba(255, 255, 255, 0.06);
  cursor: pointer;
  padding: 0;
  transition:
    background 0.1s,
    border-color 0.1s,
    opacity 0.1s;
}
.dur-toggle__bar:hover:not(.completed):not(.translucent):not(.blocked) {
  border-color: var(--accent, var(--c-accent));
  background: color-mix(in srgb, var(--accent, var(--c-accent)) 22%, transparent);
}
.dur-toggle__bar.completed {
  background: var(--accent, var(--c-accent));
  border-color: var(--accent, var(--c-accent));
}
.dur-toggle__bar.completed:hover {
  filter: brightness(1.15);
}
.dur-toggle__bar.translucent {
  background: color-mix(in srgb, var(--accent, var(--c-accent)) calc(var(--bar-fill, 0.25) * 100%), transparent);
  border-color: var(--accent, var(--c-accent));
}
.dur-toggle__bar.translucent:hover {
  background: color-mix(in srgb, var(--accent, var(--c-accent)) calc((var(--bar-fill, 0.25) + 0.12) * 100%), transparent);
}
.dur-toggle__bar.blocked {
  opacity: 0.18;
  cursor: not-allowed;
}
.dur-toggle__bar-multiplier {
  font-size: 9px;
  color: var(--c-text3);
  margin-left: 2px;
  font-family: var(--font-mono, monospace);
}
.dur-toggle__beats {
  display: flex;
  gap: 4px;
}
.dur-toggle__beat {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, 0.5);
  background: rgba(255, 255, 255, 0.08);
  cursor: pointer;
  padding: 0;
  transition:
    background 0.1s,
    border-color 0.1s,
    opacity 0.1s;
}
.dur-toggle__beat:hover:not(.active):not(.blocked) {
  border-color: var(--accent, var(--c-accent));
  background: color-mix(in srgb, var(--accent, var(--c-accent)) 22%, transparent);
}
.dur-toggle__beat.active {
  background: var(--accent, var(--c-accent));
  border-color: var(--accent, var(--c-accent));
}
.dur-toggle__beat.blocked {
  opacity: 0.18;
  cursor: not-allowed;
}

/* src/components/VoicingTemplatePicker.css */
.vtp-panel {
  font-family:
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    sans-serif;
  font-size: 12px;
  background: var(--c-surface2);
  border: 1px solid var(--c-border2);
  border-radius: var(--radius-md);
  overflow: hidden;
  width: 360px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.55);
  position: absolute;
  z-index: 300;
  top: calc(100% + 6px);
  left: 0;
}
.vtp-header {
  font-size: 11px;
  font-weight: 600;
  color: var(--c-text);
  padding: 8px 10px;
  border-bottom: 1px solid var(--c-border);
}
.vtp-body {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 8px;
  max-height: 320px;
  overflow-y: auto;
}
.vtp-col {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.vtp-col__header {
  font-size: 9px;
  color: var(--c-text3);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 2px 4px 4px;
  opacity: 0.75;
}
.vtp-item {
  display: block;
  width: 100%;
  font-size: 11px;
  color: var(--c-text2);
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: 4px;
  padding: 5px 8px;
  text-align: left;
  transition:
    background 0.1s,
    color 0.1s,
    border-color 0.1s;
}
.vtp-item:hover {
  background: var(--c-surface2);
  color: var(--c-text);
  border-color: var(--c-text3);
}
.vtp-item.active {
  color: var(--c-accent);
  border-color: var(--c-accent2);
  background: rgba(174, 191, 214, 0.12);
}
.vtp-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  border-top: 1px solid var(--c-border);
  background: var(--c-surface);
}
.vtp-footer__text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.vtp-footer__label {
  font-size: 11px;
  font-weight: 600;
  color: var(--c-text);
}
.vtp-footer__hint {
  font-size: 9px;
  color: var(--c-text3);
  opacity: 0.8;
}
.vtp-switch {
  flex: 0 0 auto;
  width: 34px;
  height: 18px;
  border-radius: 9px;
  border: 1px solid var(--c-border2);
  background: var(--c-surface2);
  position: relative;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.vtp-switch__knob {
  position: absolute;
  top: 1px;
  left: 1px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--c-text3);
  transition: transform 0.15s, background 0.15s;
}
.vtp-switch.on {
  background: rgba(174, 191, 214, 0.25);
  border-color: var(--c-accent2);
}
.vtp-switch.on .vtp-switch__knob {
  transform: translateX(16px);
  background: var(--c-accent);
}

/* src/components/TextProgressionEntry.css */
.tpe-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-top: 12vh;
  z-index: 1000;
}
.tpe-card {
  background: var(--c-surface);
  border: 1px solid var(--c-border2);
  border-radius: var(--radius-lg);
  width: min(900px, calc(100vw - 48px));
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
}
.tpe-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--c-border);
  background: var(--c-surface2);
  font-size: 13px;
  flex-wrap: wrap;
}
.tpe-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 5px;
  background: var(--c-accent);
  color: var(--c-accent-ink);
  font-family: "SF Mono", monospace;
  font-weight: 600;
  font-size: 13px;
}
.tpe-label {
  color: var(--c-text);
  font-weight: 500;
}
.tpe-help {
  color: var(--c-text2);
  font-size: 12px;
}
.tpe-help kbd {
  padding: 1px 6px;
  background: var(--c-surface);
  border: 1px solid var(--c-border2);
  border-radius: 3px;
  font-family: "SF Mono", monospace;
  font-size: 11px;
  color: var(--c-text);
}
.tpe-target {
  margin-left: auto;
  color: var(--c-text2);
  font-size: 12px;
  display: flex;
  gap: 8px;
  align-items: baseline;
}
.tpe-target__name {
  color: var(--c-text);
  font-weight: 500;
}
.tpe-target__key {
  color: var(--c-text3);
  font-family: "SF Mono", monospace;
  font-size: 11px;
}
.tpe-input {
  width: 100%;
  padding: 16px 18px;
  font-size: 18px;
  background: var(--c-surface);
  color: var(--c-text);
  border: none;
  border-bottom: 1px solid var(--c-border);
  outline: none;
  resize: none;
  min-height: 60px;
  max-height: 180px;
  font-family: "SF Mono", monospace;
  line-height: 1.4;
  overflow-y: auto;
}
.tpe-input::placeholder {
  color: var(--c-text3);
  white-space: pre-line;
  line-height: 1.4;
  font-size: 13px;
}
.tpe-input:focus {
  background: var(--c-bg);
}
.tpe-preview {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px 18px;
  min-height: 84px;
  align-items: stretch;
  background: var(--c-surface);
  flex: 1 1 auto;
  overflow-y: auto;
}
.tpe-preview__hint {
  color: var(--c-text3);
  font-style: italic;
  font-size: 13px;
}
.tpe-preview-section {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.tpe-preview-section__label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-text2);
  padding-bottom: 2px;
  border-bottom: 1px solid var(--c-border);
}
.tpe-preview-section--named .tpe-preview-section__label {
  color: var(--cl-stable);
  border-bottom-color: var(--cl-stable);
}
.tpe-preview-section__pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: flex-start;
}
.tpe-pill {
  position: relative;
  min-width: 78px;
  padding: 8px 12px 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--c-border2);
  background: var(--c-surface2);
  display: flex;
  flex-direction: column;
  gap: 2px;
  transition:
    transform 80ms ease,
    box-shadow 120ms ease,
    border-color 120ms ease;
  text-align: left;
  font: inherit;
  color: inherit;
}
.tpe-pill--actionable {
  cursor: pointer;
}
.tpe-pill--actionable:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
}
.tpe-pill--actionable:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
}
.tpe-pill__name {
  font-size: 14px;
  font-weight: 500;
  color: var(--c-text);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}
.tpe-pill__glyph {
  font-size: 10px;
  font-family: "SF Mono", monospace;
}
.tpe-pill__glyph--ok {
  color: var(--cl-stable);
}
.tpe-pill__glyph--warn {
  color: var(--cl-tension);
}
.tpe-pill__glyph--err {
  color: var(--cl-tension);
}
.tpe-pill__glyph--rest {
  color: var(--c-text3);
}
.tpe-pill__sub {
  font-size: 11px;
  color: var(--c-text2);
  letter-spacing: 0.01em;
}
.tpe-pill__accent {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 3px;
  border-bottom-left-radius: var(--radius-md);
  border-bottom-right-radius: var(--radius-md);
}
.tpe-pill__roman {
  font-family: "SF Mono", monospace;
  font-size: 11px;
  color: var(--c-accent);
  border-bottom: 1px dotted var(--c-accent2);
  display: inline-block;
  padding-bottom: 1px;
}
.tpe-pill__alt-link {
  color: var(--c-accent);
  border-bottom: 1px dashed var(--c-accent2);
  padding-bottom: 1px;
  font-weight: 500;
}
.tpe-pill--actionable:hover .tpe-pill__alt-link {
  border-bottom-style: solid;
}
.tpe-pill--unknown {
  background: transparent;
  border-style: dashed;
}
.tpe-pill--unknown .tpe-pill__name {
  color: var(--c-text3);
  font-family: "SF Mono", monospace;
  font-size: 13px;
}
.tpe-pill--rest {
  min-width: 36px;
  background: transparent;
  border-style: dashed;
  opacity: 0.6;
}
.tpe-pill--rest .tpe-pill__name {
  color: var(--c-text3);
  justify-content: center;
}
.tpe-pill--rest .tpe-pill__accent {
  display: none;
}
.tpe-pill--ambig {
  border-color: var(--cl-tension);
}
.tpe-pill--typo {
  border-color: var(--cl-tension);
  border-style: dashed;
  background: transparent;
}
.tpe-pill--typo .tpe-pill__name {
  font-family: "SF Mono", monospace;
  font-size: 13px;
  color: var(--c-text2);
}
.tpe-footer {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 18px;
  border-top: 1px solid var(--c-border);
  background: var(--c-surface2);
}
.tpe-stats {
  color: var(--c-text2);
  font-size: 12px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tpe-actions {
  display: flex;
  gap: 8px;
}
.tpe-btn {
  padding: 8px 14px;
  background: var(--c-surface);
  color: var(--c-text);
  border: 1px solid var(--c-border2);
  border-radius: var(--radius-sm);
  font-size: 13px;
  cursor: pointer;
  transition: background 80ms ease, border-color 80ms ease;
}
.tpe-btn:hover {
  background: var(--c-surface2);
  border-color: var(--c-text3);
}
.tpe-btn--primary {
  background: var(--c-accent);
  border-color: var(--c-accent);
  color: var(--c-accent-ink);
  font-weight: 500;
}
.tpe-btn--primary:hover {
  background: var(--c-accent2);
  border-color: var(--c-accent2);
}
.tpe-btn--primary:disabled {
  background: var(--c-surface2);
  border-color: var(--c-border);
  color: var(--c-text3);
  cursor: not-allowed;
}

/* appended from cfg.cssEntry */
:root {
  --c-bg:          #0f0f11;
  --c-surface:     #17171a;
  --c-surface2:    #1e1e22;
  --c-border:      rgba(255,255,255,0.08);
  --c-border2:     rgba(255,255,255,0.14);
  --c-text:        #f0f0f0;
  --c-text2:       #a8a8bc;
  --c-text3:       #72728a;
  /* v123: chrome accent decoupled from the Stable strand. Chrome is now the
     AT-7 "bright steel" (#aebfd6, ex-section-marker diamond); the signature
     purple survives as --cl-stable ONLY. Steel is light, so filled-accent
     surfaces use --c-accent-ink for legible text instead of white. */
  --c-accent:      #aebfd6;
  --c-accent2:     #7e8ba3;
  --c-accent-ink:  #14161b;
  /* v75 G-1: cool-blue selection / group color. Distinct from the purple
     accent so transient multi-select + persistent group rings stand apart
     from the rest of the UI. Used by .tl-pill.in-selection / .in-group. */
  --c-select:      #4dabf7;
  --radius-sm:     4px;
  --radius-md:     6px;
  --radius-lg:     8px;

  /* v75 colour scheme (Julian 2026-05-09): cluster palette redone for
     visual distinctness. Prior values had two greens (stable+momentum)
     that read identical at a glance, and --cl-color was the same hex
     as --c-accent so cluster-tinted UI conflated with selection state.
     New palette: green / orange / magenta / sky-blue — 4 distinct hues
     across the wheel, none of which collide with --c-accent purple. */
  /* v123 (Julian 2026-06): stable = royal blue, the COOL pole of a
     tension<->resolve hue axis (warm strands want to move, cool is home).
     Decoupled from chrome (now steel) so blue reads "home", not "selected". */
  --cl-stable:     #3a56d4;
  --cl-stable-bg:  rgba(58,86,212,0.15);
  /* v123: tension = red — the strongest pull back home (swapped with remote,
     which took the orange). Red anchors the hot end of the axis. */
  --cl-tension:    #cc3a3a;
  --cl-tension-bg: rgba(204,58,58,0.15);
  --cl-color:      #c66ad8;  /* magenta — modal interchange, color chords */
  --cl-color-bg:   rgba(198,106,216,0.15);
  --cl-momentum:   #4ea0d8;  /* sky     — secondary dominants, II-V moves */
  --cl-momentum-bg:rgba(78,160,216,0.15);

  /* v75 round 4 (Julian 2026-05-09): modal cluster — for chords that
     introduce notes out of the section's key (modal interchange, etc.).
     Distinct from --cl-color (in-key extensions stay magenta) so the
     drawer's modal-interchange chips and timeline pills no longer look
     the same as 9/11 chords. Rose pink — clearly off the green/orange/
     magenta/sky wheel. */
  --cl-modal:      #c06090;
  --cl-modal-bg:   rgba(192,96,144,0.15);

  /* remote cluster — tritone subs and V alternatives, the most chromatic
     options. v123 swapped this to orange (Tension took the red); stays in
     the warm half, clearly off the new red tension. */
  --cl-remote:     #e07050;
  --cl-remote-bg:  rgba(224,112,80,0.15);

  /* v75 colour scheme: off-chord note amber. Used by PatternEditor cells
     when the pitch played falls outside the active chord. Distinct from
     the cluster colours, signals "deliberately spicy". */
  --c-off-chord:   #e6b042;
  --c-off-chord-bg:rgba(230,176,66,0.18);

  /* v75 round 5 (Julian 2026-05-09): pattern-element colour now chrome —
     a steel/slate blue-grey that sits clearly off the purple home-base
     and the cotton-candy / rose / orange / sky cluster hues. Pattern
     pills + velocity bars share this swatch. */
  --c-pattern:     #7d8a9c;
  --c-pattern-bg:  rgba(125,138,156,0.55);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html, body, #root {
  height: 100%;
  background: var(--c-bg);
  color: var(--c-text);
  font-family: 'Hanken Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

button {
  font-family: inherit;
  font-size: inherit;
  cursor: pointer;
  border: none;
  background: none;
  color: inherit;
}

code, .mono {
  font-family: 'IBM Plex Mono', 'SF Mono', 'Fira Code', monospace;
}

/* v75 (Julian 2026-05-09): shared play-button style. Sideways-triangle
   inside a 32×32 circle, fills with accent when playing. Used by
   PatternEditor, ChordTimeline "Play section", and Arrangement "Play
   song" — consistent transport affordance across the product. */
.play-btn {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid var(--c-border2);
  background: transparent;
  color: var(--c-text2);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
  transition: background 0.1s, color 0.1s, border-color 0.1s;
}
.play-btn:hover {
  background: rgba(174, 191, 214, 0.15);
  border-color: var(--c-accent);
  color: var(--c-accent);
}
.play-btn.playing {
  background: var(--c-accent);
  border-color: var(--c-accent);
  color: var(--c-accent-ink);
}
.play-btn__icon {
  font-size: 11px;
  line-height: 1;
  margin-left: 1px;  /* triangle optical centering */
}
.play-btn.playing .play-btn__icon { margin-left: 0; }
.play-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
