/* ═══════════════════════════════════════════════════
   Théorie Piano — thème sombre, mobile-first
   Fork de style.css (app guitare) : socle identique, la partie
   instrument est remplacée par le clavier et les voicings.
   ═══════════════════════════════════════════════════ */

/* Polices auto-hébergées (Raleway, Antic Didone) — jamais de réseau,
   même à la toute première ouverture, même en fichier local sans
   serveur. Sous-ensemble latin uniquement : couvre le français. */
@font-face {
  font-family: "Raleway";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/raleway-400.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Raleway";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/raleway-700.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Antic Didone";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/antic-didone-400.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Fonds — repris de la toute première version (plus sombre) */
  --bg:        #0d0d0d;
  --bg-2:      #141414;
  --bg-3:      #1c1c1c;
  --bg-4:      #242424;
  --border:    #2b2b2b;
  --border-2:  #3a3a3a;

  /* Textes */
  --text:      #f2f2f2;
  --text-dim:  #b8b8b8;
  --text-faint:#7d7d7d;

  /* Degrés — code couleur imposé, jamais retouché */
  --deg-1: #ff6b00;
  --deg-3: #4a9eff;
  --deg-5: #4aff91;
  --deg-7: #b44aff;
  --deg-x: #e0e0e0;

  /* Mains — voir le bloc « Voicings ». Volontairement neutre : les
     cinq couleurs de degré sont déjà prises, une 6e et une 7e teinte
     se confondraient avec la tonique et la tierce. Deux valeurs, car
     un contour clair est invisible sur une touche blanche et un
     contour sombre invisible sur une noire. */
  --hand-on-white: #000000;
  --hand-on-black: #ffffff;

  /* Accent d'interface — le rouge d'adrienstary.fr, indépendant de la
     tonique (--deg-1) qui reste orange sur le manche et les diagrammes. */
  --accent: #c21c27;

  /* Métriques */
  --radius:    10px;
  --radius-sm: 8px;
  --gap:       12px;
  --pad:       14px;
  --header-h:  58px;
  --tabs-h:    46px;

  /* Raleway pour l'interface, écho direct du site ; Antic Didone réservé
     au seul grand titre de l'en-tête. */
  --font: "Raleway", -apple-system, BlinkMacSystemFont, "Segoe UI",
          Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: "Antic Didone", Georgia, "Times New Roman", serif;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;

  color-scheme: dark;
}

/* ─────────── Reset ─────────── */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  padding-bottom: env(safe-area-inset-bottom);
  overflow-x: hidden;
}

/* `hidden` doit toujours l'emporter : plusieurs éléments masqués par
   défaut (.kv, .legend…) ont un display explicite qui l'écraserait. */
[hidden] { display: none !important; }

h1, h2, h3, p, ul { margin: 0; }
ul { list-style: none; padding: 0; }

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

::selection { background: rgba(194,28,39,.3); }

/* Scrollbars discrètes */
* { scrollbar-width: thin; scrollbar-color: var(--border-2) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--border-2);
  border-radius: 4px;
}

/* ─────────── En-tête ─────────── */

.app-header {
  padding: calc(env(safe-area-inset-top) + 12px) var(--pad) 10px;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}

.app-title {
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 400;
  letter-spacing: .02em;
  text-transform: none;
  color: var(--text-dim);
}
.app-title b {
  font-weight: 600;
  color: var(--text);
}

.app-sub {
  margin-top: 2px;
  font-size: .72rem;
  letter-spacing: .04em;
  color: var(--text-faint);
}

/* ─────────── Onglets ─────────── */

.tabs {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }

.tab {
  flex: 1 1 0;
  min-width: 0;
  min-height: var(--tabs-h);
  padding: 0 8px;
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  color: var(--text-faint);
  font-size: .8rem;
  letter-spacing: .01em;
  white-space: nowrap;
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}
.tab:hover { color: var(--text-dim); }
.tab.is-active {
  color: var(--text);
  border-bottom-color: var(--accent);
}
.tab:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -3px;
}

/* Sous 400 px, « Cycle des quintes » ne tient pas dans un tiers de l'écran :
   on bascule sur le libellé court plutôt que de le laisser tronquer. */
.tab-short { display: none; }
@media (max-width: 400px) {
  .tab-long  { display: none; }
  .tab-short { display: inline; }
  .tab { font-size: .78rem; }
}

/* ─────────── Contenu ─────────── */

.app-main {
  max-width: 1400px;
  margin: 0 auto;
  padding: var(--pad);
}

.panel { display: none; }
.panel.is-active {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  animation: fade .18s ease;
}

