:root{
  /* Neon Pulse - kleurstijl sinds v0.18.0 (verving "Aurora Glass"),
     gebruikersverzoek: hele app in de stijl van de zelf aangeleverde
     "PianoICO_Library"-iconen ("neon glowing line art in cyan/magenta,
     minimalist modern app interface"). De precieze tinten zijn niet uit de
     lucht gegrepen: gemeten via pixel-sampling op de PNG's zelf (kern rond
     #C060D0/#70E0F0). --bg-dark/--bg-card bleven bewust dicht bij hun oude
     Aurora-waarden - die kwamen al opvallend dicht bij de donkere
     cirkel-badge-achtergrond van de iconen zelf uit (circa #151c3a), dus
     alleen licht verdiept i.p.v. compleet vervangen; geen dubbele/
     tegenstrijdige donkere ondergrond tussen icoon-badge en
     tegel-achtergrond.
     **--accent = cyaan (niet magenta)** — bijgesteld ná eerste gebruikers-
     feedback op deze ronde ("focus meer op blauwe/cyaan accenten, ook de
     omlijningen van MIDI en de kaarten") — cyaan is de PRIMAIRE, in
     enkelvoudige kleur-contexten gebruikte tint (randen/omlijningen,
     `.tile-btn:hover`-rand, `.mode-switch-btn.active` — dus ook de
     MIDI-modusschakelaar —, `.tile-badge`/MIDI-badge-rand,
     `--border-color`, `--wheel-tonic`); magenta leeft voortaan alleen nog
     als TWEEDE kleur in de knop-/gloed-kleurverlopen
     (`linear-gradient(var(--accent),var(--accent-2))`), dus als accent-tint
     i.p.v. de hoofdkleur. Zelfde volgorde-principe toegepast op de ambient
     achtergrondgloed (body{background-image}, .blob.one/.blob.two) en de
     `.tile-icon-wrap img`-drop-shadow verderop in dit bestand.
     --wheel-maj/--wheel-min (kwintencirkel) blijven zoals in elke eerdere
     kleurronde BEWUST de originele blauwtinten - nog steeds de enige
     uitzondering, nu vooral omdat major/minor daar hun eigen, van
     --accent/--accent-2 losstaande onderscheid nodig hebben (zie
     Root_Note_Context.md). */
  --bg-dark:#0a0d1f; --bg-panel:#0a0d1f; --bg-card:#141833; --bg-panel-glass:rgba(10,13,31,.62);
  --text-main:#f5f7fb; --text-muted:#8b93a9; --border-color:rgba(34,211,238,.18);
  --accent:#22d3ee; --accent-hover:#06b6d4; --accent-2:#c026d3;
  /* --accent-ink (sinds v0.18.3): tekstkleur BOVENOP een vlak-gevulde
     var(--accent)-achtergrond (bijv. `.mode-switch-btn.active`) — de
     felle dark-mode-cyaan is te licht voor witte tekst (gebruikersfeedback:
     "Cyan te fel waardoor de tekst niet goed leesbaar is"), dus hier
     bewust donker i.p.v. wit; in light mode (hieronder) is --accent al
     een dieper cyaan waar wit wél goed op leest. */
  --accent-ink:#0a0d1f;
  --paper-bg:#10132a; --paper-ink:#f2f4f9; --paper-border:rgba(34,211,238,.16); --paper-muted:#8b93a9;
  --piano-white:#fdfbf3; --piano-black:#14110f; --overlay-bg:#0a0d1f;
  --paper-btn-bg:#1b1f42; --paper-btn-hover:#262c50;
  --radius-sm:12px; --radius-md:20px; --radius-lg:28px;
  --shadow-sm:0 2px 10px rgba(0,0,0,.35);
  --shadow-md:0 14px 32px rgba(0,0,0,.4);
  --shadow-lg:0 30px 70px rgba(34,211,238,.3);

  /* Kwintencirkel — originele blauwtinten (Dark Mode), niet aangepast */
  --wheel-maj: #3b82f6;
  --wheel-min: #60a5fa;
  --wheel-bg: var(--bg-panel);
  --wheel-line: var(--bg-dark);
  --wheel-ink: #ffffff;
  --wheel-ink-min: #ffffff;
  --wheel-ink-dim: #ffffff;
  --wheel-stave: #f2f4f9;
  /* Tonica-wijzertjes: volgen de accentkleur (+ zachte gloed via
     .wheel-tonic-marker in CSS) i.p.v. een los wit/zwart contrastlijntje —
     sluit daardoor aan bij de rest van het glasachtige uiterlijk. */
  --wheel-tonic: var(--accent);
}
[data-theme="light"]{
  /* Light mode: zelfde Neon Pulse-merkkleuren, maar verzadigder/donkerder
     (cyan-600/fuchsia-800 i.p.v. de felle dark-mode-neon) — zelfde
     contrast-patroon dat het oude Aurora Glass-thema ook al hanteerde
     (donkere/heldere variant per thema i.p.v. één kleur die op beide
     achtergronden evengoed leest). --accent is hier ook cyaan (zie
     toelichting bij :root hierboven), magenta blijft de tweede
     gradient-tint. De PianoICO-badges zelf blijven ONGEWIJZIGD tussen de
     thema's (zie TILE_ICONS/tiles-ui.js) — hun eigen donkere cirkel-badge
     is al zelfvoorzienend genoeg contrast op wit. */
  /* Structuur OMGEDRAAID (derde feedbackronde op v0.18.3, gebruikers-
     inzicht: "in het donkere thema is de achtergrond DONKERDER dan kaart en
     header" — in dark mode is --bg-dark #0a0d1f inderdaad het donkerste
     punt, en liggen --bg-card/--paper-bg er als iets LICHTERE, "opgetilde"
     vlakken bovenop). De vorige light-mode-poging deed het omgekeerde: een
     getint canvas (--bg-dark) met witte kaarten erbovenop (kaart = het
     extreme punt). Nu wél hetzelfde principe als dark mode, gespiegeld in
     helderheid: --bg-dark is hier het EXTREME punt (zuiver wit), --bg-card/
     --paper-bg zijn een tikje MINDER extreem — dus "opgetild" door van het
     canvas AF te wijken, precies zoals in dark mode. --paper-btn-bg/-hover
     (knoppen BOVENOP de kaart) gaan om dezelfde reden weer terug richting
     wit/zuiverder — net als in dark mode de knoppen-op-paper
     (--paper-btn-bg) weer LICHTER zijn dan --paper-bg zelf.
     **Kaart-/kop-tint: eerst crème/sepia geprobeerd, uiteindelijk lichtblauw
     (vijfde feedbackronde) — een ivoor/crème-tint (vorige poging) bleek nog
     steeds te botsen met de cyaan/magenta-merkkleuren; een zachte
     lichtblauwe/cyaan-tint (#e3f5fa) sluit direct aan bij --accent zelf,
     dus geen aparte, om het thema heen gekozen kleur meer. */
  --bg-dark:#ffffff; --bg-panel:#ffffff; --bg-card:#e3f5fa; --bg-panel-glass:rgba(255,255,255,.62);
  --text-main:#181229; --text-muted:#6b6680; --border-color:rgba(8,145,178,.28);
  --accent:#0891b2; --accent-hover:#0e7490; --accent-2:#a21caf;
  --accent-ink:#ffffff;
  --paper-bg:#e3f5fa; --paper-ink:#181229; --paper-border:rgba(8,145,178,.34); --paper-muted:#6b6680;
  --overlay-bg:#ffffff;
  --paper-btn-bg:#ffffff; --paper-btn-hover:#c9ecf5;
  /* Schaduwen/gloed opgehoogd (sinds v0.18.3, gebruikersfeedback: "Light
     Thema is erg saai/eentonig ... springt er minder goed uit dan Dark
     Thema") — was te subtiel/laag-verzadigd (rgba(6,95,120,...), een
     gedempte teal) om als merkbare "gloed" te lezen tegen een wit canvas;
     nu directer op de cyaan-accentkleur + hogere opacity, dezelfde
     richting als de dark-mode-gloed maar met genoeg diepte om op wit te
     dragen. */
  --shadow-sm:0 2px 10px rgba(8,145,178,.14);
  --shadow-md:0 14px 32px rgba(8,145,178,.18);
  --shadow-lg:0 30px 70px rgba(8,145,178,.26);

  /* Kwintencirkel — originele blauwtinten (Light Mode), niet aangepast */
  --wheel-maj: #60a5fa;
  --wheel-min: #93c5fd;
  --wheel-bg: #f9fafb;
  --wheel-line: #ffffff;
  --wheel-ink: #ffffff;
  --wheel-ink-min: #1e3a8a;
  --wheel-ink-dim: #6b7280;
  --wheel-stave: #111827;
  --wheel-tonic: var(--accent);
}

