/* ========== Theme Tokens ========== */
/* Three-way toggle (#themeSelect in index.html): "browser" leaves
   data-theme unset on <html> and lets the prefers-color-scheme media query
   below decide; "light"/"dark" set data-theme explicitly and always win
   over system preference (that's what the :not([data-theme="dark"]) guard
   is for). Dark is this app's original look, so it's also the plain
   :root default — covers "browser" mode on a dark system, and any browser
   too old to evaluate prefers-color-scheme at all. See app.js's
   applyTheme()/setTheme() for the JS half, and the inline script in
   index.html's <head> for the pre-paint flash fix. */
:root {
  --bg: #0f1722;
  --text: #e6eef6;
  --muted: #9fb2c8;
  --text-bright: #cfe6ff;
  --panel-title: #dbeeff;
  --button-bg: #1f2937;
  --button-border: rgba(255, 255, 255, 0.04);
  --panel-grad-1: rgba(255, 255, 255, 0.02);
  --panel-grad-2: rgba(255, 255, 255, 0.01);
  --panel-border: rgba(255, 255, 255, 0.03);
  --circle-border: rgba(255, 255, 255, 0.18);
  --key-cap: #e6eef6;
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg: #f4f6f9;
    --text: #182430;
    --muted: #5a6b7d;
    --text-bright: #1f5f96;
    --panel-title: #14497a;
    --button-bg: #e3e8ee;
    --button-border: rgba(0, 0, 0, 0.12);
    --panel-grad-1: rgba(0, 0, 0, 0.025);
    --panel-grad-2: rgba(0, 0, 0, 0.01);
    --panel-border: rgba(0, 0, 0, 0.06);
    --circle-border: rgba(0, 0, 0, 0.15);
    --key-cap: #182430;
  }
}

:root[data-theme="light"] {
  --bg: #f4f6f9;
  --text: #182430;
  --muted: #5a6b7d;
  --text-bright: #1f5f96;
  --panel-title: #14497a;
  --button-bg: #e3e8ee;
  --button-border: rgba(0, 0, 0, 0.12);
  --panel-grad-1: rgba(0, 0, 0, 0.025);
  --panel-grad-2: rgba(0, 0, 0, 0.01);
  --panel-border: rgba(0, 0, 0, 0.06);
  --circle-border: rgba(0, 0, 0, 0.15);
  --key-cap: #182430;
}

:root[data-theme="dark"] {
  --bg: #0f1722;
  --text: #e6eef6;
  --muted: #9fb2c8;
  --text-bright: #cfe6ff;
  --panel-title: #dbeeff;
  --button-bg: #1f2937;
  --button-border: rgba(255, 255, 255, 0.04);
  --panel-grad-1: rgba(255, 255, 255, 0.02);
  --panel-grad-2: rgba(255, 255, 255, 0.01);
  --panel-border: rgba(255, 255, 255, 0.03);
  --circle-border: rgba(255, 255, 255, 0.18);
  --key-cap: #e6eef6;
}

/* ========== Base / Global Styles ========== */
* {
  box-sizing: border-box;
  font-family: Segoe UI, Roboto, Arial, sans-serif;
}

body {
  margin: 0;
  padding: 16px;
  background: var(--bg);
  color: var(--text);
}

/* ========== Compatibility Banners ========== */
/* Shared style for the two "this won't work" messages: <noscript> (JS
   disabled) and the old-browser probe in index.html (JS enabled, but too
   old to parse app.js's syntax — see handoff.md for the version floor). */
.compat-banner {
  background: #3a1f1f;
  color: #ffd6d6;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 6px;
  padding: 12px 16px;
  margin-bottom: 12px;
  font-size: 14px;
  line-height: 1.4;
}

/* ========== Site Link (back to kei-c.com) ========== */
/* Top bar: the "back to main site" link (left) and the less-instrument-
   specific settings — Language, Theme — (right), separated from the rest
   of .controls since they're page-level preferences, not bandoneon
   controls, and grouping them here keeps the "Enable MIDI Keyboard" row
   below from growing too long to fit on one line. */
.top-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 8px;
}

.site-link {
  color: var(--muted);
  font-size: 13px;
  text-decoration: none;
}

.site-link:hover {
  color: var(--text-bright);
  text-decoration: underline;
}

.top-bar-settings {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 13px;
  color: var(--muted);
}

.top-bar-settings label {
  display: flex;
  align-items: center;
  gap: 4px;
}

.top-bar-settings select {
  font-size: 12px;
  padding: 2px 4px;
}

/* ========== Header ========== */
header {
  display: flex;
  align-items: center;
  gap: 16px;
}

header h1 {
  margin: 0;
  font-size: 20px;
}

header p {
  margin: 0 0 0 auto;
  text-align: right;
}

/* ========== Controls & Form Elements ========== */
.controls {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  margin: 12px 0;
}

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

.file input {
  display: inline-block;
}

/* Reed detune/bellows breath/vibrato only affect the reed-synth signal
   chain (see startReedVoice() in app.js) — plain waveforms never read
   them. Grayed out via a disabled input (native dimming/no-interaction)
   plus dimming the label text itself, toggled by
   updateReedControlsAvailability() whenever the instrument isn't one of
   accordion/harmonica/bandoneon. */
.reed-only.reed-disabled {
  opacity: 0.45;
}

input:disabled {
  cursor: not-allowed;
}

/* Forces the next control onto a new line within the wrapping .controls
   flexbox, so unrelated control groups (MIDI file/play vs. instrument/reed
   vs. status) don't visually blend into one continuous row. */
