/* ============================================================================
   DoReDog — Letter Notes Player (split layout: scrolling score + cinematic stage)
   ========================================================================== */

.player{
  border:1px solid var(--border); border-radius:var(--radius-lg);
  background:linear-gradient(180deg, rgba(18,18,30,.75), rgba(10,10,18,.85));
  backdrop-filter:blur(14px); overflow:hidden; box-shadow:var(--shadow); position:relative;
}

/* ---- transport ---- */
.player-top{ position:relative; z-index:3; }
.progress{ height:3px; background:rgba(255,255,255,.08); position:relative; cursor:pointer; }
.progress-fill{ height:100%; width:0; background:linear-gradient(90deg,var(--gold),var(--violet)); transition:width .08s linear; }
.player-bar{ display:flex; align-items:center; gap:16px; padding:16px 20px; border-bottom:1px solid var(--border); flex-wrap:wrap; }
.play-btn{
  width:58px; height:58px; border-radius:50%; flex:none; display:flex; align-items:center; justify-content:center;
  background:linear-gradient(135deg,var(--gold-2),var(--gold)); color:#100a01;
  box-shadow:0 10px 26px -8px rgba(244,193,93,.55), inset 0 1px 0 rgba(255,255,255,.5);
  transition:transform .25s var(--ease), box-shadow .25s;
}
.play-btn:hover{ transform:scale(1.06); } .play-btn:active{ transform:scale(.96); }
.play-btn svg{ width:24px; height:24px; }
.play-btn.playing{ background:linear-gradient(135deg,var(--violet-2),var(--violet)); color:#0a0616; }
.transport-title{ display:flex; flex-direction:column; min-width:0; }
.transport-title b{ font-family:var(--font-display); font-weight:500; font-size:1.05rem; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.transport-title span{ font-size:.78rem; color:var(--text-mute); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.transport-controls{ display:flex; align-items:center; gap:18px; margin-left:auto; flex-wrap:wrap; }
.ctrl{ display:flex; align-items:center; gap:.6rem; }
.ctrl label{ font-family:var(--font-mono); font-size:.66rem; letter-spacing:.14em; text-transform:uppercase; color:var(--text-mute); }
.ctrl output{ font-family:var(--font-mono); font-size:.8rem; color:var(--gold); min-width:3.4em; }
.voice-sel{ font-family:var(--font-mono); font-size:.74rem; color:var(--text); background:var(--surface-2, #14141f); border:1px solid var(--border, #2a2a3a); border-radius:8px; padding:.34em 1.7em .34em .6em; cursor:pointer; -webkit-appearance:none; appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238a8aa0' stroke-width='2.5'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat:no-repeat; background-position:right .5em center; }
.voice-sel:hover{ border-color:var(--violet, #8b6bff); }
.voice-sel:focus{ outline:none; border-color:var(--violet, #8b6bff); }
.voice-sel option{ background:#0f0f1c; color:var(--text); }
/* practice tools */
.practice-bar{ display:flex; align-items:center; gap:22px; flex-wrap:wrap; margin-top:14px; padding-top:14px; border-top:1px solid var(--border, #23232f); }
.pr-group{ display:flex; align-items:center; gap:7px; }
.pr-label{ font-family:var(--font-mono); font-size:.64rem; letter-spacing:.14em; text-transform:uppercase; color:var(--text-mute); margin-right:2px; }
.pr-btn{ font-family:var(--font-mono); font-size:.72rem; color:var(--text-dim); background:var(--surface, #14141f); border:1px solid var(--border, #2a2a3a); border-radius:7px; padding:.32em .66em; cursor:pointer; transition:border-color .15s, background .15s, color .15s; }
.pr-btn:hover{ border-color:var(--border-2, #3a3a4a); color:var(--text); }
.pr-btn.active{ color:#fff; background:var(--violet, #8b6bff); border-color:var(--violet, #8b6bff); }
.pr-btn.set{ color:var(--gold, #f6b73f); border-color:var(--gold, #f6b73f); }
.pr-btn.ab-off{ color:var(--text-mute); }
.tr-out{ font-family:var(--font-mono); font-size:.82rem; color:var(--gold, #f6b73f); min-width:2.1em; text-align:center; }
.meas-out{ font-family:var(--font-mono); font-size:.74rem; color:var(--gold, #f6b73f); min-width:3.6em; text-align:center; }
.progress{ position:relative; }
.ab-mark{ position:absolute; top:-2px; width:2px; height:calc(100% + 4px); pointer-events:none; z-index:2; }
.ab-mark.ab-a{ background:var(--o3, #35e08c); } .ab-mark.ab-b{ background:var(--o4, #ff5f64); }
input[type=range].slider{ -webkit-appearance:none; appearance:none; width:118px; height:4px; border-radius:4px;
  background:linear-gradient(90deg,var(--gold) 0 var(--fill,50%), rgba(255,255,255,.14) var(--fill,50%)); }
input[type=range].slider::-webkit-slider-thumb{ -webkit-appearance:none; width:16px; height:16px; border-radius:50%; background:#fff; box-shadow:0 2px 8px rgba(0,0,0,.5); cursor:pointer; border:3px solid var(--gold); }
input[type=range].slider::-moz-range-thumb{ width:14px; height:14px; border-radius:50%; background:#fff; border:3px solid var(--gold); cursor:pointer; }
.icon-btn{ width:40px; height:40px; border-radius:12px; border:1px solid var(--border); display:flex; align-items:center; justify-content:center; color:var(--text-dim); transition:.25s; }
.icon-btn:hover{ color:var(--text); border-color:var(--border-2); background:var(--surface-2); }
.icon-btn.active{ color:var(--gold); border-color:rgba(244,193,93,.4); }
.icon-btn svg{ width:18px; height:18px; }

/* ---- split body: narrow score (lines are short) + wide keyboard stage ---- */
/* stacked full-width: the score gets the whole width (long lines fit), the keyboard
   stays full-width and big below it. A fixed-height score scrolls internally so the
   keyboard never leaves view. */
.player-body{ display:flex; flex-direction:column; }

/* ---- top: full-width scrolling score ---- */
.notation-pane{
  position:relative; overflow:auto; min-height:160px; max-height:clamp(180px, 30vh, 340px);
  border-bottom:1px solid var(--border);
  scrollbar-width:none;                 /* hide the scrollbar — it sat next to the keyboard and cluttered the stage; the pane still wheel-scrolls and auto-follows playback */
}
.notation-pane::-webkit-scrollbar{ width:0; height:0; display:none; }
/* centred as a whole (same axis as the keyboard); blocks keep a shared left edge */
.notation{ padding:22px 22px 40px; font-family:var(--font-mono); font-size:15px; line-height:1.55; width:max-content; margin-inline:auto; }
/* `contain:layout style` isolates each block's layout/style recalc so scrolling or highlighting one block
   never re-flows the whole (huge) notation. Not content-visibility — that estimates off-screen block heights,
   which broke the playhead auto-scroll (offsetTop drifted). Blocks stay laid out, so offsetTop stays exact. */
.nota-block{ margin-bottom:20px; position:relative; contain:layout style; }
.nota-block:last-child{ margin-bottom:0; }
.nota-num{ font-size:.68rem; color:var(--text-mute); letter-spacing:.1em; margin-bottom:3px; user-select:none; }
.nota-line{ white-space:pre; }
.nota-oct{ color:var(--text-mute); opacity:.7; user-select:none; }
.nota-body{ color:rgba(255,255,255,.16); }               /* dash colour */
.nn{ display:inline-block; width:1ch; text-align:center; font-weight:600; cursor:pointer;
  transition:transform .12s var(--ease), text-shadow .12s; }
.o2{ color:var(--o2); } .o3{ color:var(--o3); } .o4{ color:var(--o4); } .o5{ color:var(--o5); } .o6{ color:var(--o6); }
.nn.hit{ transform:translateY(-2px) scale(1.4); text-shadow:0 0 16px currentColor; }
/* RH / LH */
.nota-hand{ font-family:var(--font-mono); font-size:.6rem; font-weight:700; letter-spacing:.06em; padding:1px 5px; border-radius:5px; margin-right:7px; user-select:none; }
.nota-hand.rh{ color:var(--gold); background:rgba(244,193,93,.12); border:1px solid rgba(244,193,93,.32); }
.nota-hand.lh{ color:var(--cyan); background:rgba(77,208,255,.12); border:1px solid rgba(77,208,255,.32); }
.nota-line.lh-line{ margin-top:5px; }
.nota-line.rh-line + .nota-line.lh-line{ margin-top:9px; }
/* playhead (moved via transform) */
.playhead{ position:absolute; top:16px; bottom:2px; left:0; width:2px; z-index:4; pointer-events:none;
  background:linear-gradient(180deg, transparent, var(--gold), transparent);
  box-shadow:0 0 16px 2px rgba(244,193,93,.7); opacity:0; transition:transform .09s linear, opacity .2s; }
.playhead.on{ opacity:1; }

/* ---- bottom: full-width cinematic keyboard stage ---- */
.stage{
  position:relative; overflow:hidden; min-height:clamp(250px, 34vh, 380px);
  display:flex; flex-direction:column; gap:8px; padding:14px 16px 18px;
  background:
    radial-gradient(90% 55% at 50% 8%, rgba(139,107,255,.14), transparent 62%),
    radial-gradient(70% 50% at 84% 42%, rgba(77,208,255,.08), transparent 60%),
    radial-gradient(60% 50% at 14% 74%, rgba(255,84,178,.07), transparent 60%),
    linear-gradient(180deg, rgba(10,10,18,.35), rgba(6,6,12,.6));
}
.viz{ position:absolute; inset:0; z-index:0; pointer-events:none; }
.falling{ position:absolute; inset:0; z-index:1; pointer-events:none; opacity:0; transition:opacity .25s; }
.player.learn .falling{ opacity:1; }
.icon-btn.learn-btn.active{ color:var(--gold); border-color:rgba(244,193,93,.4); }
.stage-shine{ position:absolute; left:50%; top:-6%; width:130%; height:58%; transform:translateX(-50%); z-index:0; pointer-events:none;
  background:radial-gradient(closest-side, rgba(139,107,255,.18), transparent 70%); filter:blur(8px); animation:stagePulse 6s ease-in-out infinite alternate; }
@keyframes stagePulse{ 0%{ opacity:.45; transform:translateX(-50%) scale(1); } 100%{ opacity:.85; transform:translateX(-50%) scale(1.05); } }
.stage-head{ position:relative; z-index:1; display:flex; justify-content:center; align-items:center; padding-top:2px; }
.stage-caption{ font-family:var(--font-mono); font-size:.6rem; letter-spacing:.28em; text-transform:uppercase; color:var(--text-mute); }
/* particles rise in this space above the keyboard */
.stage-spacer{ flex:1 1 auto; min-height:20px; }

/* ---- piano ---- */
/* overflow-y:hidden is the key fix — overflow-x:auto (needed to slide a wide keyboard sideways) implicitly
   makes overflow-y `auto` too, and the sub-keyboard glow spills a few px below the box, so a stray VERTICAL
   scrollbar appeared right next to the keyboard. Pin overflow-y and hide the (horizontal) scrollbar chrome. */
.piano-scroll{ position:relative; z-index:1; width:100%; overflow-x:auto; overflow-y:hidden; padding:26px 2px 6px; scrollbar-width:none; }
.piano-scroll::before{ content:""; position:absolute; left:50%; bottom:-4%; width:88%; height:74%; transform:translateX(-50%);
  background:radial-gradient(closest-side, rgba(139,107,255,.20), transparent 72%); filter:blur(16px); z-index:-1; pointer-events:none; }
.piano-scroll::-webkit-scrollbar{ display:none; }
.piano{ display:flex; justify-content:center; position:relative; height:150px; width:100%; user-select:none;
  transform:perspective(1600px) rotateX(7deg); transform-origin:center 94%; transition:transform .5s var(--ez); }
.octave-group{ flex:none; }   /* keep the fitted key widths; centred by the piano */
.piano:hover{ transform:perspective(1600px) rotateX(4deg); }   /* leans up slightly when you reach for it */
.octave-group{ display:flex; position:relative; }
.octave-label{ position:absolute; top:-15px; left:0; right:0; text-align:center; font-family:var(--font-mono); font-size:.6rem; letter-spacing:.14em; text-transform:uppercase; font-weight:600; }
.key{ position:relative; }
.key.white{ width:40px; height:150px; background:linear-gradient(180deg,#f3f1f7,#d9d6e2); border:1px solid rgba(0,0,0,.35);
  border-radius:0 0 6px 6px; box-shadow:inset 0 -8px 12px -6px rgba(0,0,0,.2); display:flex; align-items:flex-end; justify-content:center;
  padding-bottom:8px; font-size:.72rem; font-weight:600; color:#3a3746; transition:background .08s, transform .08s, box-shadow .18s; }
.key.black{ position:absolute; top:0; width:26px; height:94px; z-index:2; background:linear-gradient(180deg,#2a2833,#0b0a10);
  border-radius:0 0 5px 5px; border:1px solid #000; box-shadow:0 5px 8px rgba(0,0,0,.5), inset 0 -6px 8px -4px rgba(255,255,255,.12);
  display:flex; align-items:flex-end; justify-content:center; padding-bottom:6px; font-size:.6rem; font-weight:700; color:#c9c6d6; transition:background .08s, transform .08s, box-shadow .18s; }
.key.white:active,.key.white.down{ background:linear-gradient(180deg,#e4e0ee,#c3bfd2); transform:translateY(1px); }
.key.black:active,.key.black.down{ background:linear-gradient(180deg,#3a3846,#111018); }
/* pressed keys light up in their octave colour — a clear key↔sound mark, not just a glow */
.key.lit-o2{ --lit:255,84,178; } .key.lit-o3{ --lit:53,224,140; } .key.lit-o4{ --lit:255,95,100; }
.key.lit-o5{ --lit:246,183,63; } .key.lit-o6{ --lit:79,163,255; }
.key.white.lit{ transform:translateY(3px);
  background:linear-gradient(180deg, rgba(var(--lit),.45), rgba(var(--lit),.95)) !important;
  box-shadow:0 0 34px 7px rgba(var(--lit),.9), 0 4px 12px 2px rgba(var(--lit),.6), inset 0 0 22px rgba(var(--lit),.5) !important;
  border-color:rgba(var(--lit),.95) !important; }
.key.black.lit{ transform:translateY(2px);
  background:linear-gradient(180deg, rgba(var(--lit),.75), rgba(var(--lit),1)) !important;
  box-shadow:0 0 34px 7px rgba(var(--lit),.95), inset 0 0 14px rgba(255,255,255,.45) !important; }
.key.white.lit span, .key.black.lit span{ color:#fff !important; text-shadow:0 0 6px rgba(0,0,0,.4); }
.piano.compact .key span{ display:none; }              /* too narrow for labels */

/* legend */
.oct-legend{ position:relative; z-index:1; display:flex; gap:8px 12px; flex-wrap:wrap; align-items:center; justify-content:center; }
.oct-legend .li{ display:flex; align-items:center; gap:.4rem; font-family:var(--font-mono); font-size:.68rem; color:var(--text-dim); }
.oct-legend .dot{ width:10px; height:10px; border-radius:50%; box-shadow:0 0 8px currentColor; }

/* editor / sandbox */
.nota-editor{ width:100%; min-height:200px; font-family:var(--font-mono); font-size:14px; line-height:1.5; padding:18px;
  border-radius:var(--radius); background:#0c0c16; border:1px solid var(--border); color:var(--text); resize:vertical; }
.nota-editor:focus{ outline:none; border-color:var(--violet); }

/* ---- responsive: stack, stage on top so the keyboard stays in view ---- */
@media (max-width:900px){
  .notation-pane{ max-height:32vh; min-height:170px; }
  .stage{ min-height:290px; }
}
@media (max-width:560px){
  .key.white{ width:34px; } .key.black{ width:22px; }
  .notation{ font-size:13px; }
  .transport-controls{ width:100%; margin-left:0; justify-content:space-between; gap:12px; }
}
/* ---- mobile performance: stop continuous blur re-raster + backdrop repaint (see main.css) ---- */
@media (pointer:coarse), (max-width:820px){
  .player{ backdrop-filter:none; -webkit-backdrop-filter:none; background:rgba(12,12,22,.96); }
  .stage-shine{ animation:none; }                 /* was: blur(8px) + infinite scale animation behind the canvas */
  .piano-scroll::before{ display:none; }          /* drop the blurred key-glow on the scrolling keyboard */
  .player.cinema .player-top{ backdrop-filter:none; -webkit-backdrop-filter:none; }
  .player.present .present-exit{ backdrop-filter:none; -webkit-backdrop-filter:none; }
  /* Fullscreen + cinema/present modes are removed on mobile — the phone Fullscreen API is unreliable and
     the modes don't add much on a small screen. Hide both entry buttons (desktop keeps them). */
  .player .fs-btn, .player .present-btn{ display:none !important; }
}

/* ---- fullscreen: score + keyboard both fill the screen (Fullscreen API + class fallback) ---- */
.player:fullscreen, .player:-webkit-full-screen, .player.fs-fallback{
  width:100vw; height:100vh; height:100dvh; max-width:none; border-radius:0; display:flex; flex-direction:column; }
/* 100dvh = the *visible* viewport on mobile (excludes the Safari address bar), so the keyboard isn't pushed
   off-screen the way plain 100vh does on iOS. */
.player:fullscreen .player-top, .player:-webkit-full-screen .player-top, .player.fs-fallback .player-top{ flex:0 0 auto; }
.player:fullscreen .player-body, .player:-webkit-full-screen .player-body, .player.fs-fallback .player-body{ flex:1 1 auto; min-height:0; }
.player:fullscreen .notation-pane, .player:-webkit-full-screen .notation-pane, .player.fs-fallback .notation-pane{ max-height:none; flex:1 1 46%; min-height:0; }
.player:fullscreen .stage, .player:-webkit-full-screen .stage, .player.fs-fallback .stage{ flex:1 1 54%; min-height:0; }
.player:fullscreen .notation, .player:-webkit-full-screen .notation, .player.fs-fallback .notation{ font-size:17px; }
.player.fs-fallback{ position:fixed; inset:0; z-index:300; padding-top:env(safe-area-inset-top, 0px); box-sizing:border-box; }
/* while the mobile CSS-overlay fullscreen is open: hide the site chrome (the fixed header would otherwise
   peek over the trapped overlay) and lock the page so it can't scroll behind the player. */
html.drd-fs{ overflow:hidden; }
html.drd-fs #site-header, html.drd-fs #site-footer{ display:none !important; }
.icon-btn.fs-btn.active{ color:var(--gold); border-color:rgba(244,193,93,.4); }

/* ---- cinema mode: cinematic treatment layered onto fullscreen ---- */
.player.cinema{ background:radial-gradient(130% 100% at 50% -10%, #16122a 0%, #08060f 55%, #040308 100%) !important; }
.player.cinema .player-top{ background:rgba(6,6,12,.55); backdrop-filter:blur(6px); }
.player.cinema .stage{ background:transparent; }
.player.cinema .viz{ opacity:1; filter:saturate(1.15) brightness(1.08); }
.player.cinema .stage-shine{ opacity:.9; }
.player.cinema .stage-caption{ font-size:.82rem; letter-spacing:.22em; color:var(--gold); text-shadow:0 0 22px rgba(244,193,93,.35); }
.player.cinema .notation-pane{ background:rgba(8,8,16,.4); }
/* vignette so the visualiser reads as the focal point */
.player.cinema::after{ content:""; position:absolute; inset:0; pointer-events:none; z-index:4;
  box-shadow:inset 0 0 240px 70px rgba(0,0,0,.72); }

/* ---- presentation / record mode: only notation, keyboard and animations remain ---- */
.player.present .player-top,
.player.present .stage-hint{ display:none !important; }
.present-exit{ display:none; }
.player.present .present-exit{ display:inline-flex; align-items:center; gap:6px; position:absolute; top:calc(16px + env(safe-area-inset-top, 0px)); right:18px; z-index:30;
  font-family:var(--font-mono); font-size:.74rem; letter-spacing:.04em; color:#fff; background:rgba(18,18,28,.55);
  border:1px solid rgba(255,255,255,.28); border-radius:40px; padding:8px 15px; cursor:pointer; -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px); transition:background .15s; }
.player.present .present-exit:hover{ background:rgba(44,44,60,.85); }
.present-count[hidden]{ display:none; }
.present-count{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center; pointer-events:none; z-index:25;
  font-family:var(--font-display, Georgia, serif); font-weight:800; font-size:26vh; line-height:1; color:rgba(255,255,255,.92);
  text-shadow:0 0 70px rgba(0,0,0,.7); animation:presentPulse 1s ease-in-out infinite; }
@keyframes presentPulse{ 0%,100%{ transform:scale(1); opacity:.92; } 50%{ transform:scale(1.14); opacity:.6; } }

/* first-run affordance: pulse the play button + a hint on the (otherwise empty) stage */
.player:not(.played) .play-btn{ animation:playPulse 2.1s ease-in-out infinite; }
@keyframes playPulse{
  0%,100%{ box-shadow:0 10px 26px -8px rgba(244,193,93,.55), inset 0 1px 0 rgba(255,255,255,.5), 0 0 0 0 rgba(244,193,93,.55); }
  50%{ box-shadow:0 10px 30px -8px rgba(244,193,93,.7), inset 0 1px 0 rgba(255,255,255,.5), 0 0 0 15px rgba(244,193,93,0); } }
.stage-hint{ position:absolute; left:0; right:0; top:28%; z-index:2; text-align:center; pointer-events:none; padding:0 24px;
  font-family:var(--font-display); font-size:clamp(1rem,1.5vw,1.3rem); color:var(--text-dim);
  transition:opacity .5s var(--ez); animation:hintFloat 3s ease-in-out infinite; }
.stage-hint b{ color:var(--gold); font-weight:600; font-style:normal; }
.player.played .stage-hint{ opacity:0; animation:none; visibility:hidden; }   /* stop the pulse so opacity:0 actually applies */
@keyframes hintFloat{ 0%,100%{ opacity:.6; transform:translateY(0); } 50%{ opacity:1; transform:translateY(-4px); } }
@media (prefers-reduced-motion:reduce){ .player:not(.played) .play-btn{ animation:none; } .stage-hint{ animation:none; } }
