/* ── DAWTER, embedded ───────────────────────────────────────────────────────
   The demo library on the landing page is the real interface rather than a
   picture of one: class names, colours, icons, column widths and the waveform
   routine are taken from the app (public/index.html, public/theme.css). The
   app's tokens are scoped to .app so the page's own palette is left alone. */

.app {
  --bg-primary: #0f0f0f;
  --bg-secondary: #191919;
  --bg-hover: #3a3a3a;
  --app-border: #333;
  --text-primary: #f0f0f0;
  --text-secondary: #aaa;
  --text-hover: #70adc2;
  --text-muted: #555;
  --accent: #1da7b9;

  position: relative;
  margin-top: 56px;
  overflow: hidden;
  border: 1px solid var(--app-border);
  border-radius: 14px;
  background: var(--bg-primary);
  color: var(--text-primary);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  box-shadow: 0 40px 120px -40px rgba(29, 167, 185, .28);
}

/* ── header ──
   One bar, as in the app: macOS draws the window buttons into the header
   itself, which is why there is no separate title bar above it. */
.app-header {
  position: relative;
  display: flex; align-items: center; gap: 14px;
  height: 52px; padding: 0 16px 0 14px;
  background: var(--bg-primary);
  border-bottom: 1px solid var(--bg-hover);
}
.app-lights { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.app-lights i { width: 11px; height: 11px; border-radius: 50%; display: block; }
.app-lights i:nth-child(1) { background: #ff5f57; }
.app-lights i:nth-child(2) { background: #febc2e; }
.app-lights i:nth-child(3) { background: #28c840; }

.app-search { flex: 1; max-width: 280px; min-width: 90px; }
.app-search input {
  width: 100%;
  background: var(--bg-secondary);
  border: 1px solid var(--bg-secondary);
  border-radius: 8px;
  padding: 7px 12px;
  color: var(--text-primary);
  font-family: inherit; font-size: 13px;
  outline: none;
}
.app-search input::placeholder { color: var(--text-muted); }
.app-search input:focus { border-color: var(--text-muted); }
.app-wordmark {
  position: absolute; left: 50%; transform: translateX(-50%);
  font-size: 14px; font-weight: 700; letter-spacing: 3px;
  color: var(--text-primary); pointer-events: none;
}
.app-stats {
  flex: 1; text-align: right;
  font-size: 11.5px; color: var(--text-secondary); line-height: 1.35;
}

/* ── body: icon rail + table ──
   A fixed height, so opening the player doesn't resize the window. The rail is
   a flex child and stretches the whole way down on its own; the bubble floats
   over the empty space below the rows. */
.app-body { display: flex; min-height: 364px; }

/* The rail plus the notes panel. Opening notes widens this and pushes the
   table right; the table keeps its width and the overflow is clipped by .app,
   which is how the app behaves. */
.app-sidebar {
  display: flex; flex-shrink: 0;
  width: 52px;
  background: var(--bg-secondary);
  transition: width .2s ease;
}
.app-sidebar.open { width: 320px; }

.app-notes {
  display: none; flex-direction: column;
  width: 268px; flex-shrink: 0; min-width: 0;
  border-left: 1px solid var(--bg-hover);
}
.app-sidebar.open .app-notes { display: flex; }

.notes-head {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px; border-bottom: 1px solid var(--bg-hover);
}
.notes-title {
  flex: 1; min-width: 0;
  font-size: 12.5px; font-weight: 600; color: var(--text-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.notes-close {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--text-muted); font-size: 12px;
}
.notes-close:hover { color: var(--text-hover); }

.notes-list { flex: 1; min-height: 0; overflow-y: auto; padding: 2px 0; }
.note-item {
  display: flex; gap: 8px; align-items: baseline;
  padding: 9px 12px;
  font-size: 12px; color: var(--text-secondary); line-height: 1.45;
}
.note-item + .note-item { border-top: 1px solid var(--bg-hover); }
.note-item span { flex: 1; min-width: 0; }
.notes-empty { padding: 14px 12px; font-size: 12px; color: var(--text-muted); line-height: 1.5; }

.notes-composer {
  display: flex; align-items: center; gap: 6px;
  padding: 8px 10px; border-top: 1px solid var(--bg-hover);
}
/* The app's "add timestamp": accent means the note will be pinned to the
   playhead, so clicking it in the list jumps back to that moment. */
.notes-stamp {
  flex-shrink: 0;
  background: none; border: 1px solid var(--bg-hover); border-radius: 10px;
  padding: 3px 7px; cursor: pointer;
  color: var(--text-muted); font: 500 10.5px/1 var(--mono);
  font-variant-numeric: tabular-nums;
}
.notes-stamp.on { border-color: var(--accent); color: var(--accent); }
.notes-composer input {
  flex: 1; min-width: 0;
  background: var(--bg-primary); border: 1px solid var(--bg-hover);
  border-radius: 7px; padding: 6px 8px;
  color: var(--text-primary); font-family: inherit; font-size: 12px;
  outline: none;
}
.notes-composer input:focus { border-color: var(--text-muted); }
.notes-post {
  flex-shrink: 0;
  background: none; border: 1px solid var(--accent); border-radius: 7px;
  padding: 5px 9px; cursor: pointer;
  color: var(--accent); font-family: inherit; font-size: 11.5px; font-weight: 600;
}
.notes-post:hover { background: var(--accent); color: var(--bg-primary); }

.app-rail {
  width: 52px; flex-shrink: 0;
  padding: 8px 0;
  display: flex; flex-direction: column; gap: 2px;
  background: var(--bg-secondary);
}
.rail-tab {
  height: 38px;
  display: grid; place-items: center;
  border-left: 2px solid transparent;
  color: var(--text-muted);
  background: none; border-top: 0; border-right: 0; border-bottom: 0;
  cursor: pointer;
  transition: color .1s, background .1s;
}
.rail-tab svg { display: block; }
.rail-tab:hover { background: var(--bg-hover); color: var(--text-secondary); }
.rail-tab.active { background: var(--bg-hover); border-left-color: var(--accent); color: var(--accent); }

.app-table-wrap { flex: 1; min-width: 0; }

/* Fixed layout, so the header row sets the widths and nothing sprawls. Widths
   are the app's own; Name is the one flexible column and takes what is left,
   never dropping below the app's 200px. */
.app table { width: 100%; border-collapse: collapse; font-size: 13px; table-layout: fixed; }
.app .col-daw { width: 50px; }
.app .col-name { width: auto; min-width: 200px; }
.app .col-play { width: 52px; }
.app .col-tempo { width: 70px; }
.app .col-key { width: 130px; }
.app .col-saved { width: 48px; }
.app .col-tier { width: 110px; }
.app .col-modified { width: 90px; }
.app .col-bounces { width: 70px; }
.app .col-notes { width: 60px; }
.app .col-project { width: 70px; }

.app thead tr { border-bottom: 1px solid var(--bg-hover); }
.app th {
  padding: 7px 10px;
  text-align: center; white-space: nowrap;
  color: var(--text-primary); font-weight: 500;
  font-size: 10.5px; letter-spacing: .5px;
}
/* Height lives on the row, so every row is exactly 41px regardless of what
   any one cell holds. */
.app tbody tr { height: 41px; }
.app td {
  padding: 0 10px;
  border-bottom: 1px solid var(--bg-secondary);
  text-align: center; vertical-align: middle;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.app tbody tr:last-child td { border-bottom: 0; }
.app tbody tr:hover td,
.app tbody tr.playing td { background: var(--bg-secondary); }

.app th.col-name, .app td.col-name { text-align: left; }
.app td.col-name { font-weight: 500; cursor: pointer; }
.app td.col-name:hover,
.app tr.playing td.col-name { color: var(--accent); }
.app td.col-tempo { color: var(--text-secondary); }
.app td.col-modified { color: var(--text-secondary); font-size: 11px; }
.app td.col-play { padding: 0; }
.app td.col-key { padding: 0 4px; overflow: visible; }
/* The icon plus both dots needs more than 36px, so the side padding is trimmed
   rather than letting the cell ellipsis it away. */
.app td.col-notes { padding: 0 2px; overflow: visible; }
.app td.col-project { padding: 0 6px; }

.daw-icon {
  width: 24px; height: 24px; margin: 0 auto;
  color: var(--text-primary); display: block;
  shape-rendering: geometricPrecision;
}

/* ── play button: triangle, or spectrum that becomes pause on hover ── */
.play-btn {
  width: 28px; height: 28px; margin: 0 auto;
  border: none; background: transparent;
  color: var(--text-secondary);
  display: flex; align-items: center; justify-content: center;
  padding: 0; cursor: pointer; transition: color .1s;
}
.play-btn:hover { color: var(--text-hover); }
.play-btn svg { display: block; pointer-events: none; }
.play-btn.is-playing, .play-btn.is-playing:hover { color: var(--accent); }
.play-btn .pb-eq, .play-btn .pb-pause { display: flex; pointer-events: none; }
.play-btn .pb-pause { display: none; }
.play-btn.is-playing:hover .pb-eq { display: none; }
.play-btn.is-playing:hover .pb-pause { display: flex; }

.eq rect {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: eqBar .9s ease-in-out infinite;
}
.eq rect:nth-child(1) { animation-duration: .9s;  animation-delay: -.15s; }
.eq rect:nth-child(2) { animation-duration: 1.15s; animation-delay: -.55s; }
.eq rect:nth-child(3) { animation-duration: .8s;  animation-delay: -.30s; }
.eq rect:nth-child(4) { animation-duration: 1.05s; animation-delay: -.70s; }
@keyframes eqBar {
  0%, 100% { transform: scaleY(.18); }
  50%      { transform: scaleY(1); }
}

/* ── saved, tier, key, project, bounces ── */
.save-btn {
  background: none; border: none; padding: 0 2px; cursor: pointer;
  color: var(--text-muted);
  display: inline-flex; align-items: center; justify-content: center;
  transition: color .1s;
}
.save-btn svg { display: block; overflow: visible; fill: none; stroke: currentColor; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; transition: fill .1s; }
.save-btn:hover { color: var(--text-hover); }
.save-btn.saved svg { fill: currentColor; }
.save-btn.saved, .save-btn.saved:hover { color: var(--accent); }

.stars { display: inline-flex; gap: 2px; justify-content: center; white-space: nowrap; }
.star { cursor: pointer; font-size: 13px; color: var(--text-muted); line-height: 1; transition: color .1s; }
.star.lit, .star:hover { color: var(--accent); }

/* Both halves of the key sit in one centred group, so an unset key reads as a
   dash under the middle of the column rather than adrift at its left edge. */
.key-cell { display: flex; align-items: center; justify-content: center; gap: 1px; }
.key-select {
  background: transparent; border: none;
  color: var(--text-muted);
  font-family: inherit; font-size: 11px;
  padding: 2px 0; cursor: pointer; outline: none;
  text-align: center; text-align-last: center;
  appearance: none; -webkit-appearance: none;
}
.key-select.set { color: var(--text-secondary); }
.key-select option { background: var(--bg-hover); color: var(--text-primary); text-align: left; }

/* Open in DAW and open in the cloud, without the version picker. */
.project-cell { display: flex; align-items: center; justify-content: center; gap: 4px; }
.project-ctrl-btn {
  background: none; border: 1px solid var(--bg-hover); border-radius: 5px;
  color: var(--text-secondary); font-size: 11px; font-family: inherit;
  padding: 2px 6px; line-height: 1.4; cursor: pointer;
  transition: background .1s, color .1s;
}
.project-ctrl-btn:hover { background: var(--bg-hover); color: var(--text-primary); }

/* A bare icon, no box. The grey dot means the song has notes; the accent one
   means somebody sent feedback back through a share link. */
.notes-btn {
  background: none; border: none; padding: 2px 4px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 2px;
  color: var(--text-muted); line-height: 0; transition: color .1s;
}
.notes-btn svg { display: block; }
.notes-btn:hover { color: var(--text-hover); }
.notes-btn.has-notes { color: var(--text-secondary); }
.notes-btn.active, .notes-btn.active:hover { color: var(--accent); }
.notes-dot { width: 4px; height: 4px; border-radius: 50%; background: var(--text-secondary); flex-shrink: 0; }
.notes-dot.guest { background: var(--accent); }

.note-at {
  flex-shrink: 0; background: none; border: none; padding: 0; cursor: pointer;
  color: var(--accent); font: 500 11px/1.45 var(--mono);
  font-variant-numeric: tabular-nums;
}
.note-at:hover { text-decoration: underline; }
.note-from { display: block; margin-top: 3px; font-size: 10.5px; color: var(--text-muted); font-style: normal; }

.bounce-pill {
  font-size: 11px; color: var(--text-secondary);
  padding: 2px 7px; border-radius: 8px;
  border: 1px solid var(--text-secondary);
  cursor: pointer; white-space: nowrap; transition: all .1s;
}
.bounce-pill:hover { border-color: var(--text-hover); color: var(--text-hover); }

/* Fixed, so it escapes the panel's overflow clipping the way the app's does.
   It is appended to <body>, outside .app, where the app's tokens are not in
   scope — so it carries them itself. A var() that resolves to nothing paints
   no background at all, which is what made this see-through. */
.bounce-dropdown {
  --bg-secondary: #191919;
  --bg-hover: #3a3a3a;
  --text-primary: #f0f0f0;
  --text-secondary: #aaa;
  --text-hover: #70adc2;
  position: fixed; z-index: 200; min-width: 200px;
  background: #191919; border: 1px solid #3a3a3a;
  border-radius: 8px; overflow: hidden;
  box-shadow: 0 4px 16px rgba(0, 0, 0, .6);
}
.bounce-option {
  padding: 9px 14px; font-size: 12px; color: var(--text-secondary);
  border-bottom: 1px solid var(--bg-hover); cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bounce-option:last-child { border-bottom: none; }
.bounce-option:hover { background: var(--bg-hover); color: var(--text-primary); }

/* ── the player ── */
.player-bar {
  position: absolute; bottom: 16px; left: 50%; transform: translateX(-50%);
  z-index: 5; display: none;
}
.player-bar.visible { display: block; }
.player-bubble {
  position: relative;
  width: 360px; max-width: calc(100vw - 72px);
  background: var(--bg-secondary);
  border: 1px solid var(--app-border); border-radius: 16px;
  padding: 12px 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, .6);
  display: flex; flex-direction: column; gap: 9px;
}
.bubble-top { display: flex; align-items: center; gap: 10px; }
.bubble-track { flex: 1; min-width: 0; text-align: center; }
.bubble-track .track-name {
  font-size: 13px; font-weight: 500; color: var(--text-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bubble-track .file-name {
  font-size: 11px; color: var(--text-secondary); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bubble-icon {
  width: 20px; height: 20px; flex-shrink: 0;
  background: none; border: none; padding: 0;
  color: var(--text-secondary); font-size: 13px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: color .1s;
}
.bubble-icon:hover { color: var(--text-hover); }
.bubble-icon svg { display: block; }
.bubble-icon.muted { color: var(--text-muted); }

.bubble-progress { display: flex; align-items: center; gap: 8px; }
.bubble-time { font-size: 10px; color: var(--text-secondary); min-width: 28px; font-variant-numeric: tabular-nums; }
.bubble-time.total { text-align: right; }

/* The waveform is the visual; a transparent range input on top keeps seeking,
   dragging and keyboard access native. */
.wave-wrap { position: relative; flex: 1; height: 30px; display: flex; align-items: center; }
.wave-wrap canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.wave-wrap input[type="range"] {
  position: relative; z-index: 2; width: 100%; height: 30px; margin: 0;
  background: none; cursor: pointer; outline: none;
  -webkit-appearance: none; appearance: none;
}
.wave-wrap input[type="range"]::-webkit-slider-runnable-track { background: transparent; height: 30px; }
.wave-wrap input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 2px; height: 30px; border: none; border-radius: 1px;
  background: var(--text-primary);
  opacity: 0; transition: opacity .1s;
}
.wave-wrap:hover input[type="range"]::-webkit-slider-thumb { opacity: .9; }
.wave-wrap input[type="range"]::-moz-range-thumb {
  width: 2px; height: 30px; border: none; border-radius: 1px;
  background: var(--text-primary); opacity: 0;
}
.wave-wrap:hover input[type="range"]::-moz-range-thumb { opacity: .9; }

.bubble-controls { display: flex; align-items: center; justify-content: center; gap: 14px; }
.bubble-ctrl {
  width: 28px; height: 28px; flex-shrink: 0;
  border: none; background: transparent; padding: 0;
  color: var(--text-secondary);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: color .1s;
}
.bubble-ctrl svg { display: block; pointer-events: none; }
.bubble-ctrl:hover { color: var(--text-hover); }
.bubble-ctrl.active { color: var(--accent); }
#demo-playpause { width: 36px; height: 36px; color: var(--text-primary); }
#demo-playpause:hover { color: var(--accent); }

/* ── narrow ──
   The eleven columns need ~1004px including the rail. Below that they are
   dropped one at a time, least essential first, rather than squeezed — so what
   remains keeps the app's real proportions instead of collapsing into
   ellipses. */
@media (max-width: 1060px) { .app .col-modified { display: none; } }
@media (max-width: 960px)  { .app .col-tier { display: none; } }
@media (max-width: 860px)  { .app .col-key { display: none; } }
@media (max-width: 730px)  { .app .col-project { display: none; } }
@media (max-width: 660px)  { .app .col-saved { display: none; } }
@media (max-width: 610px)  { .app .col-notes { display: none; } }
@media (max-width: 600px) {
  .app { margin-top: 36px; }
  .app-rail { width: 44px; }
  .app-wordmark { display: none; }
  .app-stats { font-size: 11px; }
  .app-body { min-height: 320px; }
}
@media (max-width: 540px)  { .app .col-tempo { display: none; } }

@media (prefers-reduced-motion: reduce) {
  .eq rect { animation: none; transform: scaleY(.55); }
}