.control-break {
  flex-basis: 100%;
  height: 0;
}

button {
  background: var(--button-bg);
  color: var(--text);
  border: 1px solid var(--button-border);
  padding: 8px 10px;
  border-radius: 6px;
  cursor: pointer;
}

/* updateBellowsButtonText() (app.js) prefixes this button's text with a
   literal "V " or "⊓ " depending on bellows state. "⊓" (U+2293) isn't in
   the font stack above, so the browser silently falls back to a different
   font just for that glyph -- and that fallback font's line-height metrics
   differ slightly from "V"'s, so the button's own rendered height would
   shift by a px or two depending on which one is showing, reflowing
   everything below it in this wrapping flex layout (the whole keyboard
   included). An explicit line-height makes the button's box height
   independent of which font ends up rendering the glyph. */
#toggleOpenClose {
  line-height: 1.4;
}

button:active {
  transform: translateY(1px);
}

/* Plain <select>/file-input otherwise keep the browser's default white
   chrome regardless of theme (there's no theme-aware default), which looks
   out of place once Day/Night is a real, deliberate choice rather than
   "whatever the browser happens to do." */
select,
input[type="file"] {
  background: var(--button-bg);
  color: var(--text);
  border: 1px solid var(--button-border);
  border-radius: 6px;
  padding: 6px 8px;
}

/* ========== Text & Labels ========== */
.kbd {
  font-size: 12px;
  color: var(--muted);
}

.mapping-hint {
  display: block;
  font-size: 12px;
  color: var(--muted);
  margin-left: 6px;
}

.label-text {
  font-size: 9px;
  color: #0f1722;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.note-text {
  font-size: 10px;
  color: #0f1722;
  font-weight: 700;
  line-height: 1.1;
}

/* ========== Bandoneon Layout & Main Container ========== */
.bandoneon {
  display: flex;
  gap: 12px;
  margin-top: 18px;
}

.panel {
  flex: 1;
  background: linear-gradient(180deg, var(--panel-grad-1), var(--panel-grad-2));
  padding: 12px;
  border-radius: 10px;
  border: 1px solid var(--panel-border);
  overflow: hidden;
}

.panel h2 {
  margin: 0 0 8px 0;
  font-size: 14px;
  color: var(--panel-title);
}

.panel .grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  grid-auto-rows: 72px;
  gap: 8px;
  position: relative;
}

.panel .layout {
  position: relative;
  width: 100%;
  min-height: 700px;
  padding: 12px 0;
}

/* ========== Button Circles ========== */
.button-wrapper {
  width: clamp(48px, 8vw, 80px);
  height: clamp(48px, 8vw, 80px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.button-circle {
  position: relative;
  width: clamp(40px, 6.5vw, 64px);
  height: clamp(40px, 6.5vw, 64px);
  border-radius: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.92);
  cursor: pointer;
  border: 1px solid var(--circle-border);
  transition: transform 0.08s, box-shadow 0.12s;
}

.button-circle:hover {
  transform: scale(1.06);
}

.button-circle.active {
  transform: scale(1.14);
}

.button-circle.active .halo {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1.05);
}

.halo {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 72px;
  height: 72px;
  border-radius: 50%;
  pointer-events: none;
  background: rgba(255, 255, 255, 0.24);
  opacity: 0;
  transition: opacity 0.16s ease, transform 0.16s ease;
}

/* ========== Keyboard Key Caps ========== */
.key-cap {
  position: absolute;
  top: 2px;
  right: 4px;
  font-size: 14px;
  font-weight: bold;
  opacity: 0.85;
  pointer-events: none;
  color: var(--key-cap);
}

/* Piano button-color mode's accidental (black) buttons: .label-text/
   .note-text/.key-cap are normally a fixed dark color that assumes a light
   button background (true for Rainbow and Single-color mode, and Piano's
   own natural/white buttons) — this overrides just the dark-background
   case so text stays legible. Set via app.js's colorForButton() /
   renderMapping(), independent of the page's own Theme (light/dark). */
.button-circle.dark-bg .label-text,
.button-circle.dark-bg .note-text,
.button-circle.dark-bg .key-cap {
  color: #f0f0f0;
}

/* "No hint" mode: hides every marking that gives away which note a button
   plays (its label, computed note name, keyboard key-cap badge), leaving
   just the colored, positioned, clickable circle. Toggled via a class on
   #bandoneonContainer itself (see app.js's applyHintMode()), so it survives
   renderMapping() rebuilding the container's children. */
.hints-off .label-text,
.hints-off .note-text,
.hints-off .key-cap {
  display: none;
}

/* ========== Info & Status ========== */
.info {
  margin-top: 12px;
  color: var(--text-bright);
}

.legend {
  margin-top: 18px;
  color: var(--muted);
}

/* Hard-caps "Active mapping buttons" at 2 lines so a chord with lots of
   simultaneous notes can't grow this line and push the bandoneon panels
   below it down the page — it just truncates with an ellipsis instead. */
.active-buttons-line {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  max-height: 2.8em;
  line-height: 1.4em;
}

.midi-status {
  margin-left: 8px;
  color: var(--muted);
}

/* ========== Responsive Media Queries ========== */
@media (max-width: 1000px) {
  .panel .grid {
    grid-template-columns: repeat(4, 1fr);
  }
  .panel .layout {
    min-height: 450px;
  }
}

@media (max-width: 600px) {
  .bandoneon {
    flex-direction: column;
  }
  .panel .grid {
    grid-template-columns: repeat(6, 1fr);
  }
  .panel .layout {
    min-height: 600px;
  }
}