*{ box-sizing:border-box; margin:0; padding:0; font-family:'Inter',sans-serif; user-select:none; -webkit-tap-highlight-color:transparent; }
body{
  background-color:var(--bg-dark); color:var(--text-main); display:flex; flex-direction:row;
  height:100dvh; min-height:100vh; overflow:hidden; transition:background-color .3s,color .3s;
  /* Neon Pulse: zachte ambient kleurwolken op de achtergrond — cyaan
     vooraan/groter (dominant), magenta kleiner op de achtergrond, zelfde
     "cyaan is de hoofdkleur"-volgorde als de rest van dit bestand. */
  background-image:
    radial-gradient(38% 32% at 10% 6%, rgba(34,211,238,.20), transparent 70%),
    radial-gradient(32% 30% at 92% 16%, rgba(192,38,211,.14), transparent 70%);
  background-attachment:fixed;
}
[data-theme="light"] body{
  /* Opgehoogd sinds v0.18.3 (zie --shadow-*-toelichting hierboven, zelfde
     "Light Thema te saai"-feedback) — was nauwelijks zichtbaar tegen het
     lichte canvas. */
  background-image:
    radial-gradient(38% 32% at 10% 6%, rgba(8,145,178,.16), transparent 70%),
    radial-gradient(32% 30% at 92% 16%, rgba(162,28,175,.13), transparent 70%);
}

#app-shell{ display:flex; flex-direction:column; width:100%; height:100%; }

/* Eigen-pianogeluid-trigger: bewust onopvallend, zie HTML-comment bij het
   element zelf. position:fixed t.o.v. het venster, dus overal in de app op
   dezelfde plek bereikbaar. Sinds v0.17.5 (zijbalk/onderbalk vervallen)
   dezelfde positie op ELKE schermbreedte — was voorheen desktop/mobiel
   gesplitst om de zijbalk resp. onderbalk te ontwijken, die zijn er niet
   meer. Bewust GEEN zichtbaar icoontje (het 📁-symbool zelf is met kleur,
   dus ook op lage opacity nog goed te zien) — alleen een heel klein, vaag
   kadertje. Werkt vanzelf mee met beide thema's via var(--border-color). */
#samples-hidden-trigger{
  position:fixed; left:8px; bottom:8px; z-index:15; width:14px; height:14px;
  background:transparent; border:1px solid var(--border-color); border-radius:4px;
  padding:0; cursor:pointer; opacity:.3; transition:opacity .2s ease, background-color .2s ease;
  font-size:0; line-height:0; color:transparent;
}
#samples-hidden-trigger:hover{ opacity:.9; background:var(--bg-card); }

/* MIDI-statusbolletje (Fase 1.1): net zo bewust onopvallend als
   #samples-hidden-trigger hierboven, ernaast geplaatst — grijs/gedimd zolang
   er niets verbonden is (of de browser geen Web MIDI ondersteunt), groen
   zodra een apparaat actief is. Geen klik-actie (nog geen apparaat-kiezer),
   dus geen cursor:pointer/hover-stijl nodig — de title-tooltip blijft wel
   werken zonder pointer-events uit te zetten. Zelfde schermbreedte-
   vereenvoudiging als hierboven sinds v0.17.5. */
#midi-status-indicator{
  position:fixed; left:28px; bottom:11px; z-index:15; width:8px; height:8px;
  border-radius:50%; background:var(--text-muted); opacity:.35;
  transition:background-color .2s ease, opacity .2s ease;
}
#midi-status-indicator.connected{ background:#22c55e; opacity:.9; }

#content-area{ flex:1; display:flex; flex-direction:column; overflow:hidden; min-width:0; }
/* Grid i.p.v. flex+space-between (gebruikersfeedback: met de modus-
   schakelaar als los 4e flex-item stond die met een grote, onnette
   tussenruimte los van de terug-knop, EN duwde de titel uit het midden).
   `1fr auto auto 1fr` met #module-title in de middelste `auto`-kolom(men)
   houdt de titel gegarandeerd gecentreerd t.o.v. de volledige breedte,
   ongeacht hoeveel er links (.topbar-left) of rechts (.topbar-right) staat
   — zolang geen van beide kolommen breder wordt dan zijn `1fr`-aandeel. */
#content-topbar{
  background-color:transparent; backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
  padding:14px 22px; display:grid; grid-template-columns:1fr auto 1fr;
  align-items:center; gap:16px; border-bottom:1px solid var(--border-color); position:relative;
  z-index:30; transition:background-color .3s; flex-shrink:0;
}
/* Light mode: getinte kaart-achtergrond i.p.v. puur transparant (sinds
   v0.18.3-feedback, "header mag beter uitspringen") — nu het canvas
   (--bg-dark) zuiver wit is, moet de topbar juist NIET ook wit-op-wit zijn;
   dezelfde lichtblauwe tint als --bg-card/--paper-bg (zie de toelichting
   bij [data-theme="light"] hierboven) geeft 'm hetzelfde "opgetilde
   kaart"-gevoel als de flashcard eronder, i.p.v. gewoon lucht. */
[data-theme="light"] #content-topbar{ background-color:rgba(227,245,250,.8); }
.topbar-left{ display:flex; align-items:center; gap:10px; grid-column:1; justify-self:start; min-width:0; }
#content-topbar h1{
  grid-column:2; justify-self:center; text-align:center;
  font-family:'Fraunces',serif; font-size:1.5rem; font-weight:600; letter-spacing:.2px; color:var(--text-main);
}
.topbar-right{ display:flex; gap:8px; align-items:center; grid-column:3; justify-self:end; }

/* Instellingen-knop (opent #settings-drawer) — vervangt de oude header-
   instellingenrij + het inklapbare mobiele paneel door één zelfde
   mechanisme op elke schermbreedte. */
#settings-btn{
  width:40px; height:40px; padding:0; border-radius:50%; flex-shrink:0;
  display:inline-flex; align-items:center; justify-content:center; font-size:1.05rem;
}

/* Terug-knop + geluid/thema/fullscreen/taal (sinds v0.17.5 hier, verhuisd
   uit de vervallen zijbalk-footer/onderbalk — zie Root_Note_Context.md).
   Zelfde ronde-knop-vorm als #settings-btn hiernaast. */
.topbar-icon-btn{
  width:40px; height:40px; padding:0; border-radius:50%; flex-shrink:0;
  background:transparent; border:1px solid var(--border-color); color:var(--text-muted);
  display:inline-flex; align-items:center; justify-content:center; font-size:1.05rem;
  transition:background-color .15s ease, color .15s ease;
}
.topbar-icon-btn:hover{ background:var(--bg-card); color:var(--text-main); }
/* Thema-/geluid-SVG's (THEME_SOUND_ICONS, `.sys-icon`, sinds v0.18.3)
   hebben geen eigen width/height-attribuut — zonder expliciete maat viel de
   browser terug op een intrinsieke standaardgrootte die per context anders
   uitpakte (te groot in de topbar, te klein op de cover-/tegelpagina; een
   eerdere poging met losse per-context pixel-regels loste de topbar wél op
   maar de cover-/tegelpagina-variant bleef om onduidelijke reden op de
   oude, te kleine maat hangen). `1em` i.p.v. een vaste pixelwaarde is
   robuuster: elke knop-context bepaalt zijn eigen icoon-grootte gewoon via
   zijn BESTAANDE `font-size` (topbar 1.05rem, cover-/tegelpagina 1.2rem,
   zie de knop-basisregels), zelfde principe als hoe de oude emoji's altijd
   al schaalden. */
.sys-icon{ width:1em; height:1em; display:block; flex-shrink:0; }

/* Modus-schakelaar (sinds de tegel-consolidatie naar 1 tegel per app) —
   vervangt de vroegere Modus-tegels op de tegel-pagina: je kiest de modus nu
   direct in de app en kunt tussentijds wisselen zonder terug te gaan. Zit
   sinds de logo-ronde (gebruikersverzoek: "kunnen ze niet gewoon op de
   bestaande [balk] naast het pijltje") INLINE in `#content-topbar` naast
   `#back-to-tiles-btn`, i.p.v. een eigen balk eronder — dus geen eigen
   border-bottom/padding meer nodig, de topbar levert dat al. Een
   MIDI-vereisende modus is grijs/niet-klikbaar zolang MidiEngine.connected
   false is (zie App.renderModeSwitcher), met een tooltip die uitlegt
   waarom — bewust GEEN aparte badge-stijl hier (die kleurtaal leeft al op
   de tegel-pagina), gewoon een gedimde knop is duidelijk genoeg naast de
   actieve/beschikbare modi ernaast. */
#mode-switcher-bar{
  display:none; gap:6px; flex-wrap:wrap; flex-shrink:0;
}
/* Tekstkleur op gebruikersfeedback opgehoogd ("kleurcontrast niet goed te
   lezen") — was `var(--text-muted)` voor ELKE niet-actieve knop, inclusief
   gewoon-beschikbare modi (niet alleen de MIDI-only-gedimde), tegen de
   doorzichtige/geblurde topbar-achtergrond te weinig contrast. Beschikbare
   modi lezen nu net zo goed als de actieve knop; alleen `.disabled` (MIDI
   vereist, geen keyboard) blijft bewust gedimd, maar minder extreem dan
   voorheen (opacity .45→.55) zodat de tekst nog leesbaar blijft i.p.v.
   vrijwel te verdwijnen. */
/* Glasachtige look (v0.20.0, gebruikersverzoek — kleur zelf blijft
   ongewijzigd) — zelfde `--bg-panel-glass`/`backdrop-filter:blur`-recept als
   de instellingen-drawer/zijbalk sinds de Piano Masterclass "Aurora
   Glass"-ronde, hier voor het eerst op de modus-knoppenrij toegepast. */