@keyframes fade {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* ─────────── Sélecteurs ─────────── */

.controls {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.controls--compact { grid-template-columns: 1fr; }

.field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.field--wide { grid-column: 1 / -1; }

.field label {
  font-size: .68rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-faint);
}

select {
  width: 100%;
  min-height: 42px;
  padding: 0 32px 0 12px;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: .92rem;
  cursor: pointer;
  appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--text-dim) 50%),
    linear-gradient(135deg, var(--text-dim) 50%, transparent 50%);
  background-position: calc(100% - 17px) 50%, calc(100% - 12px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  transition: border-color .15s ease;
}
select:hover  { border-color: var(--border-2); }
select:focus  { outline: none; border-color: var(--accent); }
select optgroup {
  background: var(--bg-2);
  color: var(--text-faint);
  font-style: normal;
  font-weight: 600;
}
select option {
  background: var(--bg-3);
  color: var(--text);
}

/* ─────────── Boutons ─────────── */

.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.btn {
  min-height: 38px;
  padding: 0 14px;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  font-size: .82rem;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.btn:hover {
  background: var(--bg-4);
  color: var(--text);
  border-color: var(--border-2);
}
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.btn[aria-pressed="true"],
.btn.is-active {
  background: rgba(194,28,39,.14);
  border-color: var(--accent);
  color: var(--accent);
}

.btn--ghost { background: transparent; }

/* Au doigt, les cibles gagnent en hauteur (repère d'accessibilité : 44 px) */
@media (pointer: coarse) {
  .btn   { min-height: 44px; padding: 0 16px; }
  .chip  { min-height: 40px; padding: 0 15px; }
  .tab   { min-height: 50px; }
  select { min-height: 46px; }
  .suggestions li { padding: 13px 14px; }
  .search-clear { width: 40px; height: 40px; }
}

/* ─────────── Cartes ─────────── */

.card {
  padding: var(--pad);
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.card-title {
  margin-bottom: 10px;
  font-size: 1.12rem;
  font-weight: 600;
  color: var(--text);
}

.kv {
  display: grid;
  grid-template-columns: 92px 1fr;
  gap: 10px;
  padding: 6px 0;
  border-top: 1px solid var(--border);
  font-size: .88rem;
}
.kv:first-of-type { border-top: 0; }

.kv-label {
  font-size: .68rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding-top: 2px;
}
.kv-value {
  font-family: var(--mono);
  color: var(--text);
  word-break: break-word;
}

@media (max-width: 400px) {
  .kv {
    grid-template-columns: 1fr;
    gap: 2px;
  }
  .kv-label { padding-top: 0; }
}

.section-title {
  font-size: .72rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 10px;
}
.section-subtitle {
  margin: 18px 0 8px;
  font-size: .72rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.hint {
  font-size: .78rem;
  color: var(--text-faint);
  text-align: center;
}

.placeholder {
  display: grid;
  place-items: center;
  min-height: 120px;
  padding: 24px;
  color: var(--text-faint);
  font-size: .82rem;
  text-align: center;
}

/* ─────────── Légende ─────────── */

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  padding: 10px var(--pad);
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: .74rem;
  color: var(--text-dim);
}
.legend li { display: flex; align-items: center; gap: 6px; }

.dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex: none;
}

/* ─────────── Clavier ───────────
   Le SVG est rendu à taille fixe et c'est le conteneur qui défile
   en X : les proportions des touches restent celles d'un vrai piano
   quelle que soit la largeur de l'écran. */

.keyboard-wrap {
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 4px;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.keyboard-wrap svg {
  display: block;
  height: auto;
}

/* Touches */
.keyboard-wrap .key-white {
  fill: #ececec;
  stroke: #0d0d0d;
  stroke-width: 1.2;
}
.keyboard-wrap .key-black {
  fill: #16161a;
  stroke: #000;
  stroke-width: 1;
}
.keyboard-wrap .key-white.is-in-scale { fill: #fbfbfb; }
.keyboard-wrap .key-black.is-in-scale { fill: #26262c; }

/* Do du milieu — un liseré discret, jamais une couleur de degré */
.keyboard-wrap .key-middle-c {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  pointer-events: none;
}

/* Repère sonore : les touches et leurs pastilles sont cliquables, et
   s'illuminent brièvement à l'écoute. */
.keyboard-wrap .key,
.keyboard-wrap .note-dot {
  cursor: pointer;
}
.keyboard-wrap .key { transition: fill .12s ease; }
.keyboard-wrap .key-white.is-pressed { fill: #c4c4c4; }
.keyboard-wrap .key-black.is-pressed { fill: #43434e; }
.keyboard-wrap .note-dot.is-pressed {
  filter: brightness(1.5) drop-shadow(0 0 4px rgba(255,255,255,.9));
}

/* La bulle de doigté ne doit pas intercepter le clic destiné à la touche */
.keyboard-wrap .fing-bubble { pointer-events: none; }

/* Pastilles de degré */
.keyboard-wrap .note-dot {
  stroke: rgba(0, 0, 0, .55);
  stroke-width: .8;
}
.keyboard-wrap .note-label {
  font-family: var(--mono);
  font-weight: 700;
  pointer-events: none;
  user-select: none;
}

/* Étiquettes d'octave sous les Do */
.keyboard-wrap .octave-label {
  font-family: var(--mono);
  font-size: 10px;
  fill: var(--text-faint);
  pointer-events: none;
  user-select: none;
}

/* Bulle de doigté */
.keyboard-wrap .fing-bubble {
  fill: var(--bg-4);
  stroke: var(--border-2);
  stroke-width: 1;
}
.keyboard-wrap .fing-text {
  font-family: var(--mono);
  font-size: 9px;
  fill: var(--text-dim);
  pointer-events: none;
  user-select: none;
}

/* ─────────── Voicings ─────────── */

.voicing-grid {
  display: grid;
  /* minmax(0, 1fr) et non 1fr : sans cela une colonne s'élargit à la
     taille de son contenu — un clavier à taille réelle fait alors
     déborder toute la page au lieu de défiler dans sa carte. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--gap);
}
.voicing-grid > .placeholder { grid-column: 1 / -1; }

.voicing-card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  gap: 8px;
  padding: 12px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.voicing-card--wide { grid-column: 1 / -1; }

.voicing-card .voicing-label {
  font-size: .78rem;
  letter-spacing: .03em;
  color: var(--accent);
  line-height: 1.3;
}
.voicing-card .keyboard-wrap {
  padding: 0;
  border: 0;
  background: transparent;
  overflow: visible;
}
/* Le SVG porte un viewBox : une largeur de 100 % le met à l'échelle de
   la carte sans déformer les proportions des touches. */
.voicing-card .keyboard-wrap svg {
  width: 100%;
  height: auto;
}

/* Sous 640 px, une carte fait au mieux ~345 px de large. Une gamme de
   trois octaves y tomberait à 16 px par touche : pastilles et doigtés
   deviennent illisibles. Ces cartes-là gardent donc leur taille réelle
   et défilent, plutôt que d'être écrasées. */
@media (max-width: 639px) {
  .voicing-card--wide .keyboard-wrap {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    min-width: 0;
  }
  .voicing-card--wide .keyboard-wrap svg {
    width: auto;
    max-width: none;
  }
}
.voicing-card .voicing-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  font-family: var(--mono);
  font-size: .72rem;
  color: var(--text-dim);
}
.voicing-card .voicing-meta b {
  color: var(--text-faint);
  font-weight: 400;
  margin-right: 5px;
}

/* Mains — la couleur reste réservée aux degrés (pastilles). La main
   est marquée par le CONTOUR de la touche jouée :
     main droite  → trait plein
     main gauche  → trait tireté
   Aucune teinte supplémentaire, donc aucune confusion possible avec
   l'orange de la tonique ou le bleu de la tierce. */
.keyboard-wrap .hand-mark {
  fill: none;
  stroke-width: 2;
  pointer-events: none;
}
.keyboard-wrap .hand-mark.on-white { stroke: var(--hand-on-white); }
.keyboard-wrap .hand-mark.on-black { stroke: var(--hand-on-black); }
.keyboard-wrap .hand-mark.hand-lh  { stroke-dasharray: 5 3; }

.legend--hands { align-items: center; }
.legend--hands .legend-note {
  color: var(--text-faint);
  font-size: .74rem;
}
/* Pastilles de légende : un carré au contour plein / tireté, pas un
   disque coloré — même grammaire visuelle que sur le clavier. */
.dot--lh, .dot--rh {
  background: transparent;
  border: 2px solid var(--text);
  border-radius: 3px;
}
.dot--lh { border-style: dashed; }

/* ─────────── Recherche d'accords ─────────── */

.search {
  position: relative;
  z-index: 15;
}

.search-input {
  width: 100%;
  min-height: 46px;
  padding: 0 42px 0 14px;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 1rem;
  transition: border-color .15s ease;
}
.search-input::placeholder { color: var(--text-faint); }
.search-input:focus { outline: none; border-color: var(--accent); }

.search-clear {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  width: 32px;
  height: 32px;
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--text-faint);
  font-size: 1.35rem;
  line-height: 1;
  cursor: pointer;
}
.search-clear:hover { color: var(--text); background: var(--bg-4); }

.suggestions {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: min(300px, 46vh);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--bg-3);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-sm);
  box-shadow: 0 12px 32px rgba(0,0,0,.6);
}
.suggestions li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-top: 1px solid var(--border);
  font-size: .9rem;
  cursor: pointer;
}
.suggestions li:first-child { border-top: 0; }
.suggestions li:hover,
.suggestions li.is-highlighted { background: var(--bg-4); }
.suggestions .sug-en {
  font-family: var(--mono);
  font-weight: 600;
}
.suggestions .sug-fr {
  color: var(--text-faint);
  font-size: .78rem;
  text-align: right;
}

/* ─────────── Ma progression ─────────── */

.progression-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-height: 34px;
}

.placeholder-inline {
  font-size: .82rem;
  color: var(--text-faint);
}

.prog-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 38px;
  padding: 0 8px 0 14px;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: 19px;
  font-size: .88rem;
}
.prog-chip .prog-chip-num {
  color: var(--text-faint);
  font-size: .72rem;
  font-family: var(--mono);
}
.prog-chip button {
  width: 24px;
  height: 24px;
  background: none;
  border: 0;
  border-radius: 50%;
  color: var(--text-faint);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
}
.prog-chip button:hover { background: var(--bg-4); color: var(--text); }

