:root {
  --bg: #0a0d12;
  --card: #141821;
  --card-2: #10141c;
  --border: #262c39;
  --text: #e6e9ef;
  --muted: #8b93a1;
  --accent: #1fb8a6;
  --accent-bright: #3fd9c7;
  --accent-dim: #102b28;
  --radius: 10px;
}

* { box-sizing: border-box; }

body {
  font-family: "Segoe UI", -apple-system, BlinkMacSystemFont, sans-serif;
  background: var(--bg);
  color: var(--text);
  margin: 0;
  line-height: 1.5;
}

.shell { display: flex; align-items: stretch; min-height: 100vh; }

.sidebar {
  flex: 0 0 220px;
  background: #000;
  border-right: 1px solid var(--border);
  padding: 1.5rem 1.1rem;
  display: flex;
  flex-direction: column;
}
.sidebar-brand {
  font-size: 1.05rem;
  font-weight: 800;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 1.75rem;
}
.sidebar-section-label {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0 0 0.5rem;
  padding: 0 0.75rem;
}
.sidebar-nav-item {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  padding: 0.6rem 0.75rem;
  border-radius: 8px;
  color: var(--muted);
  text-decoration: none;
  margin-bottom: 0.15rem;
}
.sidebar-nav-item:hover { color: var(--text); }
.sidebar-nav-item.active { background: #1c2230; color: var(--text); }

/* Pinned to the bottom of the sidebar via margin-top:auto (the sidebar is a flex column) -
   mirrors the reference UI's bottom sidebar card, repurposed honestly as a free-tier reminder
   tied to the real FREE_PAGE_LIMIT enforced in api/jobs.py, not a fake upsell (no paid tier
   exists yet). */
.sidebar-footer-card {
  margin-top: auto;
  padding: 0.9rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card-2);
  font-size: 0.78rem;
  color: var(--muted);
  line-height: 1.45;
}
.sidebar-footer-card a { color: var(--accent-bright); }

.main { flex: 1 1 auto; min-width: 0; padding-bottom: 4rem; }

.topbar {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 1.1rem 1.5rem;
  border-bottom: 1px solid var(--border);
}
.topbar-icon { font-size: 1.3rem; }
.topbar h1 { font-size: 1.3rem; margin: 0; letter-spacing: -0.01em; }
.topbar .subtitle { font-size: 0.85rem; margin: 0; max-width: none; }
.topbar .subtitle::before { content: "\00B7\0020"; }

@media (max-width: 700px) {
  .shell { flex-direction: column; }
  .sidebar { flex: 0 0 auto; border-right: none; border-bottom: 1px solid var(--border); }
}

.badge {
  display: inline-block;
  background: #5b5bf0;
  color: #fff;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  vertical-align: middle;
  margin-left: 0.6rem;
}
h1 { font-size: 2.2rem; margin: 0 0 0.6rem; letter-spacing: -0.01em; }
.subtitle { color: var(--muted); font-size: 1rem; margin: 0; max-width: 32rem; }

.content { max-width: 1240px; margin: 0 auto; padding: 1.5rem 1.25rem; }

/* Left column is upload/input, right column is everything that comes out of it - preview,
   playback, downloads - split evenly. */
.workspace {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
  align-items: start;
}
@media (max-width: 900px) {
  .workspace { grid-template-columns: 1fr; }
}

.settings-panel { display: flex; flex-direction: column; }

/* The upload dropzone gets outsized treatment (it's the tool's actual primary input, like the
   reference UI's big centered CTA in its main content area before anything has happened yet)
   even though its column is narrower now - it just grows taller instead of wider. */
.main-column { display: flex; flex-direction: column; gap: 1.25rem; min-width: 0; }
.settings-panel { min-width: 0; }
.dropzone-large { padding: 3.5rem 2rem; }
.dropzone-large .dropzone-icon { font-size: 2.2rem; }
.dropzone-large .dropzone-text { font-size: 1.15rem; }
.dropzone-large .dropzone-sub { font-size: 0.9rem; }

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem;
  margin-bottom: 1rem;
}

.col-title {
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 0.6rem;
}

.upload-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
}