.mode-switch-btn{
  padding:6px 13px; border-radius:999px; border:1px solid var(--border-color);
  background:var(--bg-panel-glass); backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  color:var(--text-main); font-size:.78rem; font-weight:600;
  font-family:'Inter',sans-serif; cursor:pointer;
  transition:background-color .15s ease, color .15s ease, border-color .15s ease;
}
.mode-switch-btn:hover:not(.disabled):not(.active){ border-color:var(--accent); }
.mode-switch-btn.active{ background:var(--accent); border-color:var(--accent); color:var(--accent-ink); font-weight:700; }
.mode-switch-btn.disabled{ color:var(--text-muted); opacity:.55; cursor:not-allowed; }

@media (max-width:640px){
  #content-topbar{ padding:12px 14px; display:flex; flex-wrap:wrap; }
  /* .topbar-left ontgrendeld terug naar gewone flex-children van de topbar
     (`display:contents` laat de wrapper zelf geen doos meer vormen) zodat
     de bestaande regel-per-regel-wikkel-logica hieronder (terug-knop+titel
     op regel 1, schakelaar op regel 2, iconen op regel 3) ongewijzigd blijft
     werken — de grid-indeling hierboven is puur voor breed scherm. */
  .topbar-left{ display:contents; }
  #content-topbar h1{
    font-size:1.05rem; flex:1 1 auto; min-width:0; overflow:hidden;
    text-overflow:ellipsis; white-space:nowrap;
  }
  /* Modus-schakelaar wikkelt op smal scherm naar haar eigen volle regel
     (net als .topbar-right hieronder) i.p.v. de titel te verdringen. */
  #mode-switcher-bar{ flex-basis:100%; order:3; }
  /* De iconen-cluster wikkelt naar een eigen regel (flex-basis:100% dwingt
     een nieuwe regel af in de flex-wrap-topbar) zodat terug-knop + titel op
     regel 1 blijven staan, ook bij een lange "App — Modus"-titel. */
  .topbar-right{ flex-basis:100%; justify-content:flex-end; order:4; }
  .topbar-icon-btn, #settings-btn{ width:34px; height:34px; font-size:.95rem; }
}

button{
  background:var(--bg-card); color:var(--text-main); border:1px solid var(--border-color);
  padding:10px 16px; border-radius:var(--radius-sm); cursor:pointer; transition:all .18s ease; font-weight:600;
  font-size:.95rem; display:flex; align-items:center; justify-content:center; gap:8px;
}
button:hover{ background:var(--border-color); }
button:active{ transform:scale(.97); }
/* Effen cyaan i.p.v. de cyaan-magenta-gradient (v0.20.0, gebruikersfeedback:
   "een functionele knop met twee kleuren leest niet fijn") — zelfde
   `--accent`-kleur als de knopgroep-actieve-stand (.opt-btn.active), puur de
   gradient eraf. */
button.primary{ background:var(--accent); color:var(--accent-ink); border:none; box-shadow:0 6px 18px rgba(34,211,238,.35); }
button.primary:hover{ filter:brightness(1.08); }
button.primary:active{ filter:brightness(.96); }
button:disabled{ opacity:.45; cursor:not-allowed; transform:none; }

select, input[type="number"]{
  background:var(--bg-dark); color:var(--text-main); border:1px solid var(--border-color);
  padding:12px; border-radius:var(--radius-sm); outline:none; font-size:.9rem; font-weight:500;
  transition:background-color .3s, color .3s, border-color .2s;
}
select:focus{ border-color:var(--accent); }

#main-container{ flex:1; display:flex; flex-direction:column; overflow:hidden; position:relative; }
#init-overlay{
  position:fixed; inset:0; background:var(--overlay-bg); display:flex; flex-direction:column;
  justify-content:center; align-items:center; z-index:9999; text-align:center; padding:20px;
  overflow-y:auto; transition:background-color .3s;
}
.theme-toggle-container{ position:absolute; top:20px; right:20px; z-index:20; display:flex; gap:8px; }
/* Sinds v0.17.5: dezelfde rechtsboven-thema/taal-knoppen op #tiles-page als
   op #init-overlay (gebruikersverzoek) — selectors verbreed i.p.v. verdubbeld. */
#lang-btn-start, #lang-btn-tiles{ font-family:'Inter',sans-serif; font-weight:700; font-size:.8rem; padding:0; }
#init-overlay .start-theme-btn, #tiles-page .start-theme-btn{
  background:var(--bg-panel-glass); border:1px solid var(--border-color); width:44px; height:44px; border-radius:50%;
  display:flex; align-items:center; justify-content:center; font-size:1.2rem; backdrop-filter:blur(10px);
  color:var(--text-main); cursor:pointer;
}

/* Tegel-overzicht (sinds v0.17.5) — tussenscherm tussen coverpagina en een
   module, zelfde fixed-fullscreen-recept als #init-overlay maar een eigen,
   lagere z-index (ze zijn mutueel exclusief via display:none/flex, maar
   nooit gelijk aan elkaar laten zijn is veiliger). Top-uitgelijnd i.p.v.
   verticaal gecentreerd (zoals #init-overlay) — een lijst van 9 groepen/17
   tegels past niet altijd op één scherm, dus overflow-y:auto i.p.v. één
   gecentreerde kaart. */
#tiles-page{
  position:fixed; inset:0; background:var(--overlay-bg); z-index:9998;
  display:flex; flex-direction:column; align-items:center;
  padding:76px 20px 40px; overflow-y:auto; transition:background-color .3s;
}
/* Ambient gloed-blobs (sinds de dashboard-herstijling, gebruikersverzoek:
   "de referentiestijl is de gecentreerde glow-esthetiek van het
   startscherm") — hergebruikt #init-overlay .welcome-bg-decor/.blob/
   @keyframes blob-float (selectors verbreed naar #tiles-page, zie verderop
   in dit bestand) i.p.v. verdubbeld. */
/* Tegel-grid: geconsolideerd naar 1 tegel per app (8 tegels totaal, was 17
   tegels/9 gegroepeerde rijen) — past daardoor op vrijwel elk scherm zonder
   scrollen, dus geen aparte .tile-group/.tile-group-header-indeling meer
   nodig (elke tegel draagt zijn eigen naam al). Vaste kolomaantal per
   breakpoint i.p.v. auto-fill — voorspelbaar. **3 kolommen op groot scherm
   (was 4, gebruikersverzoek: "misschien 3x3" — 9 tegels vormen zo een
   nette 3x3-rooster i.p.v. 4+4+1) geeft bredere tegels, dus meer ruimte
   voor de omschrijving vóór de 3-regel-afkap (zie .tile-desc verderop).**
   De oude 700-1000px-tussenstap (ook 3 kolommen) is nu overbodig, want dat
   is al de standaardwaarde. */
