/* kwigbo-gb-sdk tracker — styling. Plain monospace throughout (.song format
   is whitespace-aligned columns; sans-serif throws alignment off). */

:root {
  --fg: #1c1c1c;
  --muted: #666;
  --accent: #2a6f97;
  --bg: #fafafa;
  --panel: #fff;
  --border: #d0d0d0;
  --err: #b00020;
  --hdr: #f0f0f0;
  --selected: #fff7c2;
  --note: #1a4d80;
  --rest: #a04040;
  --sustain: #999;
  --drum: #6a4a1a;
}

* { box-sizing: border-box; }

/* Disable mobile's double-tap-to-zoom (and the legacy 300ms tap delay)
   across the whole tracker. Pinch-zoom still works under
   `manipulation`; only the dbl-tap gesture is suppressed, which is the
   one that fires accidentally when you tap a cell or the play button
   twice in quick succession. */
html { touch-action: manipulation; }
button, input, select, textarea, label, td, th, dialog,
.transport-btn, .icon-btn, .drawer-item, .select-btn {
  touch-action: manipulation;
}

/* Tap target hygiene — Safari/iOS won't reliably register taps on
   targets <44×44, swallows the native flash when no tap-highlight-color
   is set, and waits for the click event to draw any active state.
   These rules apply across transport, drawer, dialogs, picker, and
   grid so a tap lands on every interactive element. */
button, .icon-btn, .transport-btn, .drawer-item, .select-btn,
.picker-btn, .octave-tab, .note-btn,
#grid td.rownum, #grid td input.cell {
  -webkit-tap-highlight-color: rgba(42, 111, 151, 0.18);
  -webkit-touch-callout: none;
}
button, .icon-btn, .transport-btn, .drawer-item, .select-btn,
.picker-btn, .octave-tab, .note-btn,
#grid td.rownum {
  -webkit-user-select: none;
  user-select: none;
}
.icon-btn       { min-width: 44px; min-height: 44px; }
.transport-btn  { min-height: 44px; }
.select-btn     { min-height: 44px; }
.drawer-item    { min-height: 48px; }
.picker-btn,
.octave-tab,
.note-btn       { min-height: 44px; }

/* Press-state feedback — fires on touchstart so the user gets immediate
   acknowledgement instead of waiting for the click event to dispatch. */