.dropzone {
  border: 1.5px dashed var(--border);
  border-radius: 10px;
  background: var(--card-2);
  padding: 2rem 1rem;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.dropzone:hover { border-color: #3a4152; }
.dropzone.dragover { border-color: var(--accent); background: var(--accent-dim); }
.dropzone-icon { font-size: 1.6rem; margin-bottom: 0.5rem; opacity: 0.85; }
.dropzone-text { font-size: 0.92rem; color: var(--text); }
.dropzone-sub { font-size: 0.78rem; color: var(--muted); margin-top: 0.2rem; }
.dropzone-filename {
  margin-top: 0.75rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--accent-bright);
  word-break: break-all;
}

/* Picked-file state (see convert-diagram.js): the empty-state prompt gives way to a
   "source → output" diagram. */
.dropzone.has-file .dropzone-icon,
.dropzone.has-file .dropzone-text,
.dropzone.has-file .dropzone-sub { display: none; }
.convert-diagram {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
}
.diagram-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  flex: 0 1 8rem;
  min-width: 0;
  text-align: center;
}
.diagram-icon {
  height: 84px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.diagram-icon svg { height: 84px; width: auto; display: block; }
.diagram-icon img {
  max-height: 84px;
  max-width: 100%;
  border-radius: 2px;
  background: #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
}
.diagram-label { font-size: 0.85rem; font-weight: 600; color: var(--text); }
/* Nudged up by roughly a label's height so the arrow lines up with the icons, not the labels. */
.diagram-arrow { color: var(--text); margin-bottom: 1.9rem; }
.diagram-arrow svg { width: 48px; display: block; }
.dropzone.converting .diagram-arrow {
  color: var(--accent-bright);
  animation: diagram-nudge 1s ease-in-out infinite;
}
@keyframes diagram-nudge {
  0%, 100% { transform: translateX(-4px); opacity: 0.6; }
  50% { transform: translateX(4px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .dropzone.converting .diagram-arrow { animation: none; }
}
.diagram-change { margin-top: 0.35rem; font-size: 0.8rem; color: var(--accent-bright); }

button {
  font-size: 0.9rem;
  font-weight: 600;
  padding: 0.6rem 1.1rem;
  border-radius: 8px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: opacity 0.15s ease, background 0.15s ease;
}
button:disabled { opacity: 0.4; cursor: default; }

.btn-primary { background: var(--accent); color: #04201c; }
.btn-primary:hover:not(:disabled) { background: var(--accent-bright); }

.btn-outline {
  background: transparent;
  color: var(--accent-bright);
  border: 1px solid var(--accent);
}

.btn-danger { background: transparent; color: #ff8577; border: 1px solid #ff8577; }

#status {
  font-weight: 600;
  font-size: 0.95rem;
}
#status:empty { display: none; }

#downloads a {
  display: block;
  padding: 0.5rem 0.75rem;
  margin: 0.35rem 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--accent-bright);
  text-decoration: none;
  font-size: 0.9rem;
  background: var(--card);
}
#downloads a:hover { background: var(--card-2); }

/* Generic labeled-slider control, reused by the audio tools (speed/pitch, metronome BPM). */
.field { margin-bottom: 1rem; }
.field label {
  display: flex;
  justify-content: space-between;
  font-size: 0.85rem;
  color: var(--muted);
  margin-bottom: 0.4rem;
}
.field input[type="range"] { width: 100%; accent-color: var(--accent); }
.field input[type="number"] {
  width: 100%;
  font-size: 0.9rem;
  padding: 0.5rem;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--card-2);
  color: var(--text);
}

.result-value {
  font-size: 2rem;
  font-weight: 800;
  color: var(--accent-bright);
}
.result-label { font-size: 0.85rem; color: var(--muted); }

/* Fallback for when LilyPond re-engraving fails (see pipeline/pdf_export.py) - the browser's
   own print-to-PDF always works off whatever OSMD already rendered successfully on screen, so
   it's offered as a "save as PDF" escape hatch. Isolates #viewer using the standard
   visibility trick (not display:none) so its internal layout/sizing is undisturbed. */
@media print {
  body * { visibility: hidden; }
  #viewer, #viewer * { visibility: visible; }
  #viewer { position: absolute; left: 0; top: 0; width: 100%; height: auto !important; overflow: visible !important; border: none; padding: 0; background: #fff !important; }
  #viewer .score-pages > * { margin: 0 !important; box-shadow: none !important; }
}

/* Score viewer (score-viewer.js): A4 pages in a fixed-height scroll box + toolbar. */
.score-toolbar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}
.score-toolbar[hidden] { display: none; }
.score-toolbar-group { display: flex; align-items: center; gap: 0.35rem; }
.score-btn.btn-outline { padding: 0.3rem 0.65rem; font-size: 0.85rem; min-width: 2.2rem; color: var(--text); border-color: var(--border); }
.score-btn.btn-outline:hover:not(:disabled) { border-color: var(--accent); }
.score-btn:disabled { opacity: 0.4; cursor: default; }
.score-btn.btn-outline.active { border-color: var(--accent); color: var(--accent-bright); background: var(--accent-dim); }
.score-page-label { font-size: 0.85rem; color: var(--muted); min-width: 4.5rem; text-align: center; }
#viewer.has-score { background: #e9e7e2; height: max(480px, calc(100vh - 180px)); padding: 16px; }
.score-pages { margin: 0 auto; position: relative; }
.score-pages > div {
  background: #fff;
  margin: 0 auto 16px;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.25);
}