#tiles-grid{
  position:relative; z-index:10; width:100%; max-width:1200px;
  display:grid; grid-template-columns:repeat(3, 1fr); gap:20px; padding-bottom:20px;
}
@media (max-width:700px){ #tiles-grid{ grid-template-columns:repeat(2, 1fr); } }
@media (max-width:460px){ #tiles-grid{ grid-template-columns:1fr; } }
/* Horizontale opzet (icoon links, titel+omschrijving ernaast) — een
   tussentijdse ronde met een 50/50 icoon/tekst-grid + scheidingslijn is op
   gebruikersverzoek weer teruggedraaid ("het is gelukt maar levert toch
   niet het gewenste resultaat op"); alleen de badge-positie uit die ronde
   (gecentreerd onderaan, zie .tile-badge verderop) is behouden. */
.tile-btn{
  /* aspect-ratio 4/3 -> 2/1 (gebruikersfeedback: "veel losse ruimte boven
     de badge") — 4/3 was afgestemd op de vorige tegel-indeling (badge
     rechtsboven, verder geen ondergrens), met de badge nu onderaan
     gecentreerd bleef er duidelijk lucht over tussen de gecentreerde
     icoon+tekst-rij en de badge-regel.
     Bijgesteld naar 5/2 toen het raster van 4 naar 3 kolommen ging (bredere
     tegels): aspect-ratio schaalt met de BREEDTE, dus bredere tegels op
     hetzelfde 2/1 zouden ook merkbaar hoger zijn geworden en de net
     opgeloste lege-ruimte-klacht weer deels terugbrengen — 5/2 houdt de
     tegelhoogte ongeveer waar die stond vóór de kolom-wijziging. */
  position:relative; aspect-ratio:5/2; display:flex; flex-direction:row; align-items:center;
  gap:16px;
  /* Iets lichter dan het canvas (var(--bg-card)) + een subtiele, semi-
     transparante accent-gloed rechtsboven in de tegel — zelfde "glow"-
     gevoel als de ambient blobs, maar lokaal per tegel. */
  background:radial-gradient(circle at 85% 10%, rgba(34,211,238,.14), transparent 55%), var(--bg-card);
  border:1px solid var(--border-color); border-radius:var(--radius-md);
  /* Padding-bottom groter dan -top: de icoon+tekst-rij staat gecentreerd
     (align-items:center) binnen deze box, extra ruimte onderin houdt 'm
     los van de onderaan-gecentreerde badge i.p.v. eroverheen te vallen nu
     de tegel minder hoog is (aspect-ratio 2/1). */
  padding:16px 20px 30px; text-align:left;
  transition:transform .2s ease, border-color .2s ease, box-shadow .2s ease; cursor:pointer;
}
.tile-text{ display:flex; flex-direction:column; gap:4px; min-width:0; }
.tile-btn:hover{ transform:translateY(-4px); border-color:var(--accent); box-shadow:0 14px 32px rgba(34,211,238,.32); }
.tile-btn:active{ transform:translateY(-1px) scale(.98); }
/* Icoon-cirkel — HERZIEN (Neon-herstijling, v0.18.0): niet langer een
   zelf-getekend wit SVG-icoon op een aparte accent-kleurverloop-cirkel —
   de negen PianoICO_Library-PNG's dragen hun neon-cirkel-badge AL
   ingebakken (cyaan/magenta-lijnwerk op een eigen donkere ronde
   achtergrond, zie TILE_ICONS in tiles-ui.js), dus geen tweede cirkel er
   omheen meer nodig (dat gaf eerder een dubbele-cirkel-effect tijdens het
   testen). `.tile-icon-wrap` is nu puur een maat-container; de gloed komt
   van een `drop-shadow`-filter op de `<img>` zelf i.p.v. een
   `box-shadow` op een gekleurd vlak — een `drop-shadow` volgt de
   ronde/transparante vorm van de PNG, een `box-shadow` zou een vierkante
   gloed achter de cirkel tonen. */
.tile-icon-wrap{
  width:64px; height:64px; border-radius:50%;
  display:flex; align-items:center; justify-content:center; flex-shrink:0;
}
.tile-icon-wrap img{
  width:100%; height:100%; object-fit:contain; pointer-events:none;
  filter:drop-shadow(0 0 10px rgba(34,211,238,.55)) drop-shadow(0 0 18px rgba(192,38,211,.28));
}
.tile-label{ font-size:1.05rem; font-weight:800; color:var(--text-main); font-family:'Inter',sans-serif; }
/* Max 3 regels (gebruikersverzoek) via line-clamp, geen aparte mobiele
   verberg-regel meer nodig (bredere tegels op elke breedte dan de vorige
   opzet, dus altijd ruimte voor op z'n minst 1-2 regels). */
.tile-desc{
  font-size:.74rem; color:var(--text-muted); line-height:1.35;
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden;
}
/* Badge gecentreerd ONDERAAN (sinds v0.18.3, was de rechterbovenhoek sinds
   de dashboard-herstijling in v0.17.6) — enige stuk dat overleefde uit een
   verder teruggedraaide tegel-herontwerpronde (zie .tile-btn hierboven).
   `position:absolute` + `left:50%`/`transform` i.p.v. de eerdere
   `margin-top:auto`-flexbox-aanpak uit die ronde, want `.tile-btn` is weer
   een horizontale rij (icoon+tekst naast elkaar), niet meer een kolom
   waarin de badge vanzelf onderaan terechtkomt. De kleurgecodeerde vulling
   (groen/amber) uit v0.17.6 is op gebruikersverzoek destijds al
   TERUGGEDRAAID naar de rustigere, uniforme outline-stijl uit v0.17.5 —
   alleen de TEKST verschilt nog tussen "MIDI Enabled"/"MIDI Only", geen
   apart gevuld/solid-kleurtje meer. */
.tile-badge{
  position:absolute; bottom:10px; left:50%; transform:translateX(-50%);
  display:inline-block; padding:2px 9px; border-radius:999px; font-size:.6rem; font-weight:800;
  letter-spacing:.03em; font-family:'JetBrains Mono',monospace;
  color:var(--accent); border:1px solid var(--accent); background:transparent;
  white-space:nowrap;
}
.tile-badge-construction{ color:var(--text-muted); border-color:var(--text-muted); background:transparent; }
/* Vooruit Lezen-tegel (sinds v0.17.5 terug als tegel, was tot en met
   v0.17.4 volledig uit de navigatie verborgen): blijft een gewone, klikbare
   <button> — de klik doet alleen niets (zie TilesUI/App), de grijze/
   gedimde stijl communiceert dat. */
.tile-btn.tile-disabled{ filter:grayscale(1); opacity:.55; cursor:default; }
.tile-btn.tile-disabled:hover{ transform:none; border-color:var(--border-color); box-shadow:none; }

/* Ambient kleurwolken, zelfde idee als body{background-image:...}
   elders in de app — hier lokaal herhaald omdat #init-overlay
   (z-index:9999) boven die achtergrond ligt. */
#init-overlay .welcome-bg-decor, #tiles-page .welcome-bg-decor{ position:absolute; inset:0; overflow:hidden; z-index:1; pointer-events:none; }
#init-overlay .blob, #tiles-page .blob{ position:absolute; border-radius:50%; filter:blur(80px); opacity:.2; animation:blob-float 20s infinite alternate ease-in-out; }
#init-overlay .blob.one, #tiles-page .blob.one{ width:60vh; height:60vh; background:var(--accent); top:-10vh; left:-10vh; }
#init-overlay .blob.two, #tiles-page .blob.two{ width:50vh; height:50vh; background:var(--accent-2); bottom:-15vh; right:-10vh; animation-delay:-5s; }
@keyframes blob-float{
  0%{ transform:translate(0,0) scale(1); }
  50%{ transform:translate(5vh,10vh) scale(1.1); }
  100%{ transform:translate(-5vh,5vh) scale(1); }
}

#init-overlay .welcome-content{ position:relative; z-index:10; display:flex; flex-direction:column; align-items:center; gap:40px; max-width:600px; width:100%; }

/* De hele merk-/titelkaart IS de start-knop — duidelijk kader +
   hover/press-gedrag zodat hij oogt/voelt als iets om in te drukken. */
#init-overlay .brand-launch-btn{
  display:flex; flex-direction:column; align-items:center; gap:22px;
  background:var(--bg-panel-glass); border:1px solid var(--border-color); border-radius:var(--radius-lg);
  padding:48px 56px; cursor:pointer; position:relative; overflow:hidden;
  backdrop-filter:blur(20px); -webkit-backdrop-filter:blur(20px);
  box-shadow:var(--shadow-lg);
  transition:transform .25s ease, border-color .25s ease;
}
#init-overlay .brand-launch-btn::before{
  content:''; position:absolute; inset:0; background:linear-gradient(135deg, transparent, rgba(255,255,255,.12), transparent);
  transform:translateX(-120%); transition:transform .5s ease; pointer-events:none;
}
#init-overlay .brand-launch-btn:hover{ transform:translateY(-4px); border-color:var(--accent); }
#init-overlay .brand-launch-btn:hover::before{ transform:translateX(120%); }
#init-overlay .brand-launch-btn:active{ transform:translateY(-1px) scale(.98); }

.brand-mark-lg{
  width:78px; height:78px; border-radius:24px; background:linear-gradient(135deg, var(--accent), var(--accent-2)); color:#fff;
  display:flex; align-items:center; justify-content:center; font-size:2.3rem;
  box-shadow:0 16px 34px rgba(34,211,238,.4);
}
.brand-mark-lg svg{ width:42px; height:42px; }

.glitter{ position:relative; overflow:hidden; }
.glitter::after{
  content:''; position:absolute; inset:-50%;
  background:linear-gradient(135deg, transparent, rgba(255,255,255,.4), transparent);
  transform:rotate(45deg); animation:glitter-sweep 4s infinite;
}
@keyframes glitter-sweep{
  0%{ transform:translate(-100%,-100%) rotate(45deg); }
  20%,100%{ transform:translate(100%,100%) rotate(45deg); }
}

#init-overlay .main-title{
  font-family:'Fraunces',serif; font-size:clamp(2.8rem, 8vw, 4rem); font-weight:700;
  color:var(--text-main); line-height:1.1; margin:0;
  background:linear-gradient(135deg, var(--text-main) 60%, var(--accent));
  -webkit-background-clip:text; -webkit-text-fill-color:transparent; filter:drop-shadow(0 2px 4px rgba(0,0,0,.1));
}
#init-overlay .sub-title-premium{ font-size:clamp(1rem, 3vw, 1.2rem); color:var(--text-muted); letter-spacing:2px; text-transform:uppercase; font-weight:600; margin-top:5px; }

#init-overlay .start-meta{ display:flex; flex-direction:column; align-items:center; gap:8px; }
#init-overlay .version-tag{ font-size:.75rem; color:var(--text-muted); font-family:'JetBrains Mono',monospace; opacity:.7; }
.creator-credit{ color:var(--text-muted); font-size:.9rem; font-weight:500; letter-spacing:.5px; }

@media (min-width:900px){
  #init-overlay .main-title{ font-size:4.5rem; }
  #init-overlay .brand-launch-btn{ padding:56px 80px; }
}
@media (max-width:480px){
  #init-overlay .brand-launch-btn{ padding:34px 28px; gap:18px; }
  #init-overlay .welcome-content{ gap:28px; }
}

#module-view{ width:100%; flex:1; display:flex; flex-direction:column; overflow:hidden; }