.transport-btn:active,
.icon-btn:active,
.picker-btn:active,
.octave-tab:active,
.note-btn:active,
.drawer-item:active,
.row-menu button:active { background: var(--hdr); }
.note-btn.sharp:active  { background: #1a1a1a; }

/* Inline SVG icons. fill: currentColor lets buttons cascade their
   colour into the glyph so we get a single monochrome look across
   transport, drawer, dialogs, and grid actions. */
.icon {
  fill: currentColor;
  pointer-events: none;
  flex: 0 0 auto;
  vertical-align: middle;
  width: 1.2em;
  height: 1.2em;
}
.icon-btn .icon       { width: 1.3em; height: 1.3em; }
.transport-btn .icon  { width: 1.5em; height: 1.5em; }
.drawer-item .ico     { display: inline-flex; align-items: center; justify-content: center; width: 1.6em; }
.drawer-item .ico .icon { width: 1.2em; height: 1.2em; }
.row-menu-insert button { display: inline-flex; align-items: center; justify-content: center; gap: 0.4em; }
.row-menu-insert button .icon { width: 1em; height: 1em; }

/* Wide-screen gutter. Body stays full-width: max-width on body
   confuses iOS Safari touch/focus inside showModal() dialogs. */
html { background: #ececec; }

body {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  margin: 0;
  padding: 0;
  line-height: 1.45;
  color: var(--fg);
  background: #ececec;
  /* Keep page-level horizontal scroll off; the grid has its own row clip. */
  overflow-x: hidden;
}

/* Fieldsets (used inside dialogs) default to min-width: min-content,
   which can stretch them past the dialog width. Override. */
fieldset { min-width: 0; border: 1px solid var(--border); border-radius: 4px; }

button, input, select, textarea { font: inherit; color: inherit; }

/* ----------------------------------------------------------------------
   Top bar — single sticky container holding the title row (hamburger +
   title + status) and the transport row (playback icons). Both rows
   stay pinned together while the grid scrolls underneath.
   ---------------------------------------------------------------------- */
.topbar {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 20;
  max-width: 960px;
  margin-left: auto;
  margin-right: auto;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 4px 6px -4px rgba(0, 0, 0, 0.12);
}
.appbar {
  display: flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.45em 0.7em;
}
.appbar h1 {
  font-size: 1em;
  margin: 0;
  flex: 0 0 auto;
}
.appbar .status {
  flex: 1 1 auto;
  font-size: 0.85em;
  color: var(--muted);
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.appbar .status.err { color: var(--err); }

/* Transport row — icon-only playback controls. Buttons share the row
   width equally; the gap between them matches the row's padding so
   the spacing rhythm is consistent on every side. */
.transport {
  display: flex;
  align-items: stretch;
  gap: 0.5em;
  padding: 0.5em;
  border-top: 1px solid var(--border);
  background: var(--hdr);
}
.transport-btn {
  flex: 1;
  height: 2.4em;
  padding: 0;
  font-size: 1.15em;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  line-height: 1;
}
.transport-btn:hover         { border-color: var(--accent); }
.transport-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.transport-btn:disabled      { opacity: 0.45; cursor: not-allowed; }

/* `display: flex` outranks the UA `[hidden] { display: none }` on
   specificity — re-assert hidden explicitly. */
.select-bar {
  display: flex;
  align-items: stretch;
  gap: 0.5em;
  padding: 0.5em;
  border-top: 1px solid var(--border);
  background: var(--hdr);
}
.select-bar[hidden] { display: none; }
.select-btn {
  flex: 1;
  height: 2.4em;
  padding: 0 0.3em;
  font: inherit;
  font-size: 0.95em;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.25em;
}
.select-btn:hover:not(:disabled) { border-color: var(--accent); }
.select-btn:focus-visible        { outline: 2px solid var(--accent); outline-offset: 1px; }
.select-btn:active               { background: var(--hdr); }
.select-btn:disabled             { opacity: 0.4; cursor: not-allowed; }
.select-btn .icon                { width: 1.5em; height: 1.5em; }

.select-info {
  flex: 1;
  display: inline-flex;
  align-items: center;
  height: 2.4em;
  padding: 0 0.7em;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  font: inherit;
  font-size: 0.9em;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.select-bar .select-info ~ .select-btn { flex: 0 0 auto; padding: 0 1em; }

.icon-btn {
  width: 2.2em;
  height: 2.2em;
  padding: 0;
  font-size: 1.2em;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  cursor: pointer;
  flex: 0 0 auto;
}
.icon-btn:hover { background: var(--hdr); }
.icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ----------------------------------------------------------------------
   Drawer + scrim — left side overlay, all primary commands as
   icon+label rows.
   ---------------------------------------------------------------------- */
.scrim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 25;
}
.drawer {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 280px;
  max-width: 84vw;
  background: var(--panel);
  border-right: 1px solid var(--border);
  z-index: 30;
  display: flex;
  flex-direction: column;
  transform: translateX(-100%);
  transition: transform 0.18s ease-out;
  box-shadow: 4px 0 12px -4px rgba(0, 0, 0, 0.18);
}
.drawer.open       { transform: translateX(0); }
.drawer[hidden]    { display: flex; }            /* hidden via transform until .open */

.drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5em 0.75em;
  border-bottom: 1px solid var(--border);
}
.drawer-title { font-weight: 600; color: var(--muted); }
.drawer-items {
  list-style: none;
  margin: 0;
  padding: 0.4em 0.4em;
  overflow-y: auto;
}
.drawer-items li { margin: 0; }
.drawer-sep {
  border-top: 1px solid var(--border);
  margin: 0.4em 0.2em;
  list-style: none;
}

.drawer-item {
  display: flex;
  align-items: center;
  gap: 0.7em;
  width: 100%;
  padding: 0.7em 0.8em;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 4px;
  text-align: left;
  font: inherit;
  color: var(--fg);
  cursor: pointer;
}
.drawer-item:hover    { background: var(--hdr); }
.drawer-item .ico     { font-size: 1.15em; width: 1.6em; text-align: center; }
.drawer-item .lbl     { flex: 1; }
.drawer-item input[type="file"] { display: none; }
/* Song picker: highlight the currently loaded song so a listener can
   tell what they're hearing without opening Song details. */
.drawer-item[aria-current="true"] {
  background: var(--hdr);
  font-weight: 600;
}
.song-list { list-style: none; margin: 0; padding: 0; }
.song-list li { margin: 0; }

/* ----------------------------------------------------------------------
   <dialog> styling — Song details + Instruments modals. Native
   <dialog> handles open/close; we just style the chrome.
   ---------------------------------------------------------------------- */
.dialog {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0;
  max-width: 92vw;
  width: 460px;
  color: var(--fg);
  background: var(--panel);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);
}
.dialog::backdrop { background: rgba(0, 0, 0, 0.4); }
.dialog-form { display: flex; flex-direction: column; }
.dialog-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.6em 0.8em;
  border-bottom: 1px solid var(--border);
}
.dialog-head h2 { font-size: 1em; margin: 0; }
.dialog-foot {
  display: flex;
  justify-content: flex-end;
  gap: 0.4em;
  padding: 0.6em 0.8em;
  border-top: 1px solid var(--border);
}
.dialog-foot button {
  padding: 0.45em 0.9em;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
}
.dialog-foot button:hover { border-color: var(--accent); }
.dialog .hint { color: var(--muted); font-size: 0.85em; padding: 0 0.8em 0.4em; }