/* Une gamme couvre-t-elle exactement la progression, ou seulement en partie ? */
.chip.is-exact { border-color: var(--deg-5); }
.chip.is-partial {
  opacity: .8;
  border-style: dashed;
}
.chip.is-selected {
  background: rgba(194,28,39,.14);
  border-color: var(--accent);
  color: var(--accent);
}
.chip .chip-coverage {
  color: var(--text-faint);
  margin-left: 5px;
  font-size: .72rem;
}

/* ─────────── Accords connexes ─────────── */

.chip-group {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.chip {
  min-height: 34px;
  padding: 0 13px;
  background: var(--bg-3);
  border: 1px solid var(--border);
  border-radius: 17px;
  color: var(--text);
  font-size: .85rem;
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}
.chip:hover { background: var(--bg-4); border-color: var(--accent); }
.chip small { color: var(--text-faint); margin-left: 5px; font-size: .72rem; }

.progressions {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.progression {
  padding: 10px 12px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.progression-name {
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 8px;
}
.progression .chip-group { gap: 6px; }

/* ─────────── Cycle des quintes ─────────── */

.circle-wrap {
  display: grid;
  place-items: center;
  padding: 10px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.circle-wrap svg {
  display: block;
  width: 100%;
  max-width: 560px;
  height: auto;
  /* En paysage sur téléphone, la hauteur est la ressource rare : la roue
     doit rester visible d'un coup d'œil plutôt que de forcer à défiler. */
  max-height: 78dvh;
}
.circle-wrap .cell {
  cursor: pointer;
  transition: fill .12s ease;
}
.circle-wrap .cell:hover { fill: #2e2e2e; }
.circle-wrap .cell:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.circle-wrap text { pointer-events: none; user-select: none; }

.key-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

/* ─────────── Pied de page ─────────── */

.app-footer {
  padding: 18px var(--pad) calc(18px + env(safe-area-inset-bottom));
  text-align: center;
  font-size: .7rem;
  letter-spacing: .06em;
  color: var(--text-faint);
  border-top: 1px solid var(--border);
  margin-top: 20px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.app-copyright {
  font-size: .68rem;
  letter-spacing: .04em;
  color: var(--text-faint);
}

/* ═══════════════ Tablette ═══════════════ */

@media (min-width: 640px) {
  :root { --pad: 18px; --gap: 16px; }

  body { font-size: 15.5px; }

  .controls { grid-template-columns: repeat(3, 1fr); }
  .field--wide { grid-column: auto; }
  .controls--compact { grid-template-columns: minmax(0, 260px); }

  .app-title { font-size: 1.15rem; }
  .tab { padding: 0 18px; font-size: .86rem; }
  .kv { grid-template-columns: 110px 1fr; }

  .voicing-grid { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
}

/* ═══════════════ Desktop ═══════════════ */

@media (min-width: 1024px) {
  :root { --pad: 24px; }

  .app-header {
    display: flex;
    align-items: baseline;
    gap: 14px;
  }
  .app-sub { margin-top: 0; }

  .tabs { border-bottom: 1px solid var(--border); }
  .tab { flex: 0 0 auto; padding: 0 26px; font-size: .86rem; }

  .voicing-grid { grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); }

  .panel--split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    align-items: start;
  }
}