/* Instellingen wonen in het opvraagbare paneel (drawer, #settings-drawer)
   i.p.v. een altijd-zichtbare balk boven de kaart — knoppen i.p.v. een
   dropdown-menu, zodat je in één tik kunt wisselen (zelfde patroon als de
   kwintencirkel), maar nu opt-in via de tandwiel-knop. */
#quick-controls{
  width:100%; display:flex; flex-direction:column; align-items:stretch; gap:22px;
}
#quick-controls:empty{ display:none; }
.setting-group{ display:flex; flex-direction:column; gap:6px; align-items:flex-start; width:100%; }
.setting-group label{
  display:inline-flex; align-items:center; gap:6px; font-size:.68rem; color:var(--text-muted);
  text-transform:uppercase; letter-spacing:.6px; font-weight:700;
}
.aa-icon{ width:19px; height:19px; flex-shrink:0; }
/* Type/Toonsoort naast elkaar i.p.v. onder elkaar (v0.20.0, Toonladders-
   verzoek: "de vele opties zorgen voor een wat vollere weergave") — Type
   verticaal (één knop per regel, i.p.v. de gewone wrappende rij) links,
   Toonsoort (blijft wél wrappen, 12 knoppen) rechts, met een subtiel
   verticaal lijntje ertussen. Valt terug naar gestapeld op een smalle
   drawer/telefoon (zelfde `minmax`-truc als .auto-adv-controls hierboven).
   Generiek genoeg om ook elders te hergebruiken, niet Toonladders-specifiek
   in de CSS zelf. */
.settings-split{ display:grid; grid-template-columns:minmax(90px,auto) 1px minmax(140px,1fr); gap:0 14px; align-items:start; }
.settings-split-col{ display:flex; flex-direction:column; gap:6px; align-items:flex-start; min-width:0; }
.settings-split-divider{ align-self:stretch; background:var(--border-color); width:1px; }
.opt-row-vertical{ flex-direction:column; align-items:stretch; }
.opt-row-vertical .opt-btn{ text-align:left; white-space:nowrap; }
/* Toonladders Type-kolom: altijd de korte knoplabels (zie
   Lang.scaleNameShort in lang.js), niet pas onder een breakpoint zoals
   .lbl-short elders — deze kolom is altijd smal (zie .settings-split), dus
   "Mineur Harmonisch" e.d. paste anders op geen enkele breedte op 1 regel. */
#opt-scale-types .lbl-full{ display:none; }
#opt-scale-types .lbl-short{ display:inline; }
/* Akkoorden Type-kolom: zelfde reden/patroon (CircleWheel.chordAbbr als
   shortLabel, zie app-core.js) — "Diminished" e.d. past anders niet op 1
   regel in deze nu smalle kolom. */
/* 13 Akkoorden-types is te veel voor 1 lange kolom (i.t.t. Toonladders'
   7) — 2 kolommen naast elkaar i.p.v. .opt-row-vertical's gewone enkele-
   kolom-gedrag, zodat de instellingen geen lange lijst worden
   (gebruikersverzoek, vervolg). */
#opt-chord-types{ display:grid; grid-template-columns:repeat(2, 1fr); gap:6px; }
/* Toonsoort (12 knoppen) blijft de gewone wrappende .opt-row (zie hieronder)
   — een geforceerde bredere grid (bijv. 4 kolommen) bleek de beschikbare
   drawerbreedte te overschrijden (horizontale scrollbar, knoppen afgesneden,
   bevestigd met een screenshot) zodra de Type-kolom ernaast ook al ruimte
   claimt. De natuurlijke wrap (3 kolommen × 4 rijen bij de standaard
   drawerbreedte) is het compactst wat hier zonder overflow past. */
#opt-chord-types .lbl-full{ display:none; }
#opt-chord-types .lbl-short{ display:inline; }
@media (max-width:420px){
  .settings-split{ grid-template-columns:1fr; }
  .settings-split-divider{ display:none; }
}
.aa-delay-val{ text-transform:none; letter-spacing:0; color:var(--text-main); }
/* Knop-labels met een korte mobiele variant (bijv. "Niv 1 (C3-C5)" i.p.v.
   "Makkelijk (C3-C5)") — standaard (breed scherm) toont de volledige tekst. */
.lbl-short{ display:none; }
.opt-row{ display:flex; flex-wrap:wrap; gap:6px; justify-content:flex-start; }
.opt-btn{
  background:var(--bg-dark); color:var(--text-main); border:1px solid var(--border-color);
  border-radius:var(--radius-sm); padding:8px 14px; font-size:.85rem; font-weight:700; cursor:pointer;
  transition:all .15s ease; font-family:'JetBrains Mono',monospace;
}
.opt-btn:hover{ background:var(--border-color); }
/* Effen cyaan i.p.v. de gradient (v0.20.0) — zelfde reden als button.primary
   hierboven. */
.opt-btn.active{ color:var(--accent-ink); background:var(--accent); border-color:transparent; box-shadow:0 4px 12px rgba(34,211,238,.35); }
/* Handen-icoontjes (Toonladders MIDI-modus) — PNG-crops i.p.v. inline SVG
   (v0.20.0, gebruikersverzoek: eigen aangeleverde tekening i.p.v. een
   zelfgetekend silhouet), vaste hoogte + auto-breedte zodat "beide handen"
   (breder) en de losse hand-iconen naast elkaar netjes uitlijnen. Effen
   grijze bronafbeelding (geen `currentColor`) — past in zowel het lichte
   als donkere thema zonder aanpassing. */
.hand-icon{ height:38px; width:auto; display:block; flex-shrink:0; }

.auto-delay-slider{
  -webkit-appearance:none; appearance:none; width:150px; height:6px; border-radius:3px;
  background:var(--border-color); outline:none; cursor:pointer;
}
.auto-delay-slider::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none; width:20px; height:20px; border-radius:50%;
  background:linear-gradient(135deg, var(--accent), var(--accent-2)); cursor:pointer; box-shadow:0 2px 6px rgba(0,0,0,.3);
}
.auto-delay-slider::-moz-range-thumb{
  width:20px; height:20px; border-radius:50%; border:none;
  background:linear-gradient(135deg, var(--accent), var(--accent-2)); cursor:pointer; box-shadow:0 2px 6px rgba(0,0,0,.3);
}
/* Challenge-BPM-slider + handmatig tekstveld (v0.20.0) — de slider zelf
   hergebruikt .auto-delay-slider; alleen de rij-indeling en het tekstveld/
   "BPM"-label zijn nieuw. `list=` op de slider (zie
   buildChallengeSpeedControl()) geeft native tick-streepjes op elke 15
   BPM-stap zonder extra CSS. */
.bpm-control-row{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.bpm-control-row .auto-delay-slider{ flex:1 1 140px; max-width:200px; }
.bpm-manual-input{
  /* 56px i.p.v. 72px oogde te krap (gebruikersfeedback, screenshot) — een
     `type="number"`-veld reserveert intern ruimte voor de browser-eigen
     spinner-pijltjes, dus het echte tekstgedeelte was smaller dan de
     opgegeven breedte deed vermoeden. */
  width:72px; background:var(--bg-dark); color:var(--text-main); border:1px solid var(--border-color);
  border-radius:var(--radius-sm); padding:5px 6px; font-size:.85rem; font-weight:700;
  font-family:'JetBrains Mono',monospace; text-align:center;
}
.bpm-manual-input:focus{ outline:none; border-color:var(--accent); }
.bpm-unit-label{ font-size:.72rem; font-weight:700; color:var(--text-muted); letter-spacing:.4px; }

#workspace{
  flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; justify-content:safe center;
  padding:22px; background:var(--bg-dark); overflow-y:auto; overflow-x:hidden; width:100%;
}

/* Instellingen wonen nu altijd in het opvraagbare paneel (drawer, zie
   #settings-drawer) i.p.v. een header-rij op breed scherm vs. een
   inklapbaar paneel op smal scherm — daarom gelden de "smal-scherm"-
   opmaakregels voor instellingen nu ONVOORWAARDELIJK (de drawer zelf is
   altijd zo'n 380px breed, ongeacht viewportbreedte). */
/* Auto-Doorgaan + Bedenktijd naast elkaar (v0.20.0, gebruikersverzoek: "zijn
   aan elkaar gekoppeld") i.p.v. onder elkaar — `minmax(140px,1fr)` valt
   vanzelf terug naar 1 kolom zodra de drawer te smal wordt om beide naast
   elkaar te tonen, geen aparte @media-regel nodig. */
.auto-adv-controls{ display:grid; grid-template-columns:repeat(2, minmax(140px, 1fr)); gap:14px 16px; justify-content:flex-start; }
.auto-adv-controls .auto-delay-slider{ width:100%; max-width:280px; }

/* Niveau-knoppen (Noten Lezen) onder elkaar i.p.v. 3-op-een-rij — de
   drawer heeft nu ruim genoeg verticale ruimte, dus de volledige labels
   ("Makkelijk (C3-C5)") passen weer gewoon op één regel per knop (zie
   basisregel .lbl-short{display:none} hierboven — .lbl-full blijft dus
   gewoon zichtbaar, geen override meer nodig). */