/* Meta form (inside Song-details dialog) */
.meta {
  display: flex;
  flex-direction: column;
  gap: 0.55em;
  margin: 0.6em 0.8em;
  padding: 0.6em 0.8em;
}
.meta legend { padding: 0 0.4em; color: var(--muted); }
.meta label  { display: flex; align-items: center; gap: 0.5em; }
.meta input[type="text"]   { flex: 1; padding: 0.4em 0.55em; border: 1px solid var(--border); border-radius: 4px; }
.meta input[type="number"] { width: 6em; padding: 0.4em 0.55em; border: 1px solid var(--border); border-radius: 4px; }
.meta select              { padding: 0.4em 0.55em; border: 1px solid var(--border); border-radius: 4px; }
.active-block {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4em 0.6em;
  align-items: center;
}
.active-block .hdr { color: var(--muted); }

/* Instruments listing (inside Instruments dialog) */
.instruments {
  display: grid;
  grid-template-columns: max-content 1fr 1fr;
  gap: 0.2em 0.7em;
  margin: 0.6em 0.8em;
  font-size: 0.92em;
}
.instruments .name  { font-weight: bold; }
.instruments .label { color: var(--muted); }
.instruments .empty { grid-column: 1 / -1; color: var(--muted); }

/* ----------------------------------------------------------------------
   Main content + grid
   ---------------------------------------------------------------------- */
.content {
  max-width: 960px;
  margin-left: auto;
  margin-right: auto;
  padding: 0.6em 0.7em 2em;
  background: var(--bg);
}

#grid {
  border-collapse: collapse;
  font-size: 12.5px;
  width: 100%;
  table-layout: fixed;
}
#grid th, #grid td {
  border: 1px solid var(--border);
  padding: 0;
  text-align: center;
  background: var(--panel);
}
/* When tickHighlight calls scrollIntoView on the playing row, leave
   room for the sticky topbar + thead so the row lands below them
   instead of behind them. Critical for loop-back to row 0. */