#opt-notes-level{ display:grid; grid-template-columns:1fr; gap:6px; }
#opt-notes-level .opt-btn{ justify-content:flex-start; text-align:left; }

/* ---- Instellingen-paneel (drawer), rechts, op elke schermbreedte ---- */
#settings-drawer-backdrop{
  position:fixed; inset:0; background:rgba(0,0,0,.35); z-index:8999; opacity:0; pointer-events:none; transition:opacity .25s ease;
}
#settings-drawer-backdrop.open{ opacity:1; pointer-events:auto; }
#settings-drawer{
  position:fixed; top:0; right:0; height:100vh; height:100dvh; width:min(380px, 92vw); z-index:9000;
  background:var(--bg-panel-glass); backdrop-filter:blur(20px); -webkit-backdrop-filter:blur(20px);
  border-left:1px solid var(--border-color); box-shadow:var(--shadow-lg);
  transform:translateX(100%); transition:transform .28s cubic-bezier(.4,0,.2,1);
  display:flex; flex-direction:column; padding:22px;
}
#settings-drawer.open{ transform:translateX(0); }
.settings-drawer-head{ display:flex; justify-content:space-between; align-items:center; margin-bottom:20px; flex-shrink:0; }
.settings-drawer-head span{ font-family:'Fraunces',serif; font-weight:600; font-size:1.15rem; }
#settings-drawer-close{ width:32px; height:32px; padding:0; border-radius:50%; }
.settings-drawer-body{ overflow-y:auto; flex:1; display:flex; flex-direction:column; }
/* Reset-knop (sinds v0.17.5, per app i.p.v. globaal) — vaste laatste rij in
   de drawer, altijd onderaan dankzij App.moveQuickControlsToDrawer()'s
   insertBefore (zie app-core.js) en margin-top:auto hier. */
.settings-reset-row{ margin-top:auto; padding-top:16px; border-top:1px solid var(--border-color); }
.settings-reset-row button{ width:100%; color:var(--text-muted); }
.settings-reset-row button:hover{ color:var(--text-main); }

.flashcard{
  background:var(--paper-bg); border-radius:var(--radius-lg); width:100%; max-width:1400px; min-height:340px;
  box-shadow:var(--shadow-lg); display:flex; flex-direction:column; align-items:center;
  justify-content:center; justify-content:safe center; padding:24px; position:relative; color:var(--paper-ink); border:1px solid var(--paper-border);
  transition:background-color .3s, border-color .3s, color .3s, min-height .3s ease; overflow-x:hidden;
}

/* Toonladders "Oefenen"-modus (sinds v0.20.5) — zelfde vormgevingspatroon
   als #scroll-counter (dikgedrukt, accent-cyaan, gecentreerd): de "X/N
   foutloos"-teller. .drill-flash wisselt tijdelijk naar groen/rood voor
   directe terugkoppeling (voltooid/te langzaam/foute noot), zelfde
   kleurenpaar als #scroll-status/#midi-answer-status hierboven. */
#scale-drill-status{
  font-size:1.05rem; font-weight:800; color:var(--accent); font-family:'JetBrains Mono',monospace;
  text-align:center; margin-bottom:10px; transition:color .15s ease;
}
#scale-drill-status.drill-flash-correct{ color:#22c55e; }
#scale-drill-status.drill-flash-wrong{ color:#ef4444; }
/* Tempo-logboek (sinds v0.20.8) — bewust kleiner/gedimd t.o.v.
   #scale-drill-status hierboven: dat blijft het primaire, opvallende
   signaal (teller + groen/rood-flash), dit is secundaire, blijvend
   zichtbare context eronder. */
#scale-drill-bpm-log{
  font-size:.85rem; font-weight:600; color:var(--text-muted); font-family:'JetBrains Mono',monospace;
  text-align:center; margin-top:-6px; margin-bottom:10px;
}
/* Gespeeld tempo, gewone MIDI-modus (sinds v0.20.9) — zelfde opvallende
   stijl als #scale-drill-status (geen streak/doel hier, dus geen
   flash-varianten nodig, puur een simpele tempo-uitlezing). */
#scale-midi-tempo{
  font-size:1.05rem; font-weight:800; color:var(--accent); font-family:'JetBrains Mono',monospace;
  text-align:center; margin-bottom:10px;
}
#score-paper{ width:100%; min-width:0; display:flex; justify-content:center; }
#score-paper svg, #answer-score svg{ width:100%; height:auto; display:block; }
/* Toonladders "Handen: Beide" dubbele weergave (Fase 2.7, aanvullend punt 1,
   v0.20.0) — twee gestapelde, onafhankelijke enkele-sleutel-notenbalken. */
#scale-dual-wrap{ display:none; flex-direction:column; align-items:center; width:100%; gap:6px; }
/* 100% → 76% (sinds v0.20.5, gebruikersmelding: "noten vallen bij twee
   handen meestal buiten het scherm") — beide notenbalken schalen mee via
   width:100%/height:auto (behouden aspect-ratio), dus een smallere
   container hier verkleint OOK de hoogte evenredig, precies wat nodig is om
   de twee gestapelde notenbalken (+ vingerzetting-cijfers/pillen/knoppen
   eronder) weer binnen een normale vensterhoogte te laten passen zonder te
   hoeven scrollen. Werkt SAMEN met (i.p.v. in plaats van) de octaafplaatsing-
   fix in _bestScaleOctave() hierboven — die vermindert al hoeveel
   hulplijntjes/8va er sowieso nodig zijn, dit is de resterende, structurele
   marge voor toonsoorten waar zelfs de beste plaatsing nog relatief veel
   ruimte kost. */
#scale-dual-treble, #scale-dual-bass{ width:76%; min-width:0; display:flex; justify-content:center; }
#scale-dual-treble svg, #scale-dual-bass svg{ width:100%; height:auto; display:block; }
#circle-chord-preview svg{ width:100%; height:auto; display:block; }
#answer-score{ margin-top:8px; width:100%; min-width:0; max-width:460px; display:flex; justify-content:center; }
#svg-container{ width:100%; display:none; flex-direction:column; align-items:center; padding:10px 0; gap:12px; position:relative; }

/* Lopende-band-modus (Fase 1.2, Noten Lezen) — child van #svg-container,
   net als .circle-main; welke van de twee zichtbaar is bepaalt
   App.renderData(). left:140px van de hit-lijn-marker MOET gelijk blijven
   aan ScrollEngine.HIT_LINE_X in scroll-engine.js (CSS kan geen JS-
   constante lezen, dus twee losse plekken die bij wijziging allebei
   bijgewerkt moeten worden). Zelfde voor height:380px, MOET gelijk blijven
   aan ScrollEngine.CANVAS_H × ScrollEngine.RENDER_SCALE (270×1.4=378,
   naar boven afgerond) — anders wordt de notenbalk weer afgesneden (zie
   de toelichting bij CANVAS_H/RENDER_SCALE in scroll-engine.js).
   max-width verwijderd (was 560px) — op verzoek "maximaliseren op de
   flashcard" i.p.v. een smal apart venstertje: vult nu gewoon de volledige
   breedte die .flashcard toelaat (zelf al begrensd op max-width:1400px). */
#scroll-view{ display:none; flex-direction:column; align-items:center; gap:14px; width:100%; }
/* Sessie-teller (sinds v0.11.0): de hele lopende-band-sessie is nu één
   doorlopende reeks (100 noten) i.p.v. steeds terugspringende reeksjes van
   8 — deze teller toont de voortgang daarin. */
#scroll-counter{
  font-size:1.1rem; font-weight:800; color:var(--accent); font-family:'JetBrains Mono',monospace;
  /* Vooruit Lezen (sinds v0.17.3) zet hier een rijtje losse segmenten
     (tijd/melodie/akkoorden/score, zie .sr-stat hieronder) i.p.v. één platte
     tekstregel — flex+wrap laat dat netjes afbreken op smalle schermen.
     Noten Lezen/Akkoorden se Lopende Band/Challenge zetten hier nog gewoon
     platte tekst (geen kind-elementen), flex heeft daar geen zichtbaar
     effect op. */
  display:flex; flex-wrap:wrap; justify-content:center; align-items:baseline; gap:6px 16px;
}
.sr-stat{ font-size:.95rem; font-weight:700; color:var(--text-muted); }
.sr-stat-time, .sr-stat-score{ color:var(--accent); font-weight:800; }
.sr-good{ color:#22c55e; }
.sr-bad{ color:#ef4444; }
#scroll-strip-host{
  /* height wordt sinds v0.16.3 per render() door ScrollEngine zelf gezet
     (`element.style.height`, zie _effectiveScale()) — de vaste 380px hier
     is puur een fallback vóór de allereerste render (voorkomt een flits
     van 0-hoogte). ScrollEngine schaalt de notatie op basis van
     window.innerHeight (nooit boven RENDER_SCALE=2.2, nooit onder
     MIN_RENDER_SCALE=1.1) — op een kort scherm (bijv. een compact
     secundair beeldscherm) zou een vaste 2.2×-hoogte de hele flashcard-
     kaart hoger maken dan de viewport, met een onhandige scrollbalk tot
     gevolg (bevestigd met foto's, gefixt in v0.16.3). */
  position:relative; width:100%; height:380px; overflow:hidden;
  border-radius:var(--radius-md); background:var(--paper-bg); border:1px solid var(--paper-border);
}
/* left:140px = de --scroll-cursor-x-fallback, moet gelijk blijven aan
   ScrollEngine.HIT_LINE_X. Vooruit Lezen (Fase 3.1) zet --scroll-cursor-x
   inline op #scroll-strip-host naar een verschoven waarde (zie
   ScrollEngine.startChallenge()'s opts.cursorMeasures) zodat de cursor
   verder in de strip staat i.p.v. vlak na de gutter — alle andere
   aanroepers laten deze var weg en vallen terug op 140px. */
#scroll-strip-host::after{
  content:''; position:absolute; left:var(--scroll-cursor-x, 140px); top:0; bottom:0; width:2px;
  background:var(--accent); opacity:.55; pointer-events:none;
}
/* Vaste sleutel-"gutter" (sinds v0.11.0, op verzoek: vioolsleutel/
   bassleutel blijven een herkenningspunt i.p.v. mee te scrollen) — width
   MOET gelijk blijven aan ScrollEngine.GUTTER_W. Ondoorzichtige achtergrond
   (zelfde als het paneel) verbergt wat er in de scrollende laag erachter
   voorbijkomt; z-index boven de scrollende strip, maar ruim vóór
   HIT_LINE_X (140px) zodat de noot bij de hit-lijn nooit overlapt wordt. */