#grid tbody tr { scroll-margin-top: var(--header-h, 7em); }
#grid thead th {
  background: var(--hdr);
  position: -webkit-sticky;
  position: sticky;
  /* Bumped down by the topbar's height (appbar + transport) so column
     names sit just below the playback controls. */
  top: var(--topbar-h, 5em);
  font-weight: 600;
  color: var(--muted);
  padding: 0.25em 0.4em;
  z-index: 1;
}
#grid th.rownum, #grid td.rownum {
  width: 3em;
  color: var(--muted);
  text-align: right;
  padding: 0 0.4em;
  background: var(--hdr);
}
#grid td.rownum {
  cursor: pointer;
  user-select: none;
}
#grid td.rownum:hover { background: var(--selected); color: var(--fg); }
#grid td.rownum:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
#grid td input.cell {
  width: 100%;
  min-height: 36px;
  border: none;
  border-radius: 0;
  background: transparent;
  padding: 0.35em 0.3em;
  text-align: center;
  font: inherit;
  color: var(--fg);
  cursor: pointer;
}
#grid td input.cell:focus {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  background: var(--selected);
}
#grid td.lyric input.cell { text-align: left; padding-left: 0.4em; }

/* Cell coloring by content category — applied via tracker.js. */
#grid input.cell.note    { color: var(--note); }
#grid input.cell.drum    { color: var(--drum); }
#grid input.cell.rest    { color: var(--rest); }
#grid input.cell.sustain { color: var(--sustain); }

/* Play-position highlight */
#grid tr.playing td,
#grid tr.playing td.rownum  { background: #fff7c2; }
#grid tr.playing input.cell { background: rgba(255, 247, 194, 0.6); }

/* .playing overrides .row--selected so the playhead is visible within
   the selection; tick loop only clears .playing, so previous rows fall
   back to the selection highlight automatically. */
#grid tr.row--selected td,
#grid tr.row--selected td.rownum  { background: #d9ecff; }
#grid tr.row--selected input.cell { background: rgba(217, 236, 255, 0.6); }
#grid tr.playing.row--selected td,
#grid tr.playing.row--selected td.rownum  { background: #fff7c2; }
#grid tr.playing.row--selected input.cell { background: rgba(255, 247, 194, 0.6); }

/* In select mode, let row taps bubble up to gridBody instead of
   landing on the cell inputs (which would open the picker). */
body.select-mode #grid td input.cell { pointer-events: none; cursor: default; }