.scroll-gutter{
  position:absolute; left:0; top:0; bottom:0; width:124px; overflow:hidden;
  background:var(--paper-bg); z-index:2; pointer-events:none;
}
#scroll-status{
  font-size:.95rem; font-weight:700; text-align:center; color:var(--text-muted); transition:color .15s ease;
}
#scroll-status.correct{ color:#22c55e; }
#scroll-status.wrong{ color:#ef4444; }

/* CSS GRID met benoemde gebieden i.p.v. flexbox+order+wrap-trucs — dat
   bleek herhaaldelijk onvoorspelbaar op écht mobiel/tablet/desktop zonder
   dat live te kunnen testen. Grid-template-areas beschrijft de layout
   letterlijk als een ASCII-tekening per breakpoint — geen giswerk.
   Mobiel (standaard): één kolom — wiel, dan notenbalk+toetsenbord, dan
   de knoppenrijen. Vanaf 900px: vier kolommen naast elkaar.
   min-width:0 blijft nodig zodat een brede notenbalk-SVG nooit een kolom
   kan dwingen breder te worden dan zijn grid-track. */
.circle-main{
  width:100%; min-width:0; display:grid; gap:14px;
  grid-template-columns: 1fr;
  /* Mobiele volgorde: wiel, dan notenbalk+keyboard, dan de
     akkoordsoort-knoppen (extra opties) onderaan — alleen op smal scherm,
     desktop houdt zijn eigen 4-koloms volgorde hieronder. */
  grid-template-areas: "wheel" "staff" "chordjump";
}
.circle-left-half{ display:contents; }
.circle-center{ grid-area:wheel; min-width:0; width:100%; max-width:480px; justify-self:center; display:flex; justify-content:center; }
#circle-wheel-wrap{ width:100%; min-width:0; display:flex; justify-content:center; aspect-ratio:1/1; max-width:480px; }
#circle-wheel-wrap svg{ width:100%; min-width:0; max-width:100%; height:auto; display:block; aspect-ratio:1/1; }
.circle-right-half{ grid-area:staff; width:100%; max-width:400px; min-width:0; display:flex; flex-direction:column; align-items:center; gap:16px; justify-self:center; }
/* Op mobiel vervangt het draaien aan het wiel zelf deze knoppenrij (zie
   CircleWheel drag-to-rotate) — op breed scherm blijft hij staan. */
#circle-quick-jump{ display:none; }
#circle-chord-jump{ grid-area:chordjump; display:flex; flex-direction:row; flex-wrap:wrap; justify-content:center; max-width:320px; gap:6px; justify-self:center; }
.circle-jump-col{ min-width:0; }
/* Akkoordnaam-label (gebruikersverzoek, v0.20.0 — ná live MIDI-test bleek
   het herkende akkoord nergens als TEKST genoemd te worden, alleen via de
   notenbalk/toetsenbord-weergave) — CircleWheel.showChord() zet hier bij
   ELKE weergave (klik én MIDI) de root+soort in, bijv. "C Majeur". */
#circle-chord-name{ font-family:'Fraunces',serif; font-weight:600; font-size:1.2rem; color:var(--text-main); text-align:center; min-height:1.4em; }
/* MIDI-afkomst (gebruikersverzoek, vervolg) — zelfde cyaan als de noten/
   toetsenbord-stipjes, om een via het keyboard ingetoetst akkoord ook in
   de naam zelf te onderscheiden van een klik. */
#circle-chord-name.midi{ color:var(--accent); }
#circle-chord-preview{ min-width:0; min-height:60px; max-width:330px; overflow:hidden; display:flex; align-items:center; justify-content:center; width:100%; }
#circle-keyboard-wrap{ display:flex; justify-content:center; justify-content:safe center; min-width:0; min-height:40px; align-items:center; overflow-x:auto; max-width:100%; width:100%; }

@media (min-width:900px){
  .circle-main{
    grid-template-columns: auto minmax(300px, 560px) auto minmax(340px, 480px);
    grid-template-areas: "keyjump wheel chordjump staff";
    align-items:center; gap:32px; justify-content:center;
  }
  .circle-center{ width:100%; max-width:560px; }
  #circle-quick-jump{
    grid-area:keyjump; display:flex; flex-direction:column; flex-wrap:wrap;
    justify-content:center; max-width:none; gap:6px; justify-self:start;
  }
  #circle-chord-jump{ flex-direction:column; max-width:none; justify-self:start; }
  .circle-right-half{ width:auto; max-width:none; padding-top:0; justify-self:stretch; }
}

html.fullscreen-active #workspace{ padding:28px; }
html.fullscreen-active .flashcard{ max-width:min(1800px, 98vw); }
html.fullscreen-active .circle-jump-btn{ font-size:1rem; height:40px; padding:0 10px; }
html.fullscreen-active .mini-key.white{ width:32px; height:112px; }
html.fullscreen-active .mini-key.black{ width:19px; height:68px; margin-left:-9.5px; margin-right:-9.5px; }
html.fullscreen-active .mini-key .mk-dot{ width:15px; height:15px; bottom:22px; }
html.fullscreen-active .mini-key.black .mk-dot{ bottom:9px; }

#circle-svg{ cursor:grab; touch-action:none; }
/* Tonica-wijzertjes: zachte gloed i.p.v. een hard contrastlijntje, zodat
   ze aansluiten bij de rest van het Aurora Glass-uiterlijk. */
.wheel-tonic-marker{ filter:drop-shadow(0 0 5px var(--accent)); }
#circle-svg:active{ cursor:grabbing; }

.circle-jump-btn{
  width:56px; height:32px; padding:0 6px; border-radius:var(--radius-sm); font-size:.76rem; font-weight:700;
  color:var(--paper-ink); background:var(--paper-btn-bg); border:1px solid var(--paper-border); flex-shrink:0; font-family:'JetBrains Mono',monospace;
  transition:all .15s ease;
}
.circle-jump-btn:hover{ background:var(--paper-btn-hover); }
/* Effen cyaan i.p.v. de gradient (gebruikersverzoek, v0.20.0, vervolg —
   zelfde reden als button.primary/.opt-btn.active hierboven: consistent
   met de rest van de app). Tekstkleur via --accent-ink i.p.v. altijd wit —
   in dark mode is --accent een felle, lichte cyaan, dus wit-op-wit-achtig
   contrast; --accent-ink is daar donkerblauw. In light mode blijft dit
   gewoon wit (--accent-ink is daar #fff, --accent zelf al dieper cyaan). */
.circle-jump-btn.active{ color:var(--accent-ink); background:var(--accent); border-color:transparent; box-shadow:0 4px 12px rgba(34,211,238,.35); }
.circle-jump-btn.chord{ width:60px; }

.mini-key{ position:relative; flex-shrink:0; user-select:none; }
.mini-key.white{ width:24px; height:88px; background:#fefcf6; border:1px solid var(--paper-border); border-radius:0 0 4px 4px; z-index:1; }
.mini-key.black{ width:15px; height:54px; background:#1c1712; margin-left:-7.5px; margin-right:-7.5px; z-index:2; border-radius:0 0 3px 3px; }
.mini-key .mk-dot{ position:absolute; left:50%; transform:translateX(-50%); width:11px; height:11px; border-radius:50%; bottom:18px; box-shadow:0 1px 3px rgba(0,0,0,.35); }
.mini-key.black .mk-dot{ bottom:8px; }
.mini-key .mk-dot.root{ background:var(--accent); }
.mini-key .mk-dot.tone{ background:#22c55e; }
/* MIDI-afkomst-kleurcode (Fase 2.7, aanvullend punt 3, v0.20.0) — grondtoon
   én overige noten dezelfde kleur, zolang de weergave het gevolg is van
   MIDI-input i.p.v. een klik op het scherm (Kwintencirkel). Was paars
   (#a855f7), op gebruikersverzoek naar dezelfde cyaan als .mk-dot.root
   gezet ("past beter") — de klik/MIDI-afkomst blijft alsnog te zien doordat
   een MIDI-akkoord ALLE stipjes (ook de niet-grondtoon-noten) uniform cyaan
   kleurt, terwijl een klik grondtoon=cyaan/overige=groen gemengd toont. */
.mini-key .mk-dot.midi{ background:var(--accent); }

@media (max-width: 640px) {
    .mini-key.white { width: 17px; height: 68px; }
    .mini-key.black { width: 10px; height: 40px; margin-left: -5px; margin-right: -5px; }
    .mini-key .mk-dot { width: 8px; height: 8px; bottom: 12px; }
    .mini-key.black .mk-dot { bottom: 5px; }
}

.text-quiz-display{ font-size:1.5rem; font-weight:bold; text-align:center; margin:15px 0; display:none; }
#answer-display{
  margin-top:10px; margin-bottom:10px; font-size:1.4rem; font-weight:800; font-family:'JetBrains Mono',monospace;
  color:var(--accent-hover); min-height:34px; opacity:0; transition:opacity .3s; text-align:center;
}
#answer-display.visible{ opacity:1; }

/* MIDI-akkoordcontrole (Fase 2.2): neutraal = "aan het luisteren" (gedimd,
   volgt tekstkleur), correct = groen, fout = rood — bewust GEEN eigen
   kleurvariabelen, dit zijn de enige twee plekken in de app die
   goed/fout-feedback tonen dus vaste kleuren volstaan. */
#midi-answer-status{
  margin-top:-6px; margin-bottom:10px; font-size:.95rem; font-weight:700; text-align:center;
  color:var(--text-muted); transition:color .15s ease;
}
#midi-answer-status.correct{ color:#22c55e; }
#midi-answer-status.wrong{ color:#ef4444; }

/* MIDI-toonladder-speel-na (Fase 2.3): één "pil" per noot van de reeks —
   grijs = nog niet bereikt, accentkleur+rand = huidig verwachte noot, groen
   = correct gespeeld (voltooid), rood = korte foutmelding op de HUIDIGE pil
   (schuift pas door bij een juiste noot, zie App._evaluateMidiScaleStep). */
#midi-scale-progress{
  margin-top:-6px; margin-bottom:10px; display:flex; flex-wrap:wrap; justify-content:center; gap:5px;
}
.midi-scale-note{
  min-width:28px; height:24px; padding:0 6px; border-radius:6px; display:flex; align-items:center; justify-content:center;
  font-size:.72rem; font-weight:700; font-family:'JetBrains Mono',monospace;
  background:var(--paper-btn-bg); color:var(--paper-muted); border:1px solid var(--paper-border);
  transition:background-color .15s ease, color .15s ease, border-color .15s ease;
}
.midi-scale-note.current{ border-color:var(--accent); color:var(--paper-ink); }
.midi-scale-note.done{ background:#22c55e; color:#fff; border-color:transparent; }
.midi-scale-note.wrong{ background:#ef4444; color:#fff; border-color:transparent; }

.flashcard-actions{ width:100%; max-width:400px; margin-top:15px; display:flex; flex-direction:column; gap:15px; }
.action-row-top{ display:flex; gap:10px; justify-content:center; }
.action-row-top button{ color:var(--paper-ink); font-weight:700; background:var(--paper-btn-bg); border:1px solid var(--paper-border); }
.action-row-top button:hover{ background:var(--paper-btn-hover); }
.action-row-bottom{ display:flex; gap:10px; }
.action-row-bottom button{ flex:1; padding:14px; font-size:1rem; }
.swipe-hint{ text-align:center; font-size:.75rem; color:var(--text-muted); margin-top:6px; }

#piano-module{ display:none; flex-direction:column; width:100%; height:100%; background:var(--bg-panel); overflow:hidden; transition:background-color .3s; }
.piano-ui-controls{ display:flex; justify-content:space-between; width:100%; max-width:600px; margin:0 auto; padding:20px; gap:10px; }
.piano-btn{ flex:1; }
/* Toets-highlight + akkoordherkenning (Fase 2.7, punten 9+10) — toont de
   naam/namen van de momenteel ingedrukte noten (met-de-hand of MIDI, zelfde
   gedeelde event-stream), plus een herkend akkoord als 2+ noten samen een
   bekend type vormen. &nbsp; als lege-staat placeholder houdt de regel-
   hoogte vast zodat de rest van het scherm niet springt zodra er iets komt
   te staan. */
.piano-note-display{
  text-align:center; min-height:1.6em; padding:0 20px 8px; font-size:1.05rem; font-weight:700;
  color:var(--accent); letter-spacing:.02em; transition:color .3s;
}
.piano-note-display .pnd-chord{ color:var(--text-muted); font-weight:600; margin-left:.5em; }
.piano-wrapper{
  width:100%; padding:20px 0; overflow-x:auto; -webkit-overflow-scrolling:touch; background:var(--bg-dark);
  border-top:1px solid var(--border-color); scroll-behavior:smooth; flex:1; display:flex; align-items:center;
}
.piano-keyboard{ display:flex; position:relative; height:250px; min-width:max-content; padding:0 40px; }
.key{ cursor:pointer; flex-shrink:0; border-radius:0 0 6px 6px; user-select:none; }
.key.white{ width:50px; height:100%; background:var(--piano-white); border:1px solid #ddd0b5; position:relative; z-index:1; box-shadow:inset 0 -4px 6px rgba(0,0,0,.1); }
.key.white:active, .key.white.active{ background:color-mix(in srgb, var(--accent) 45%, var(--piano-white)); border-bottom:6px solid var(--accent); animation:key-glow-white .35s ease-out; }
.key.black{ width:30px; height:60%; background:var(--piano-black); margin-left:-15px; margin-right:-15px; z-index:2; border-radius:0 0 4px 4px; box-shadow:inset 0 -4px 4px rgba(255,255,255,.2); }
.key.black:active, .key.black.active{ background:color-mix(in srgb, var(--accent) 55%, var(--piano-black)); border-bottom:4px solid var(--accent); animation:key-glow-black .35s ease-out; }
@keyframes key-glow-white{
  0%{ box-shadow:inset 0 -4px 6px rgba(0,0,0,.1), 0 0 16px 4px rgba(34,211,238,.65); }
  100%{ box-shadow:inset 0 -4px 6px rgba(0,0,0,.1), 0 0 0 0 rgba(34,211,238,0); }
}
@keyframes key-glow-black{
  0%{ box-shadow:inset 0 -4px 4px rgba(255,255,255,.2), 0 0 16px 4px rgba(34,211,238,.65); }
  100%{ box-shadow:inset 0 -4px 4px rgba(255,255,255,.2), 0 0 0 0 rgba(34,211,238,0); }
}
.key span{ position:absolute; bottom:15px; width:100%; text-align:center; font-size:14px; font-weight:700; color:#a9987a; pointer-events:none; }

/* Muziektheorie-naslagwerk (Fase 3.2, sinds v0.15.0) — doorbladerbare
   cheat-sheet, geen flashcard/quizstructuur. Zelfde "los top-level scherm,
   display:none tot getoond via App.loadModule()"-opzet als #piano-module
   hierboven. TheoryUI.render() (theory-ui.js) bouwt #theory-content. */
#theory-view{
  display:none; flex-direction:column; width:100%; height:100%; overflow-y:auto;
  background:var(--bg-dark); transition:background-color .3s;
}
#theory-content{ width:100%; max-width:1100px; margin:0 auto; padding:28px 22px 90px; }
.theory-category{ margin-bottom:36px; }
.theory-category:last-child{ margin-bottom:0; }
.theory-category h2{
  font-family:'Fraunces',serif; font-weight:600; font-size:1.3rem; margin:0 0 16px;
  color:var(--text-main); padding-bottom:8px; border-bottom:1px solid var(--border-color);
}
.theory-grid{ display:grid; grid-template-columns:repeat(auto-fill, minmax(220px, 1fr)); gap:16px; }
.theory-card{
  background:var(--bg-card); border:1px solid var(--border-color); border-radius:var(--radius-md);
  padding:16px; display:flex; flex-direction:column; align-items:center; text-align:center; gap:6px;
  box-shadow:var(--shadow-sm);
}
.theory-card-visual{ width:100%; min-height:70px; display:flex; align-items:center; justify-content:center; }
.theory-card-visual svg{ width:100%; height:auto; max-width:200px; display:block; }
.theory-card h3{ font-size:.95rem; font-weight:700; color:var(--text-main); margin:4px 0 0; }
.theory-card p{ font-size:.8rem; color:var(--text-muted); margin:0; line-height:1.4; }

@media (max-width:768px){
  #workspace{ padding:12px; }
  .flashcard{ min-height:240px; padding:14px; transition:background-color .3s, border-color .3s, color .3s, min-height .3s ease; }
  .piano-keyboard{ height:200px; }
  .key.white{ width:44px; }
  .key.black{ width:28px; margin-left:-14px; margin-right:-14px; }
  #theory-content{ padding:18px 14px 90px; }
  .theory-grid{ grid-template-columns:repeat(auto-fill, minmax(160px, 1fr)); gap:12px; }
}