/* Row-menu dialog (delete + insert N above/below). */
.row-menu {
  display: flex;
  flex-direction: column;
  gap: 0.6em;
  margin: 0.6em 0.8em;
}
.row-menu hr { border: 0; border-top: 1px solid var(--border); margin: 0.2em 0; }
.row-menu button {
  padding: 0.5em 0.9em;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  font: inherit;
}
.row-menu button:hover { border-color: var(--accent); }
.row-menu .row-menu-danger { color: var(--err); }
.row-menu .row-menu-danger:hover { border-color: var(--err); background: #fff0f1; }
.row-menu .row-menu-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.row-menu .row-menu-primary:hover:not(:disabled) { background: #1f5a7b; border-color: #1f5a7b; }
.row-menu .row-menu-primary:disabled { opacity: 0.4; cursor: not-allowed; }
.row-menu .row-menu-primary .icon { width: 1.05em; height: 1.05em; }
.row-menu-count {
  display: flex;
  align-items: center;
  gap: 0.5em;
}
.row-menu-count input {
  width: 5em;
  padding: 0.4em 0.55em;
  border: 1px solid var(--border);
  border-radius: 4px;
}
.row-menu-insert {
  display: flex;
  gap: 0.5em;
}
.row-menu-insert button { flex: 1; }

.paste-song-dialog { width: min(96vw, 720px); }
.paste-song-body { padding: 0.6em 0.8em; }
.paste-song-body textarea {
  width: 100%;
  min-height: 40vh;
  padding: 0.5em 0.6em;
  border: 1px solid var(--border);
  border-radius: 4px;
  font: inherit;
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 0.85em;
  color: var(--fg);
  background: var(--panel);
  resize: vertical;
  white-space: pre;
  overflow-x: auto;
}

/* Cell picker dialog (notes / instruments / drums / specials). */
.cell-picker-dialog { width: min(96vw, 560px); }
.cell-picker-current {
  padding: 0.4em 0.8em 0.2em;
  color: var(--muted);
  font-size: 0.85em;
}
.cell-picker-current b { color: var(--fg); font-weight: 600; }
.cell-picker-foot { justify-content: stretch; }
.cell-picker-foot button {
  flex: 1;
  padding: 0.6em 0.8em;
  min-height: 44px;
}
.cell-picker-foot button:disabled { opacity: 0.4; cursor: not-allowed; }
.cell-picker-foot .cell-picker-accept {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.cell-picker-foot .cell-picker-accept:hover:not(:disabled) {
  background: #1f5a7b;
  border-color: #1f5a7b;
}
.cell-picker {
  padding: 0.5em 0.8em 0.7em;
  max-height: 75vh;
  overflow-y: auto;
}
.cell-picker section { margin-bottom: 0.7em; }
.cell-picker section:last-child { margin-bottom: 0; }
.cell-picker h3 {
  font-size: 0.85em;
  color: var(--muted);
  margin: 0.4em 0 0.35em;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.cell-picker .picker-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35em;
}
.cell-picker .picker-btn {
  padding: 0.55em 0.8em;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  font: inherit;
}
.cell-picker .picker-btn:hover   { border-color: var(--accent); }
.cell-picker .picker-btn.current { background: var(--accent); color: #fff; border-color: var(--accent); }

/* Octave tabs — pick which octave the note row reflects. */
.octave-tabs {
  display: flex;
  gap: 0.3em;
  margin-bottom: 0.4em;
}
.octave-tab {
  flex: 1;
  padding: 0.5em 0.4em;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  font: inherit;
  color: var(--muted);
}
.octave-tab:hover  { border-color: var(--accent); }
.octave-tab.active { background: var(--accent); color: #fff; border-color: var(--accent); }

/* Note row — 12 chromatic buttons. Sharps tinted dark. */
.note-row {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 2px;
}
.note-btn {
  padding: 0.7em 0.1em;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 3px;
  cursor: pointer;
  font: inherit;
  font-size: 0.82em;
  color: var(--fg);
}
.note-btn:hover         { border-color: var(--accent); }
.note-btn.sharp         { background: #404040; color: #fff; }
.note-btn.sharp:hover   { background: #2a2a2a; }
.note-btn.current,
.note-btn.sharp.current { background: var(--accent); color: #fff; border-color: var(--accent); }

/* Hide the emulator canvas — MusicROM never updates VRAM. binjgb's
   Video class still needs the element to render to. */
#emulator   { display: none; }
#controller { display: none !important; }

/* ----------------------------------------------------------------------
   Mobile (≤720px wide). Hamburger UI scales down naturally; just
   tighten spacing and hide the lyric column. Sticky <thead> stays
   active under the transport row so channel labels are always
   visible while scrolling.
   ---------------------------------------------------------------------- */
@media (max-width: 720px) {
  .appbar h1 { font-size: 0.95em; }
  .appbar .status { font-size: 0.78em; }

  .content { padding: 0.4em 0.5em 2em; }

  #grid                          { font-size: 12.5px; }
  #grid th.lyric,
  #grid td.lyric                 { display: none; }
  #grid th.rownum,
  #grid td.rownum                { width: 2.6em; padding: 0 0.2em; }
  #grid td input.cell {
    min-height: 44px;
    padding: 0.45em 0.15em;
  }

  /* 12-wide note row is ~25px per button at 360px viewports — way
     under the iOS tap target threshold. Reflow to 6×2 on mobile. */
  .note-row {
    grid-template-columns: repeat(6, 1fr);
    gap: 4px;
  }

  .dialog { width: auto; max-width: 96vw; }
}
