/* ==================================================================
   Pianify — stylesheet
   Layered dark UI: deep space backdrop, glass panels, neon note glow.
   ================================================================== */

:root {
  --bg-0: #04060f;
  --bg-1: #070c1a;
  --bg-2: #0b1226;
  --panel: rgba(16, 25, 48, 0.72);
  --panel-2: rgba(22, 33, 62, 0.78);
  --line: rgba(140, 190, 255, 0.14);
  --line-strong: rgba(150, 200, 255, 0.30);

  --ink: #eaf2ff;
  --ink-dim: #9fb3d4;
  --ink-faint: #6b809f;

  --accent: #4da6ff;
  --accent-2: #9a7cff;
  --accent-3: #45e6c8;
  --hot: #ff7a9c;
  --gold: #ffd166;

  --right-hand: #55b6ff;
  /* One violet for the left hand everywhere — falling note, key, key
     sheet, legend. The canvas draws hsl(275,92%,68%); this is that hue. */
  --left-hand: #ce8aff;

  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 22px;

  --shadow-1: 0 4px 18px rgba(0, 0, 0, 0.45);
  --shadow-2: 0 18px 48px rgba(0, 0, 0, 0.6);
  --glow: 0 0 24px rgba(77, 166, 255, 0.35);

  --ease: cubic-bezier(0.22, 0.85, 0.24, 1);
  --font-display: "Exo 2", "Segoe UI", system-ui, sans-serif;
  --font-body: "Inter", "Segoe UI", system-ui, sans-serif;
}

* { box-sizing: border-box; }

/* Author `display` declarations outrank the UA stylesheet's
 * `[hidden] { display: none }` regardless of specificity, so a hidden
 * .modal / .overlay would still lay out as a full-screen grid and swallow
 * every click on the page. Restate it with enough weight to win. */
[hidden] { display: none !important; }

html, body {
  height: 100%;
  margin: 0;
  background: var(--bg-0);
  color: var(--ink);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}

body { overscroll-behavior: none; }

button, input, select { font: inherit; color: inherit; }
button { cursor: pointer; border: 0; background: none; }
h1, h2, h3, h4 { font-family: var(--font-display); margin: 0; letter-spacing: 0.01em; }

::selection { background: rgba(77, 166, 255, 0.35); }

.app { position: fixed; inset: 0; }

.ambient {
  position: absolute; inset: 0; pointer-events: none;
  width: 100%; height: 100%;
  background:
    radial-gradient(120% 90% at 50% -10%, #0e1a38 0%, transparent 62%),
    linear-gradient(180deg, #05080f 0%, #070d1e 46%, #0a1226 100%);
  z-index: 0;
}

/* ---------- scrollbars ---------- */
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: rgba(255, 255, 255, 0.03); }
*::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, rgba(90, 150, 230, 0.5), rgba(120, 100, 230, 0.5));
  border-radius: 20px; border: 2px solid transparent; background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover { background: rgba(120, 180, 255, 0.7); background-clip: padding-box; }

/* ==================================================================
   SCREENS
   ================================================================== */

.screen {
  position: absolute; inset: 0;
  z-index: 1;
  opacity: 0; visibility: hidden;
  /* Also inert during the fade-out, so the outgoing screen cannot eat a
     click aimed at the one arriving underneath it. */
  pointer-events: none;
  transform: scale(0.985) translateY(6px);
  /* visibility flips instantly on the way in and only waits for the fade
     on the way out. Never make becoming visible depend on a transition
     finishing — a throttled background tab never finishes one. */
  transition: opacity 0.34s var(--ease), transform 0.42s var(--ease), visibility 0s linear 0.34s;
  display: flex; flex-direction: column;
}
.screen.active {
  opacity: 1; visibility: visible; transform: none; pointer-events: auto;
  transition: opacity 0.34s var(--ease), transform 0.42s var(--ease), visibility 0s linear 0s;
}

/* ==================================================================
   MAIN MENU
   ================================================================== */

.screen-menu { align-items: center; justify-content: center; }

.menu-glow {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(60% 50% at 50% 42%, rgba(77, 166, 255, 0.16), transparent 70%),
    radial-gradient(45% 40% at 22% 78%, rgba(154, 124, 255, 0.14), transparent 70%);
  animation: breathe 9s ease-in-out infinite;
}
@keyframes breathe { 0%, 100% { opacity: 0.75; } 50% { opacity: 1; } }

.menu-inner {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; align-items: center;
  gap: 8px; padding: 24px; width: min(760px, 92vw);
  animation: riseIn 0.7s var(--ease) both;
}
@keyframes riseIn { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: none; } }

.brandmark { width: 132px; height: 132px; filter: drop-shadow(0 0 26px rgba(90, 170, 255, 0.5)); }
.brand-svg { width: 100%; height: 100%; }
.brand-svg .brand-keys { animation: keyBob 4.5s ease-in-out infinite; transform-origin: 60px 60px; }
@keyframes keyBob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(2px); } }
.brand-svg .brand-notes rect { animation: noteDrop 2.6s ease-in-out infinite; }
.brand-svg .brand-notes rect:nth-child(2) { animation-delay: 0.5s; }
.brand-svg .brand-notes rect:nth-child(3) { animation-delay: 1s; }
@keyframes noteDrop {
  0% { opacity: 0; transform: translateY(-14px); }
  25% { opacity: 1; }
  70% { opacity: 1; transform: translateY(12px); }
  100% { opacity: 0; transform: translateY(18px); }
}

.brand-title {
  font-size: clamp(44px, 8vw, 78px);
  font-weight: 800; letter-spacing: 0.14em;
  line-height: 1; margin-top: 4px;
  background: linear-gradient(100deg, #ffffff 0%, #a9d4ff 42%, #b9a6ff 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  text-shadow: 0 0 60px rgba(110, 180, 255, 0.35);
}
.brand-title span { font-weight: 400; opacity: 0.85; }

.tagline { color: var(--ink-dim); font-size: 15px; margin: 2px 0 26px; text-align: center; max-width: 44ch; }

.menu-nav { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; width: 100%; }
.menu-btn {
  position: relative; overflow: hidden;
  display: flex; align-items: center; gap: 14px;
  padding: 18px 22px; border-radius: var(--r-md);
  background: var(--panel); border: 1px solid var(--line);
  backdrop-filter: blur(14px);
  transition: transform 0.22s var(--ease), border-color 0.22s, background 0.22s, box-shadow 0.22s;
  text-align: left;
}
.menu-btn::before {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, 0.10) 50%, transparent 70%);
  transform: translateX(-120%); transition: transform 0.7s var(--ease);
}
.menu-btn:hover::before { transform: translateX(120%); }
.menu-btn:hover { transform: translateY(-3px); border-color: var(--line-strong); box-shadow: var(--shadow-2), var(--glow); }
.menu-btn.primary {
  grid-column: 1 / -1;
  background: linear-gradient(100deg, rgba(45, 110, 210, 0.42), rgba(120, 90, 230, 0.32));
  border-color: rgba(120, 190, 255, 0.35);
}
/* ---------- drawn icons ---------- */
.ic { width: 1.15em; height: 1.15em; display: block; flex: none; }
[data-icon] { display: inline-flex; align-items: center; justify-content: center; }
.dp-warn .ic, .dp-tip .ic, .kro-tip .ic, .ht-credit .ic, .dp-remove .ic {
  width: 15px; height: 15px; display: inline-block; vertical-align: -3px; margin-right: 5px;
}
.dp-tip .ic { color: var(--accent); }
.dp-warn .ic { color: #ffcf9a; }

.mb-icon {
  width: 42px; height: 42px; flex: none; display: grid; place-items: center;
  border-radius: 11px; color: var(--accent);
  background: rgba(120, 180, 255, 0.14); border: 1px solid var(--line);
  transition: 0.22s var(--ease);
}
.mb-icon .ic { width: 20px; height: 20px; }
.menu-btn:hover .mb-icon { background: rgba(120, 180, 255, 0.24); color: #dceeff; }
.menu-btn.primary .mb-icon { color: #eaf4ff; background: rgba(255, 255, 255, 0.14); }
.mb-text { font-family: var(--font-display); font-weight: 700; font-size: 18px; letter-spacing: 0.03em; }
.mb-sub { margin-left: auto; color: var(--ink-faint); font-size: 13px; }

.menu-foot { display: flex; gap: 14px; margin-top: 24px; flex-wrap: wrap; justify-content: center; }

.mini-field { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--ink-faint); }
.mini-field span { text-transform: uppercase; letter-spacing: 0.10em; font-weight: 600; }
/* password and email were missing here, so they rendered as unstyled
   native inputs — white boxes with a blue focus ring, because the
   `input:focus` rule below is not type-specific. */
select, input[type="search"], input[type="text"],
input[type="password"], input[type="email"], input[type="number"] {
  background: rgba(10, 18, 36, 0.85); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 8px 10px; outline: none; font-size: 13px;
  transition: border-color 0.2s, box-shadow 0.2s;
}
select:focus, input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(77, 166, 255, 0.18); }
select option { background: #0b1226; }

/* ==================================================================
   SONG SELECT
   ================================================================== */

.screen-select { padding: 0; }

.select-hero {
  position: absolute; inset: 0; pointer-events: none;
  opacity: 0.28; filter: blur(46px) saturate(1.3);
  transition: background 0.6s var(--ease);
  z-index: 0;
}
.screen-select::after {
  content: ''; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(180deg, rgba(4, 7, 16, 0.82), rgba(4, 7, 16, 0.94));
  pointer-events: none;
}

.select-top {
  position: relative; z-index: 2;
  display: flex; align-items: center; gap: 14px;
  padding: 16px 22px 10px;
}
.select-title {
  font-size: 19px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-dim); white-space: nowrap;
}
.icon-btn {
  width: 38px; height: 38px; flex: none; display: grid; place-items: center;
  border-radius: 10px; font-size: 17px; color: var(--ink-dim);
  background: rgba(255, 255, 255, 0.05); border: 1px solid var(--line);
  transition: 0.2s var(--ease);
}
.icon-btn .ic { width: 19px; height: 19px; }
.icon-btn:hover { background: rgba(120, 180, 255, 0.16); color: #fff; transform: translateY(-1px); }
.icon-btn.on { background: linear-gradient(100deg, #64d6b4, #7cc4ff); color: #061321; border-color: transparent; }

.search-box { position: relative; flex: 1; max-width: 460px; margin-left: auto; }
.search-box input {
  width: 100%; padding: 10px 36px 10px 38px; border-radius: 999px;
  background: rgba(9, 16, 34, 0.9);
}
.search-box input::-webkit-search-cancel-button { display: none; }
.search-icon { position: absolute; left: 13px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--ink-faint); }
.clear-btn {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  width: 22px; height: 22px; border-radius: 50%; font-size: 15px; line-height: 1;
  color: var(--ink-faint); opacity: 0; pointer-events: none; transition: 0.2s;
}
.clear-btn.on { opacity: 1; pointer-events: auto; }
.clear-btn:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }
.sort-field { flex: none; }

.import-btn { flex: none; display: flex; align-items: center; gap: 7px; white-space: nowrap; }
.imp-icon {
  width: 18px; height: 18px; border-radius: 5px; display: grid; place-items: center;
  background: rgba(120, 180, 255, 0.18); color: var(--accent);
}
.imp-icon .ic { width: 13px; height: 13px; }
.dp-remove { width: 100%; margin-bottom: 8px; color: var(--hot); }
.dp-remove:hover { background: rgba(255, 122, 156, 0.12); border-color: rgba(255, 122, 156, 0.4); }

.drop-veil {
  position: fixed; inset: 0; z-index: 95; display: grid; place-items: center;
  background: rgba(4, 8, 18, 0.82); backdrop-filter: blur(10px);
  opacity: 0; transition: opacity 0.18s var(--ease); pointer-events: none;
}
.drop-veil.shown { opacity: 1; }
.drop-card {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 46px 60px; border-radius: var(--r-lg); text-align: center;
  border: 2px dashed rgba(140, 200, 255, 0.55); background: rgba(20, 34, 66, 0.7);
  animation: popIn 0.24s var(--ease);
}
.drop-glyph { color: var(--accent); animation: floaty 3s ease-in-out infinite; }
.drop-glyph .ic { width: 54px; height: 54px; stroke-width: 1.2; }
.drop-card strong { font-family: var(--font-display); font-size: 20px; font-weight: 700; }
.drop-card small { font-size: 12px; color: var(--ink-faint); }

.cat-row {
  position: relative; z-index: 2;
  display: flex; gap: 8px; padding: 4px 22px 12px; flex-wrap: wrap;
}
.chip {
  padding: 6px 14px; border-radius: 999px; font-size: 12.5px; font-weight: 600;
  color: var(--ink-dim); background: rgba(255, 255, 255, 0.045);
  border: 1px solid var(--line); transition: 0.2s var(--ease);
}
.chip:hover { color: #fff; border-color: var(--line-strong); }
.chip.on {
  color: #04121f; background: linear-gradient(100deg, #7cc4ff, #a89bff);
  border-color: transparent; box-shadow: 0 4px 16px rgba(90, 160, 255, 0.35);
}

.select-body {
  position: relative; z-index: 2; flex: 1; min-height: 0;
  display: grid; grid-template-columns: minmax(300px, 380px) 1fr;
  gap: 20px; padding: 0 22px 20px;
}

/* --- detail pane --- */
.detail-pane {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 20px 20px 16px; overflow-y: auto;
  backdrop-filter: blur(18px); box-shadow: var(--shadow-2);
  animation: fadeSlide 0.4s var(--ease) both;
}

/* The primary action must never be the thing you have to scroll to find,
   so it rides along the bottom of the pane instead. */
#dp-play {
  position: sticky; bottom: 0; z-index: 3; margin-top: 6px;
  box-shadow: 0 6px 22px rgba(70, 130, 240, 0.4), 0 -14px 22px 14px var(--panel);
}
@keyframes fadeSlide { from { opacity: 0; transform: translateX(-14px); } to { opacity: 1; transform: none; } }

/* The cover is a miniature of the piece itself — the opening bars drawn
   as a piano roll — so each song's identity comes from its own notes. */
.dp-cover {
  height: 150px; border-radius: var(--r-md); position: relative; overflow: hidden;
  margin-bottom: 14px; box-shadow: var(--shadow-1);
}
.cover-art { width: 100%; height: 100%; display: block; }
.dp-cover .cover-art { animation: coverIn 0.6s var(--ease) both; }
@keyframes coverIn { from { opacity: 0; transform: scale(1.04); } to { opacity: 1; transform: none; } }
.dp-cover-cat {
  position: absolute; left: 11px; top: 11px;
  padding: 4px 10px; border-radius: 999px;
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.13em; text-transform: uppercase;
  background: rgba(4, 8, 18, 0.62); border: 1px solid rgba(255, 255, 255, 0.16);
  color: rgba(240, 248, 255, 0.92); backdrop-filter: blur(6px);
}
@keyframes floaty { 0%, 100% { transform: translateY(0) rotate(-2deg); } 50% { transform: translateY(-7px) rotate(2deg); } }

.dp-title { font-size: 22px; font-weight: 700; line-height: 1.2; }
.dp-artist { color: var(--accent); font-size: 13.5px; font-weight: 600; margin-top: 3px; }

/* The arranger's own grading, which is the one editorial fact about a
   piece worth showing here. Replaced a blurb the manifest never carried
   and a category badge that read IMPORTED on all 1,946 pieces. */
.dp-level {
  display: inline-block; margin: 10px 0 14px;
  padding: 3px 10px; border-radius: 999px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink-dim); background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--line);
}

.dp-facts { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-bottom: 16px; }
.dp-fact {
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 7px 10px;
}
.dp-fact span { display: block; font-size: 10px; text-transform: uppercase; letter-spacing: 0.09em; color: var(--ink-faint); }
.dp-fact b { font-size: 13.5px; font-weight: 600; }

.dp-block { margin-bottom: 15px; }
.dp-label {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.11em;
  color: var(--ink-faint); margin-bottom: 7px; font-weight: 700;
}
.dp-starmeter { font-style: normal; }
.dp-hint { font-size: 11.5px; color: var(--ink-faint); line-height: 1.5; margin: 7px 0 0; }

.seg { display: flex; gap: 6px; background: rgba(0, 0, 0, 0.3); padding: 4px; border-radius: 11px; border: 1px solid var(--line); }
.seg button {
  flex: 1; padding: 8px 6px; border-radius: 8px; font-size: 12.5px; font-weight: 600;
  color: var(--ink-dim); transition: 0.2s var(--ease); line-height: 1.25;
}
.seg button b { display: block; font-weight: 700; }
.seg button i { display: block; font-style: normal; font-size: 10px; opacity: 0.65; margin-top: 1px; }
.seg button:hover { color: #fff; background: rgba(255, 255, 255, 0.06); }
.seg button.on {
  color: #061321; background: linear-gradient(100deg, #7cc4ff, #a89bff);
  box-shadow: 0 3px 14px rgba(90, 160, 255, 0.4);
}

.wait-opt {
  display: flex; align-items: flex-start; gap: 10px; width: 100%; text-align: left;
  padding: 10px 12px; border-radius: 11px;
  background: rgba(0, 0, 0, 0.28); border: 1px solid var(--line);
  transition: 0.2s var(--ease);
}
.wait-opt:hover { border-color: var(--line-strong); background: rgba(255, 255, 255, 0.05); }
.wait-opt.on {
  background: linear-gradient(120deg, rgba(70, 220, 190, 0.16), rgba(90, 170, 255, 0.14));
  border-color: rgba(90, 225, 200, 0.5);
}
.wo-check {
  width: 20px; height: 20px; flex: none; margin-top: 1px; border-radius: 6px;
  display: grid; place-items: center; font-size: 12px; font-weight: 800; color: #04211c;
  background: rgba(255, 255, 255, 0.08); border: 1px solid var(--line);
}
.wait-opt.on .wo-check { background: linear-gradient(140deg, #6fe3c0, #7cc4ff); border-color: transparent; }
.wo-check .ic { width: 12px; height: 12px; }
.wo-text b { display: block; font-size: 13px; font-weight: 600; }
.wo-text i { display: block; font-style: normal; font-size: 11px; color: var(--ink-faint); line-height: 1.5; margin-top: 2px; }

.dp-tip {
  margin-top: 9px; padding: 10px 12px; border-radius: var(--r-sm);
  background: rgba(120, 180, 255, 0.09); border: 1px solid rgba(120, 180, 255, 0.26);
  font-size: 11.5px; line-height: 1.55; color: var(--ink-dim);
}
.dp-tip .btn { margin-top: 8px; width: 100%; }

.dp-warn {
  background: rgba(255, 160, 90, 0.10); border: 1px solid rgba(255, 170, 90, 0.35);
  border-radius: var(--r-sm); padding: 10px 12px; font-size: 12px; color: #ffcf9a;
  line-height: 1.5; margin-bottom: 14px;
}
.linkish { color: var(--accent); text-decoration: underline; font-size: 12px; }

.dp-best {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; border-radius: var(--r-sm);
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--line); margin-bottom: 14px;
}
.dp-best .dp-label { margin: 0; }
.dp-never { color: var(--ink-faint); font-size: 12px; }
.best-rank { font-family: var(--font-display); font-weight: 800; font-size: 19px; }
.best-score { font-weight: 700; }
.best-acc { color: var(--ink-dim); font-size: 12.5px; margin-left: auto; }

/* --- list pane --- */
.list-pane { min-height: 0; display: flex; flex-direction: column; }
.list-count { font-size: 11px; color: var(--ink-faint); letter-spacing: 0.09em; text-transform: uppercase; padding: 0 0 8px 6px; font-weight: 600; }
.song-list { overflow-y: auto; padding: 4px 10px 10px 4px; display: flex; flex-direction: column; gap: 7px; }
.empty-note { color: var(--ink-faint); text-align: center; padding: 40px; font-size: 14px; }

.song-panel {
  display: flex; align-items: center; gap: 14px; width: 100%;
  padding: 9px 18px 9px 9px; text-align: left;
  border-radius: 12px 26px 26px 12px;
  background: linear-gradient(100deg, rgba(20, 30, 56, 0.85), rgba(14, 22, 44, 0.7));
  border: 1px solid var(--line);
  transform: skewX(-7deg);
  transition: transform 0.26s var(--ease), box-shadow 0.26s, border-color 0.26s, background 0.26s;
  animation: panelIn 0.45s var(--ease) both;
  will-change: transform;
}
@keyframes panelIn { from { opacity: 0; transform: skewX(-7deg) translateX(38px); } to { opacity: 1; transform: skewX(-7deg); } }
.song-panel > * { transform: skewX(7deg); }
.song-panel:hover { transform: skewX(-7deg) translateX(-10px); border-color: var(--line-strong); }
.song-panel.selected {
  transform: skewX(-7deg) translateX(-22px) scale(1.015);
  border-color: rgba(140, 200, 255, 0.55);
  background: linear-gradient(100deg, rgba(38, 66, 122, 0.9), rgba(50, 40, 100, 0.75));
  box-shadow: var(--shadow-2), 0 0 30px rgba(80, 150, 255, 0.28);
}

.sp-cover {
  width: 54px; height: 54px; flex: none; border-radius: 11px; overflow: hidden;
  display: block; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07), 0 3px 10px rgba(0, 0, 0, 0.45);
}
.sp-text { flex: 1; min-width: 0; display: block; }
.sp-title { display: block; font-family: var(--font-display); font-weight: 600; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sp-artist { display: block; font-size: 11.5px; color: var(--ink-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sp-meta { flex: none; text-align: right; display: block; }
.sp-time { display: block; font-size: 10.5px; color: var(--ink-faint); margin-top: 3px; letter-spacing: 0.03em; }

/* The grade a piece carries. One scale, running cool to warm, so a glance
   down a long list reads as a gradient rather than a set of labels to
   decode. Ungraded pieces get no badge at all — an empty space says "not
   rated" more honestly than a grey chip claiming to be a rating. */
.sp-level {
  display: inline-block; margin-bottom: 4px;
  padding: 2px 8px; border-radius: 999px;
  font-size: 9.5px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase;
  border: 1px solid currentColor;
}
.lv-beginner { color: #6fe3c4; }
.lv-easy { color: #62c8ff; }
.lv-medium { color: #9d9bff; }
.lv-intermediate { color: #c88cff; }
.lv-hard { color: #ff8fbe; }
.lv-advanced { color: #ff9a76; }
.lv-medley { color: #f0c96a; }

/* The same grade in the detail pane, where it replaced a row of buttons.
   It is deliberately not a control: nothing here is yours to choose. */
.dp-level {
  display: flex; flex-direction: column; gap: 3px;
  padding: 11px 13px; border-radius: 11px;
  background: rgba(0, 0, 0, 0.28); border: 1px solid var(--line);
}
.dp-level b {
  font-family: var(--font-display); font-size: 17px; font-weight: 700; line-height: 1.15;
  color: currentColor;
}
.dp-level i { font-style: normal; font-size: 11.5px; color: var(--ink-faint); line-height: 1.45; }
.dp-level.lv-none { color: var(--ink-dim); }

/* Selecting a panel is not the same as starting it, so say so. */
.sp-go {
  flex: none; display: flex; align-items: center; gap: 8px;
  max-width: 0; opacity: 0; overflow: hidden; white-space: nowrap;
  transition: max-width 0.3s var(--ease), opacity 0.25s var(--ease), margin 0.3s var(--ease);
}
.song-panel.selected .sp-go { max-width: 190px; opacity: 1; margin-left: 6px; }
.sp-go b {
  width: 30px; height: 30px; flex: none; border-radius: 50%;
  display: grid; place-items: center; color: #041220;
  background: linear-gradient(140deg, #8ed0ff, #a89bff);
  box-shadow: 0 0 16px rgba(120, 190, 255, 0.6);
}
.sp-go b .ic { width: 13px; height: 13px; margin-left: 1px; }
.sp-go i { font-style: normal; font-size: 10px; color: var(--ink-dim); line-height: 1.25; white-space: normal; max-width: 92px; }

.stars { display: inline-flex; align-items: center; gap: 2px; }
.stars i {
  width: 7px; height: 7px; border-radius: 2px; display: block;
  background: rgba(255, 255, 255, 0.12); transform: rotate(45deg);
}
.stars i.on { background: linear-gradient(135deg, #ffd166, #ff9f5a); box-shadow: 0 0 7px rgba(255, 190, 90, 0.6); }
.stars i.half { background: linear-gradient(135deg, #ffd166 50%, rgba(255, 255, 255, 0.12) 50%); }
.stars b { margin-left: 6px; font-size: 11px; color: var(--gold); font-weight: 700; }

/* ==================================================================
   PLAY SCREEN
   ================================================================== */

.screen-play { background: linear-gradient(180deg, #030610, #050a18); }

.hud {
  display: flex; align-items: center; gap: 16px;
  padding: 10px 18px; border-bottom: 1px solid var(--line);
  background: rgba(6, 11, 24, 0.82); backdrop-filter: blur(12px);
  z-index: 4;
}
.hud-song { min-width: 0; }
.hud-title { font-family: var(--font-display); font-weight: 700; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hud-meta { font-size: 11px; color: var(--ink-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.hud-stats { display: flex; gap: 22px; margin-left: auto; }
.stat { text-align: right; }
.stat-label { display: block; font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-faint); font-weight: 700; }
.stat-value { display: block; font-family: var(--font-display); font-weight: 700; font-size: 19px; font-variant-numeric: tabular-nums; }
.stat-value.combo { transition: color 0.2s, text-shadow 0.2s; }
.stat-value.combo.hot { color: var(--gold); text-shadow: 0 0 16px rgba(255, 200, 90, 0.7); }

.hud-toggles { display: flex; gap: 7px; align-items: center; }
.chip-toggle {
  padding: 7px 13px; border-radius: 999px; font-size: 11.5px; font-weight: 600;
  color: var(--ink-faint); background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line); transition: 0.2s var(--ease); white-space: nowrap;
}
.chip-toggle:hover { color: #fff; }
.chip-toggle.on {
  color: #061321; background: linear-gradient(100deg, #64d6b4, #7cc4ff);
  border-color: transparent; box-shadow: 0 3px 14px rgba(80, 200, 190, 0.4);
}

/* --- stage --- */
.stage { position: relative; flex: 1; min-height: 180px; overflow: hidden; }
.note-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

.keybed {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: clamp(96px, 17vh, 150px);
  z-index: 3;
}
.keybed-glow {
  position: absolute; left: 0; right: 0; top: -3px; height: 6px;
  background: linear-gradient(90deg, rgba(90, 180, 255, 0.55), rgba(150, 220, 255, 0.95), rgba(150, 130, 255, 0.6));
  box-shadow: 0 0 26px 5px rgba(110, 190, 255, 0.65), 0 0 60px 12px rgba(80, 150, 255, 0.35);
  border-radius: 4px;
  /* --audio-level is written by the game loop from the master analyser. */
  filter: brightness(calc(1 + var(--audio-level, 0) * 1.1));
  transform: scaleY(calc(1 + var(--audio-level, 0) * 0.8));
  animation: bedPulse 3.4s ease-in-out infinite;
}
@keyframes bedPulse { 0%, 100% { opacity: 0.85; } 50% { opacity: 1; } }

.piano { position: absolute; inset: 0; user-select: none; touch-action: none; }

.pkey {
  position: absolute; top: 0;
  /* Only the key dip is animated. A `filter` leg used to sit here too, but
     nothing sets a filter on .pkey — they all land on .pkey-face, and a
     transition does not cascade to a child. */
  transition: transform 0.05s linear;
}
.pkey-face { position: absolute; inset: 0; border-radius: 0 0 5px 5px; }
.pkey-label {
  position: absolute; left: 0; right: 0; bottom: 7px;
  text-align: center; font-size: 10px; font-weight: 700;
  pointer-events: none; letter-spacing: 0.02em;
}

.pkey.white { height: 100%; z-index: 1; }
.pkey.white .pkey-face {
  background: linear-gradient(180deg, #fbfcff 0%, #f0f3fa 55%, #dfe4f0 82%, #c3cbdc 100%);
  box-shadow:
    inset 0 -7px 12px rgba(20, 30, 60, 0.16),
    inset -1.5px 0 0 rgba(20, 30, 60, 0.14),
    inset 1px 0 0 rgba(255, 255, 255, 0.9),
    0 4px 12px rgba(0, 0, 0, 0.55);
}
.pkey.white .pkey-label { color: #7d8aa3; }

.pkey.black { height: 62%; z-index: 2; }
.pkey.black .pkey-face {
  background: linear-gradient(180deg, #39415a 0%, #171d2e 42%, #0a0e1a 88%, #222a3f 100%);
  border-radius: 0 0 4px 4px;
  box-shadow:
    inset 0 -4px 8px rgba(255, 255, 255, 0.10),
    inset 0 1px 0 rgba(255, 255, 255, 0.16),
    0 6px 14px rgba(0, 0, 0, 0.75);
}
.pkey.black .pkey-label { color: #93a4c4; bottom: 5px; font-size: 9px; }

.pkey:not(.mapped) .pkey-label { opacity: 0; }
.pkey:not(.mapped) .pkey-face { filter: saturate(0.6) brightness(0.82); }

.pkey.down { transform: translateY(2px) scaleY(0.985); transform-origin: top; }
.pkey.white.down .pkey-face {
  background: linear-gradient(180deg, #dcefff 0%, #a8d8ff 60%, #7cbdf5 100%);
  box-shadow: inset 0 -6px 14px rgba(20, 60, 120, 0.35), 0 0 22px rgba(110, 190, 255, 0.75);
}
.pkey.black.down .pkey-face {
  background: linear-gradient(180deg, #4a86c8 0%, #2a5f9e 55%, #17406f 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0 0 20px rgba(110, 190, 255, 0.8);
}
/* The left hand wears the colour its own falling notes wear. This was a
   hue-rotate over the blue, which lands about eighteen degrees short of
   the note's violet and washes the key out besides; explicit stops match
   the note exactly and cost less to paint than a filter. */
.pkey.white.down.hand-left .pkey-face {
  background: linear-gradient(180deg, #f0dbff 0%, #dba8ff 60%, #c27af5 100%);
  box-shadow: inset 0 -6px 14px rgba(70, 20, 120, 0.35), 0 0 22px rgba(195, 112, 255, 0.75);
}
.pkey.black.down.hand-left .pkey-face {
  background: linear-gradient(180deg, #944dc7 0%, #6d2a9d 55%, #4a176e 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), 0 0 20px rgba(195, 112, 255, 0.8);
}

/* Where the next notes are going to land.
   Colour is reserved for the moment a note actually arrives, so this cue
   carries none: it is a light rising at the back of the key, fading out
   before the halfway mark, which leaves the key's own surface visible.
   The old version painted the same blue and violet the sounding state
   uses, and reached that colour a third of a second early — long enough
   to read as a key that was already playing.
   --lit still runs 0..1 as the note approaches, so the cue grows. */
.pkey.target:not(.down) .pkey-face::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  opacity: var(--lit, 0);
  pointer-events: none;
}
/* A white key is marked by shade, since light on white says nothing. The
   band at the very top is the marker proper; the wash below it gives the
   marker somewhere to sit.
   box-shadow rather than a filter or a border: drop-shadow re-rasterises
   the element's alpha mask every time --lit changes, which is many times
   a second across a dozen keys, and a border would move the layout. */
.pkey.white.target:not(.down) .pkey-face::after {
  background: linear-gradient(180deg,
    rgba(99, 103, 114, 0.52) 0%,
    rgba(99, 103, 114, 0.22) 30%,
    rgba(99, 103, 114, 0) 66%);
  box-shadow: inset 0 3px 0 rgba(58, 61, 70, 0.9);
}
/* A black key takes the same marker inverted, since shade on black says
   nothing either. */
.pkey.black.target:not(.down) .pkey-face::after {
  background: linear-gradient(180deg,
    rgba(238, 240, 246, 0.55) 0%,
    rgba(238, 240, 246, 0.20) 32%,
    rgba(238, 240, 246, 0) 68%);
  box-shadow: inset 0 2px 0 rgba(244, 246, 250, 0.92);
}
/* ==================================================================
   SETTINGS TABS
   ================================================================== */

/* One pane at a time. The panel had become a single long scroll where
   whatever you wanted was never where you left it. */
.stabs {
  display: flex; gap: 4px; flex-wrap: wrap;
  padding: 4px; margin-bottom: 16px;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid var(--line); border-radius: 12px;
  position: sticky; top: 0; z-index: 3;
  backdrop-filter: blur(8px);
}
.stab {
  flex: 1 1 auto; min-width: 92px;
  padding: 9px 12px; border-radius: 9px;
  font-size: 12.5px; font-weight: 600; color: var(--ink-dim);
  transition: 0.18s var(--ease);
}
.stab:hover { color: var(--ink); background: rgba(255, 255, 255, 0.05); }
.stab.on {
  color: #06121f;
  background: linear-gradient(180deg, var(--right-hand), hsl(206 100% 58%));
  box-shadow: 0 2px 10px rgba(85, 182, 255, 0.35);
}

/* ==================================================================
   KEY BINDING EDITOR
   ================================================================== */

.sgroup-note { font-size: 11.5px; color: var(--ink-faint); line-height: 1.5; margin: 0 0 10px; }

.bindgrid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(74px, 1fr));
  gap: 5px; margin-bottom: 10px;
  max-height: 320px; overflow-y: auto;
  padding: 2px;
}
/* The instrument's own black keys, so the grid reads like a keyboard
   rather than a list of names. */
.bindcell.black { background: rgba(0, 0, 0, 0.55); }
.bindcell.black .bc-note { color: #b9c6df; }
.bindcell {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 7px 4px; border-radius: 8px;
  background: rgba(0, 0, 0, 0.3); border: 1px solid var(--line);
  transition: 0.15s var(--ease);
}
.bindcell:hover { border-color: var(--right-hand); background: rgba(85, 182, 255, 0.12); }
.bc-note { font-family: var(--font-display); font-size: 12px; font-weight: 700; }
.bc-key {
  font-size: 10.5px; color: var(--ink-faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
/* Listening for the key you are about to press. */
.bindcell.listening {
  border-color: var(--accent-3); background: rgba(80, 230, 190, 0.16);
  animation: hintPulse 0.85s ease-in-out infinite;
}
.bindcell.listening .bc-key { color: var(--accent-3); }
.bindcell.unbound .bc-key { color: var(--ink-dim); font-style: italic; }
/* Bound to a key this keyboard does not physically have. */
.bindcell.offboard { border-color: rgba(255, 150, 90, 0.7); }
.bindcell.offboard .bc-key { color: #ff9a76; }

.pkey.white.target:not(.down) .pkey-label { color: #4c505c; }
.pkey.black.target:not(.down) .pkey-label { color: #d6d9e2; }

/* A sounding key kept the resting grey label, which all but disappears
   against a saturated face — and left the marked state with the darker,
   more definite label of the two, exactly backwards. */
.pkey.white.down .pkey-label { color: #16324e; }
.pkey.white.down.hand-left .pkey-label { color: #2f1049; }
.pkey.black.down .pkey-label { color: #e8f3ff; }

.pkey.hint .pkey-face {
  animation: hintPulse 0.85s ease-in-out infinite;
  box-shadow: 0 0 0 2px rgba(120, 255, 210, 0.85) inset, 0 0 22px rgba(90, 240, 200, 0.6);
}
@keyframes hintPulse { 0%, 100% { filter: brightness(1); } 50% { filter: brightness(1.35); } }

/* Live octave reach: the whole board is speaking an octave away. */
body.reach-up .keybed-glow,
body.reach-down .keybed-glow { animation: none; }
body.reach-up .keybed-glow {
  background: linear-gradient(90deg, rgba(110, 240, 200, 0.6), rgba(160, 255, 230, 0.95), rgba(110, 240, 200, 0.6));
  box-shadow: 0 0 30px 6px rgba(110, 240, 200, 0.7);
}
body.reach-down .keybed-glow {
  background: linear-gradient(90deg, rgba(200, 150, 255, 0.6), rgba(225, 190, 255, 0.95), rgba(200, 150, 255, 0.6));
  box-shadow: 0 0 30px 6px rgba(190, 150, 255, 0.7);
}
body.reach-up .sheet-octave { color: #7ef0c8; }
body.reach-down .sheet-octave { color: #c9a6ff; }

body.pedal .keybed-glow { box-shadow: 0 0 34px 8px rgba(150, 210, 255, 0.85), 0 0 80px 18px rgba(80, 150, 255, 0.5); }

/* --- key sheet ("lyrics") --- */
.sheet {
  flex: none; background: rgba(6, 11, 24, 0.9); border-top: 1px solid var(--line);
  backdrop-filter: blur(14px); z-index: 4;
}
.sheet-head { display: flex; align-items: baseline; gap: 12px; padding: 9px 20px 2px; }
.sheet-title { font-family: var(--font-display); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.14em; color: var(--accent); }
.sheet-hint { font-size: 11px; color: var(--ink-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sheet-octave { margin-left: auto; font-size: 11px; color: var(--accent-3); font-weight: 600; }

/* A mirrored gutter opposite the keyboard map, so the key sheet sits in
   the middle of the screen rather than in the bottom-left corner — you
   read it without looking away from the falling notes. */
.sheet-main {
  --keymap-w: min(340px, 30vw);
  display: grid; grid-template-columns: var(--keymap-w) minmax(0, 1fr) var(--keymap-w);
  gap: 18px; padding: 0 20px; align-items: stretch;
}
.keymap { width: 100%; }
.sheet-view {
  height: clamp(96px, 14vh, 128px); overflow: hidden; position: relative;
  mask-image: linear-gradient(180deg, transparent, #000 22%, #000 72%, transparent);
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 22%, #000 72%, transparent);
}
.sheet-lines { padding: 8px 0 24px; transition: transform 0.42s var(--ease); }

/* --- the physical keyboard map --- */
.keymap {
  width: min(340px, 30vw); flex: none;
  display: flex; flex-direction: column; gap: 7px;
  padding: 9px 11px; border-radius: 12px;
  background: rgba(255, 255, 255, 0.035); border: 1px solid var(--line);
}
.km-next { display: flex; align-items: baseline; gap: 9px; min-height: 22px; }
.km-next-label {
  font-size: 9px; text-transform: uppercase; letter-spacing: 0.14em;
  color: var(--ink-faint); font-weight: 700; flex: none;
}
.km-next-keys {
  font-family: var(--font-display); font-weight: 800; font-size: 19px;
  letter-spacing: 0.10em; color: var(--right-hand);
  text-shadow: 0 0 14px rgba(80, 170, 255, 0.6);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.km-next-keys.left { color: var(--left-hand); text-shadow: 0 0 14px rgba(202, 128, 255, 0.6); }

.km-board { display: flex; flex-direction: column; gap: 3px; }
.km-row { display: flex; gap: 3px; }
.km-row.r1 { padding-left: 7px; }
.km-row.r2 { padding-left: 13px; }
.km-row.r3 { padding-left: 19px; }
.km-key {
  flex: 1 1 0; min-width: 0; height: 19px; border-radius: 4px;
  display: grid; place-items: center; overflow: hidden;
  font-size: 8.5px; font-weight: 600; color: var(--ink-faint);
  background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.06);
  transition: background 0.12s, color 0.12s, box-shadow 0.12s, transform 0.08s;
}
.km-key.off { opacity: 0.28; }
.km-key.white { color: #b9d3f2; background: rgba(120, 180, 255, 0.09); border-color: rgba(120, 180, 255, 0.14); }
.km-key.black { color: #a99bff; background: rgba(150, 120, 255, 0.11); border-color: rgba(150, 120, 255, 0.18); }

/* Which hand owns which part of the board, at a glance. */
.km-key.zone-left { box-shadow: inset 0 -2px 0 rgba(172, 140, 255, 0.55); }
.km-key.zone-right { box-shadow: inset 0 -2px 0 rgba(85, 182, 255, 0.55); }
.km-key.zone-left.next, .km-key.zone-right.next,
.km-key.zone-left.down, .km-key.zone-right.down { box-shadow: 0 0 15px rgba(130, 195, 255, 0.85); }
.km-key.soon { background: rgba(120, 190, 255, 0.24); color: #e2f1ff; border-color: rgba(120, 190, 255, 0.4); }
.km-key.next {
  background: linear-gradient(140deg, #8ed0ff, #a89bff); color: #041220;
  border-color: transparent; box-shadow: 0 0 15px rgba(130, 195, 255, 0.85);
  animation: kmPulse 0.7s ease-in-out infinite;
}
@keyframes kmPulse { 0%, 100% { filter: brightness(1); } 50% { filter: brightness(1.35); } }
.km-key.down {
  background: linear-gradient(140deg, #6fe3c0, #7cc4ff); color: #04211c;
  border-color: transparent; transform: translateY(1px);
  box-shadow: 0 0 15px rgba(90, 220, 200, 0.75);
}

.km-legend { display: flex; gap: 14px; font-size: 9px; color: var(--ink-faint); letter-spacing: 0.06em; }
.km-lg { display: flex; align-items: center; gap: 5px; }
.km-lg i { width: 8px; height: 8px; border-radius: 2px; display: block; }
.km-lg.right i { background: var(--right-hand); box-shadow: 0 0 7px var(--right-hand); }
.km-lg.left i { background: var(--left-hand); box-shadow: 0 0 7px var(--left-hand); }

.sl {
  padding: 5px 0; opacity: 0.26; transform-origin: left center;
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease), filter 0.35s;
  filter: blur(0.4px);
}
.sl.past { opacity: 0.16; }
.sl.active { opacity: 1; filter: none; transform: scale(1.045); }
.sl-cells { display: flex; gap: 7px; flex-wrap: wrap; align-items: flex-end; justify-content: center; }

.cell {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 4px 7px; border-radius: 9px; min-width: 30px;
  background: rgba(255, 255, 255, 0.045); border: 1px solid transparent;
  transition: 0.18s var(--ease);
}
.cell.free { font-size: 13px; color: var(--ink-dim); padding: 10px 14px; }
.ck-row { display: flex; gap: 3px; }
.cell .ck {
  font-family: var(--font-display); font-weight: 700; font-size: 15px;
  line-height: 1.1; color: var(--right-hand); text-shadow: 0 0 10px rgba(80, 170, 255, 0.4);
}
.cell .ck.left { color: var(--left-hand); text-shadow: 0 0 10px rgba(202, 128, 255, 0.4); }
.cell .cn { font-style: normal; font-size: 8.5px; color: var(--ink-faint); letter-spacing: 0.03em; }

.sl.active .cell.now {
  background: linear-gradient(140deg, rgba(90, 190, 255, 0.32), rgba(198, 117, 255, 0.26));
  border-color: rgba(150, 215, 255, 0.7);
  box-shadow: 0 0 20px rgba(90, 180, 255, 0.5);
  transform: translateY(-3px) scale(1.1);
}
.sl.active .cell.now .ck { color: #fff; }
.cell.done { background: rgba(80, 230, 190, 0.14); border-color: rgba(80, 230, 190, 0.30); }
.cell.done .ck { color: var(--accent-3); text-shadow: none; }
.cell.missed { background: rgba(255, 110, 140, 0.12); border-color: rgba(255, 110, 140, 0.3); }
.cell.missed .ck { color: var(--hot); text-shadow: none; }

/* --- transport --- */
.transport {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 20px 12px;
}
.transport { margin-top: 6px; border-top: 1px solid rgba(255, 255, 255, 0.05); }
.tp-btn {
  width: 36px; height: 36px; flex: none; border-radius: 10px;
  display: grid; place-items: center; position: relative;
  color: var(--ink-dim); background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--line); font-size: 13px;
  transition: 0.18s var(--ease);
}
.tp-btn .ic { width: 18px; height: 18px; }
.tp-btn.play .ic { width: 20px; height: 20px; }
.tp-btn:hover { color: #fff; background: rgba(120, 180, 255, 0.18); transform: translateY(-1px); }
.tp-btn:active { transform: translateY(1px) scale(0.95); }
.tp-btn .tp-label {
  position: absolute; bottom: 1px; right: 3px; font-size: 7.5px; font-weight: 700;
  color: var(--accent); letter-spacing: 0.02em;
}
.tp-btn.play {
  width: 44px; height: 44px; font-size: 14px;
  background: linear-gradient(120deg, rgba(80, 160, 255, 0.35), rgba(140, 110, 250, 0.3));
  border-color: rgba(140, 200, 255, 0.4); color: #fff;
}
.tp-time { font-size: 11.5px; color: var(--ink-faint); font-variant-numeric: tabular-nums; min-width: 38px; text-align: center; }

.seek { flex: 1; height: 26px; display: flex; align-items: center; cursor: pointer; touch-action: none; }
.seek-track { position: relative; width: 100%; height: 5px; border-radius: 999px; background: rgba(255, 255, 255, 0.09); }
.seek-fill {
  position: absolute; left: 0; top: 0; bottom: 0; width: 0%; border-radius: 999px;
  background: linear-gradient(90deg, #4da6ff, #9a7cff);
  box-shadow: 0 0 14px rgba(90, 160, 255, 0.65);
}
.seek-knob {
  position: absolute; top: 50%; left: 0%; width: 13px; height: 13px; border-radius: 50%;
  transform: translate(-50%, -50%); background: #eaf4ff;
  box-shadow: 0 0 12px rgba(140, 200, 255, 0.9); transition: width 0.15s, height 0.15s;
}
.seek:hover .seek-knob { width: 16px; height: 16px; }
.speed-field { flex: none; }

/* --- overlays --- */
.overlay {
  position: absolute; inset: 0; z-index: 20; display: grid; place-items: center;
  background: rgba(3, 6, 14, 0.78); backdrop-filter: blur(10px);
  animation: fadeIn 0.22s var(--ease);
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.overlay-card {
  background: var(--panel-2); border: 1px solid var(--line-strong);
  border-radius: var(--r-lg); padding: 30px 40px; text-align: center;
  box-shadow: var(--shadow-2); animation: popIn 0.28s var(--ease);
}
@keyframes popIn { from { opacity: 0; transform: scale(0.92) translateY(10px); } to { opacity: 1; transform: none; } }
.overlay-card h3 { font-size: 26px; letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 20px; }
.overlay-actions { display: flex; flex-direction: column; gap: 9px; min-width: 220px; }

.countin { position: absolute; inset: 0; display: grid; place-items: center; z-index: 15; pointer-events: none; }
.countin span {
  font-family: var(--font-display); font-size: 104px; font-weight: 800; line-height: 1;
  color: rgba(190, 228, 255, 0.95); text-shadow: 0 0 60px rgba(90, 170, 255, 0.8);
  /* Duration is set per beat from the game loop. */
  animation: countPop 0.85s var(--ease) both;
}
@keyframes countPop {
  0% { opacity: 0; transform: scale(1.9); filter: blur(6px); }
  22% { opacity: 1; transform: scale(1); filter: blur(0); }
  75% { opacity: 0.9; transform: scale(1); }
  100% { opacity: 0; transform: scale(0.86); }
}

/* ==================================================================
   BUTTONS
   ================================================================== */

.btn {
  position: relative; overflow: hidden;
  padding: 11px 20px; border-radius: 11px; font-weight: 600; font-size: 14px;
  background: rgba(255, 255, 255, 0.06); border: 1px solid var(--line); color: var(--ink);
  transition: background 0.18s var(--ease), border-color 0.18s var(--ease),
    transform 0.12s var(--ease), box-shadow 0.18s var(--ease), filter 0.18s;
}
.btn:hover { background: rgba(120, 180, 255, 0.16); border-color: var(--line-strong); transform: translateY(-1px); }
.btn:active { transform: translateY(1px) scale(0.985); filter: brightness(0.94); }
.btn.primary {
  background: linear-gradient(100deg, #3f8fe8, #8a6ff0); border-color: transparent; color: #fff;
  box-shadow: 0 6px 22px rgba(70, 130, 240, 0.4);
}
.btn.primary:hover { box-shadow: 0 10px 30px rgba(70, 130, 240, 0.55); filter: brightness(1.08); }
.btn.primary:active { filter: brightness(0.95); }
.btn.ghost { background: transparent; color: var(--ink-faint); }
.btn.ghost:hover { color: var(--ink); }
.btn.big { width: 100%; padding: 15px; font-size: 16px; font-family: var(--font-display); letter-spacing: 0.05em; }
.btn.small { padding: 7px 13px; font-size: 12.5px; }

/* Press feedback on anything clickable, so a tap always registers visibly. */
.chip:active, .chip-toggle:active, .seg button:active,
.icon-btn:active, .tp-btn:active, .menu-btn:active, .song-panel:active { filter: brightness(0.92); }
.menu-btn:active { transform: translateY(1px) scale(0.995); }

/* A visible keyboard focus ring everywhere — the game is played by
   keyboard, so tabbing through the UI has to be legible. */
:where(button, select, input, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 8px;
}

/* ==================================================================
   RESULTS
   ================================================================== */

.screen-result { align-items: center; justify-content: center; }
.result-card {
  width: min(760px, 94vw); background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 28px; backdrop-filter: blur(18px);
  box-shadow: var(--shadow-2); animation: popIn 0.45s var(--ease) both;
}
.result-head { text-align: center; margin-bottom: 22px; }
.result-head h2 { font-size: 13px; letter-spacing: 0.28em; text-transform: uppercase; color: var(--ink-faint); }
.result-song { font-family: var(--font-display); font-size: 19px; font-weight: 600; margin-top: 6px; }

.result-body { display: grid; grid-template-columns: 190px 1fr; gap: 26px; align-items: center; }

.rank-badge {
  width: 175px; height: 175px; border-radius: 50%; display: grid; place-items: center;
  position: relative; animation: rankIn 0.7s var(--ease) 0.15s both;
}
@keyframes rankIn { from { opacity: 0; transform: scale(0.4) rotate(-25deg); } to { opacity: 1; transform: none; } }
.rank-badge::before {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(from 0deg, transparent, currentColor, transparent 60%);
  opacity: 0.35; animation: spin 7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.rank-badge::after {
  content: ''; position: absolute; inset: 9px; border-radius: 50%;
  background: rgba(8, 13, 28, 0.94); border: 1px solid rgba(255, 255, 255, 0.1);
}
.rank-badge span {
  position: relative; z-index: 2; font-family: var(--font-display);
  font-size: 74px; font-weight: 800; line-height: 1; color: currentColor;
  text-shadow: 0 0 40px currentColor;
}
.rank-badge.rSS { color: #ffe08a; }
.rank-badge.rS { color: #ffd166; }
.rank-badge.rA { color: #7bf5b2; }
.rank-badge.rB { color: #7cc4ff; }
.rank-badge.rC { color: #b79bff; }
.rank-badge.rD { color: #ff8fa8; }
.rank-badge.rX { color: #6b809f; }

.result-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px; }
.rr {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  padding: 9px 13px; border-radius: 10px;
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--line);
  animation: fadeIn 0.5s var(--ease) both;
}
.rr.big { grid-column: span 2; }
.rr-l { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-faint); font-weight: 700; }
.rr b { font-family: var(--font-display); font-size: 17px; font-variant-numeric: tabular-nums; }
.rr.big b { font-size: 26px; }
.rr.j-perfect b { color: #9beeff; }
.rr.j-great b { color: #8cffc0; }
.rr.j-good b { color: #ffe08a; }
.rr.j-miss b { color: var(--hot); }

.result-tags { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin: 20px 0 4px; min-height: 10px; }
.rtag {
  padding: 6px 14px; border-radius: 999px; font-size: 11px; font-weight: 800;
  letter-spacing: 0.12em; text-transform: uppercase;
  animation: popIn 0.4s var(--ease) both;
}
.rtag.fc { background: linear-gradient(100deg, #45e6c8, #4da6ff); color: #041a20; }
.rtag.perfect { background: linear-gradient(100deg, #ffd166, #ff9f5a); color: #2a1400; }
.rtag.best { background: linear-gradient(100deg, #9a7cff, #ff8fd0); color: #1c0a2a; }
.rtag.auto { background: rgba(255, 255, 255, 0.08); color: var(--ink-faint); }

.result-actions { display: flex; gap: 10px; justify-content: center; margin-top: 20px; }
.result-actions .btn { min-width: 160px; }

/* ==================================================================
   MODALS + FORM CONTROLS
   ================================================================== */

.modal {
  position: fixed; inset: 0; z-index: 60; display: grid; place-items: center;
  background: rgba(2, 5, 12, 0.72); backdrop-filter: blur(8px);
  opacity: 0; transition: opacity 0.2s var(--ease); padding: 20px;
}
.modal.shown { opacity: 1; }
.modal-card {
  width: min(560px, 96vw); max-height: 88vh; display: flex; flex-direction: column;
  background: linear-gradient(160deg, rgba(18, 27, 52, 0.97), rgba(11, 17, 36, 0.97));
  border: 1px solid var(--line-strong); border-radius: var(--r-lg);
  box-shadow: var(--shadow-2); transform: scale(0.95) translateY(12px);
  transition: transform 0.26s var(--ease);
}
.modal.shown .modal-card { transform: none; }
.modal-card.wide { width: min(780px, 96vw); }
.modal-head { display: flex; align-items: center; gap: 12px; padding: 18px 20px 12px; border-bottom: 1px solid var(--line); }
.modal-head h3 { flex: 1; font-size: 17px; }
.modal-body { padding: 16px 20px; overflow-y: auto; flex: 1; }
.modal-foot { display: flex; gap: 10px; justify-content: flex-end; padding: 14px 20px; border-top: 1px solid var(--line); }

.sgroup { margin-bottom: 22px; }
.sgroup h4 {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.16em;
  color: var(--accent); margin-bottom: 10px; font-weight: 700;
}
.srow {
  display: grid; grid-template-columns: 1fr auto; gap: 14px; align-items: center;
  padding: 11px 0; border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.srow:last-child { border-bottom: 0; }
.srow-l span { font-size: 13.5px; font-weight: 500; display: block; }
.srow-l small { display: block; font-size: 11px; color: var(--ink-faint); margin-top: 3px; line-height: 1.5; }
.srow-c { display: flex; align-items: center; gap: 8px; justify-content: flex-end; }
.srow-c select { min-width: 150px; max-width: 230px; }
.note-dim { font-size: 11.5px; color: var(--ink-faint); max-width: 220px; text-align: right; }

.slider { display: flex; align-items: center; gap: 10px; }
.slider output { font-size: 12px; color: var(--accent); font-variant-numeric: tabular-nums; min-width: 46px; text-align: right; font-weight: 600; }
input[type="range"] {
  -webkit-appearance: none; appearance: none; width: 140px; height: 4px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.12); outline: none;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 15px; height: 15px; border-radius: 50%;
  background: linear-gradient(140deg, #8fd0ff, #a68bff); cursor: pointer;
  box-shadow: 0 0 12px rgba(120, 180, 255, 0.7);
}
input[type="range"]::-moz-range-thumb {
  width: 15px; height: 15px; border: 0; border-radius: 50%;
  background: linear-gradient(140deg, #8fd0ff, #a68bff); cursor: pointer;
}

.switch {
  width: 46px; height: 26px; border-radius: 999px; position: relative;
  background: rgba(255, 255, 255, 0.10); border: 1px solid var(--line);
  transition: 0.22s var(--ease);
}
.switch i {
  position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%;
  background: #7f92b3; transition: 0.22s var(--ease);
}
.switch.on { background: linear-gradient(100deg, #3f8fe8, #8a6ff0); border-color: transparent; }
.switch.on i { left: 23px; background: #fff; box-shadow: 0 0 12px rgba(255, 255, 255, 0.8); }

/* --- rollover modal --- */
.kro-intro { font-size: 13px; color: var(--ink-dim); line-height: 1.6; margin: 0 0 14px; }
.kro-test { display: flex; align-items: center; gap: 14px; margin-bottom: 12px; flex-wrap: wrap; }
.kro-live { font-size: 12.5px; color: var(--accent-3); font-weight: 600; }
.kro-verdict { font-size: 13px; line-height: 1.55; padding: 10px 13px; border-radius: 10px; margin: 0 0 14px; }
.kro-verdict.good { background: rgba(70, 230, 190, 0.10); border: 1px solid rgba(70, 230, 190, 0.3); color: #9df3dd; }
.kro-verdict.ok { background: rgba(255, 209, 102, 0.10); border: 1px solid rgba(255, 209, 102, 0.3); color: #ffe3a3; }
.kro-verdict.bad { background: rgba(255, 122, 156, 0.10); border: 1px solid rgba(255, 122, 156, 0.3); color: #ffb3c5; }
.kro-tip { font-size: 12px; color: var(--ink-faint); line-height: 1.6; margin: 16px 0 0; }

.kbd-map { display: flex; flex-direction: column; gap: 4px; padding: 12px; border-radius: var(--r-md); background: rgba(0, 0, 0, 0.35); border: 1px solid var(--line); margin-bottom: 16px; overflow-x: auto; }
.kbd-row { display: flex; gap: 4px; }
.kbd-row.r1 { padding-left: 14px; }
.kbd-row.r2 { padding-left: 24px; }
.kbd-row.r3 { padding-left: 36px; }
.kk {
  min-width: 30px; height: 34px; flex: none; border-radius: 6px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600; color: var(--ink-faint);
  background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.07);
  transition: 0.12s;
}
.kk i { font-style: normal; font-size: 7px; opacity: 0.6; }
.kk.white { color: #cfe0f7; background: rgba(120, 180, 255, 0.10); border-color: rgba(120, 180, 255, 0.2); }
.kk.black { color: #a99bff; background: rgba(150, 120, 255, 0.12); border-color: rgba(150, 120, 255, 0.24); }
.kk.lit {
  background: linear-gradient(140deg, #7cc4ff, #a89bff); color: #04121f;
  border-color: transparent; box-shadow: 0 0 16px rgba(120, 190, 255, 0.8);
  transform: translateY(1px);
}
.kk.lit i { color: #04121f; opacity: 0.75; }

/* --- how to play --- */
.ht-block { margin-bottom: 16px; }
.ht-block h4 { font-size: 13px; color: var(--accent); margin-bottom: 5px; }
.ht-block p { font-size: 13px; color: var(--ink-dim); line-height: 1.65; margin: 0; }
.ht-keys { margin: 18px 0; }
.ht-keys h4 { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.14em; color: var(--accent); margin-bottom: 9px; }
.kk-row { display: flex; align-items: center; gap: 12px; padding: 6px 0; font-size: 13px; color: var(--ink-dim); }
kbd {
  font-family: var(--font-display); font-size: 11.5px; font-weight: 700;
  padding: 5px 10px; border-radius: 7px; min-width: 54px; text-align: center;
  background: rgba(255, 255, 255, 0.08); border: 1px solid var(--line);
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.4); color: var(--ink);
}

.ht-credit {
  margin: 16px 0 0; padding-top: 12px; border-top: 1px solid var(--line);
  font-size: 11px; color: var(--ink-faint); line-height: 1.6;
}
.ht-credit a { color: var(--accent); }

/* ==================================================================
   TOAST + AUDIO NUDGE
   ================================================================== */

.toast {
  position: fixed; left: 50%; bottom: 34px; transform: translate(-50%, 20px);
  z-index: 90; padding: 12px 22px; border-radius: 999px;
  background: rgba(16, 26, 50, 0.95); border: 1px solid var(--line-strong);
  font-size: 13px; box-shadow: var(--shadow-2);
  opacity: 0; transition: 0.25s var(--ease); pointer-events: none;
}
.toast.shown { opacity: 1; transform: translate(-50%, 0); }

.audio-nudge {
  position: fixed; right: 20px; top: 20px; z-index: 80;
  /* Purely informational and it floats over the UI, so it must never be
     able to intercept a click meant for a control underneath it. */
  pointer-events: none;
  padding: 10px 18px; border-radius: 999px; font-size: 12.5px;
  background: rgba(16, 26, 50, 0.92); border: 1px solid var(--line-strong);
  color: var(--ink-dim); animation: nudge 2.4s ease-in-out infinite;
}
body.in-play .audio-nudge { display: none; }
@keyframes nudge { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }

/* ==================================================================
   RESPONSIVE
   ================================================================== */

@media (max-width: 1180px) {
  .sheet-main { --keymap-w: min(260px, 26vw); }
  .km-key { font-size: 7.5px; height: 17px; }
}

@media (max-width: 900px) {
  .sheet-main { grid-template-columns: minmax(0, 1fr); }
  .keymap, .sheet-gutter { display: none; }
}

@media (max-width: 1000px) {
  .select-body { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .detail-pane { max-height: 40vh; }
  .result-body { grid-template-columns: 1fr; justify-items: center; }
  .hud-stats { gap: 14px; }
  .stat-value { font-size: 16px; }
}

@media (max-width: 720px) {
  .menu-nav { grid-template-columns: 1fr; }
  .select-top { flex-wrap: wrap; }
  .search-box { max-width: none; order: 3; width: 100%; margin-left: 0; }
  .sort-field { order: 2; }
  .hud { flex-wrap: wrap; gap: 8px 12px; }
  .hud-toggles { width: 100%; justify-content: flex-end; }
  .sheet-hint { display: none; }
  .transport { flex-wrap: wrap; }
  .seek { order: 9; width: 100%; flex-basis: 100%; }
  .result-grid { grid-template-columns: 1fr; }
  .rr.big { grid-column: span 1; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.08s !important;
  }
}

/* ==================================================================
   ACCOUNTS
   ================================================================== */

.afield { display: block; margin-bottom: 14px; }
.afield-label {
  display: block; font-size: 11.5px; font-weight: 600; color: var(--ink-dim);
  text-transform: uppercase; letter-spacing: 0.09em; margin-bottom: 6px;
}
.afield input { width: 100%; padding: 10px 12px; font-size: 14px; }
.afield-note { display: block; font-size: 11.5px; color: var(--ink-faint); margin-top: 5px; min-height: 15px; }
.afield-note.good { color: var(--accent-3); }
.afield-note.bad { color: var(--hot); }

.acheck {
  display: flex; gap: 10px; align-items: flex-start;
  font-size: 12.5px; color: var(--ink-dim); line-height: 1.5;
  margin-bottom: 10px; cursor: pointer;
}
.acheck input { margin: 2px 0 0; accent-color: var(--accent); flex: none; }
.acheck a { color: var(--accent); }

.arow { display: flex; gap: 10px; margin-top: 16px; }
.arow.tight { margin-top: 8px; }
.arow .btn { flex: 1; }
.arow.tight .btn { flex: 0 0 auto; }
.arow input { flex: 1; padding: 8px 11px; }

.alinks { margin-top: 14px; font-size: 12.5px; color: var(--ink-faint); }
.alink {
  color: var(--accent); font-size: 12.5px; font-weight: 600;
  padding: 0; border-bottom: 1px solid transparent;
}
.alink:hover { border-bottom-color: currentColor; }
.alink.danger { color: var(--hot); }
.alink-sep { margin: 0 7px; opacity: 0.4; }
.adim { color: var(--ink-faint); }

.anote { font-size: 12.5px; line-height: 1.55; color: var(--ink-dim); margin: 0 0 14px; }
.anote.dim { color: var(--ink-faint); font-size: 12px; }
.anote.warn { color: var(--hot); }

/* Reserves its own height, so a message appearing does not shove the
   buttons down under the cursor that was about to click them. */
.aresult { min-height: 18px; font-size: 12.5px; margin-top: 4px; }
.aresult.bad { color: var(--hot); }
.aresult.good { color: var(--accent-3); }

.aturnstile { margin: 4px 0 10px; }

.ah {
  font-size: 12px; font-weight: 700; color: var(--ink-dim);
  text-transform: uppercase; letter-spacing: 0.1em;
  margin: 22px 0 10px; padding-top: 16px; border-top: 1px solid var(--line);
}

/* ---- profile ---- */

.aprofile { display: flex; gap: 16px; align-items: center; margin-bottom: 18px; }
.aprofile-face { flex: none; line-height: 0; }
.aprofile-face svg { border-radius: 20px; box-shadow: var(--shadow-1); }
.aprofile-who { min-width: 0; }
.aprofile-name { font-family: var(--font-display); font-size: 21px; font-weight: 700; }
.aprofile-since { font-size: 12px; color: var(--ink-faint); margin-top: 2px; }
.aprofile-mail { font-size: 12px; color: var(--ink-faint); margin-top: 4px; word-break: break-all; }

.astats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 4px; }
.astat {
  background: rgba(0, 0, 0, 0.24); border: 1px solid var(--line);
  border-radius: 11px; padding: 10px 8px; text-align: center;
}
.astat b { display: block; font-family: var(--font-display); font-size: 17px; }
.astat span { display: block; font-size: 10.5px; color: var(--ink-faint); margin-top: 3px; line-height: 1.3; }

.avgrid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; }
.avpick {
  padding: 4px; border-radius: 13px; line-height: 0;
  border: 2px solid transparent; transition: 0.18s var(--ease);
}
.avpick:hover { border-color: var(--line-strong); transform: translateY(-2px); }
.avpick.on { border-color: var(--accent); box-shadow: var(--glow); }
.avpick svg { border-radius: 11px; }

.adanger { margin-top: 24px; padding-top: 16px; border-top: 1px solid rgba(255, 122, 156, 0.22); }

/* ==================================================================
   LEADERBOARD
   ================================================================== */

.dp-board { margin-top: 20px; }

.lb-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 12px; }
.lb-head h4 {
  font-size: 12px; font-weight: 700; color: var(--ink-dim);
  text-transform: uppercase; letter-spacing: 0.1em;
}
.lb-hands { font-size: 11px; color: var(--ink-faint); }
.lb-note { font-size: 12.5px; color: var(--ink-dim); padding: 10px 0; line-height: 1.5; }
.lb-note.dim { color: var(--ink-faint); font-size: 12px; }

/* ---- podium ----
   Second, first, third in the DOM, which is the order they are read in
   and the order they are shown in. The middle plinth is taller through
   its own height rather than a transform, so the three still sit on one
   baseline at the bottom. */
.lb-podium {
  display: grid; grid-template-columns: 1fr 1.18fr 1fr; gap: 8px;
  align-items: end; margin-bottom: 16px;
}
.pod { display: flex; flex-direction: column; align-items: center; min-width: 0; }
.pod-figure { position: relative; line-height: 0; }
.pod-av svg { border-radius: 16px; box-shadow: var(--shadow-1); }
.pod-1 .pod-av svg { box-shadow: 0 6px 26px rgba(255, 209, 102, 0.34); }
.pod-fc {
  position: absolute; right: -5px; bottom: -4px;
  font-size: 9px; font-weight: 800; letter-spacing: 0.04em;
  background: var(--accent-3); color: #062018;
  padding: 2px 5px; border-radius: 6px;
}
.pod-name {
  margin-top: 8px; font-size: 12.5px; font-weight: 600;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pod-1 .pod-name { font-size: 14px; }
.pod-score { font-family: var(--font-display); font-size: 13.5px; margin-top: 2px; }
.pod-1 .pod-score { font-size: 16px; color: var(--gold); }
.pod-acc { font-size: 10.5px; color: var(--ink-faint); }
.pod-step {
  width: 100%; margin-top: 8px; border-radius: 9px 9px 0 0;
  background: linear-gradient(180deg, rgba(120, 170, 255, 0.20), rgba(90, 130, 220, 0.06));
  border: 1px solid var(--line); border-bottom: 0;
  display: grid; place-items: center;
}
.pod-1 .pod-step {
  height: 54px;
  background: linear-gradient(180deg, rgba(255, 209, 102, 0.26), rgba(255, 209, 102, 0.04));
}
.pod-2 .pod-step { height: 38px; }
.pod-3 .pod-step { height: 28px; }
.pod-step b { font-family: var(--font-display); font-size: 15px; opacity: 0.75; }
.pod.empty .pod-step { opacity: 0.3; }
.pod.mine .pod-name { color: var(--accent); }

/* ---- the rest of the list ---- */
.lb-list { list-style: none; margin: 0; padding: 0; }
.lb-row, .lb-mine {
  display: grid;
  grid-template-columns: 26px 28px 1fr auto auto auto;
  gap: 9px; align-items: center;
  padding: 6px 8px; border-radius: 9px; font-size: 12.5px;
}
.lb-row + .lb-row { margin-top: 2px; }
.lb-row:nth-child(odd) { background: rgba(255, 255, 255, 0.028); }
.lb-row.mine, .lb-mine { background: rgba(77, 166, 255, 0.14); border: 1px solid var(--line-strong); }
.lb-mine { margin-top: 10px; }
.lb-pos { font-family: var(--font-display); color: var(--ink-faint); text-align: right; font-size: 12px; }
.lb-av { line-height: 0; }
.lb-av svg { border-radius: 8px; display: block; }
.lb-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-name i { font-style: normal; color: var(--accent); font-size: 10.5px; margin-left: 4px; }
.lb-rank { font-family: var(--font-display); font-weight: 700; font-size: 11.5px; opacity: 0.9; }
.lb-acc { color: var(--ink-faint); font-size: 11.5px; font-variant-numeric: tabular-nums; }
.lb-score { font-family: var(--font-display); font-variant-numeric: tabular-nums; }

/* ---- on the results screen ---- */
.result-rank { margin-top: 14px; }
.rrank {
  display: inline-flex; flex-wrap: wrap; gap: 6px 10px; align-items: baseline;
  justify-content: center; font-size: 12.5px;
  padding: 9px 14px; border-radius: 11px;
  background: rgba(0, 0, 0, 0.28); border: 1px solid var(--line);
}
.rrank.good { color: var(--accent-3); border-color: rgba(69, 230, 200, 0.35); }
.rrank.dim { color: var(--ink-faint); }
.rrank b { color: var(--ink-dim); font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.08em; }
.rrank span { display: block; }

/* The account button carries a picture once somebody is signed in, and
   an avatar is an <svg>, not the 19px icon the menu normally holds. */
#menu-account-face svg { width: 26px; height: 26px; border-radius: 8px; display: block; }

@media (max-width: 720px) {
  .astats { grid-template-columns: repeat(2, 1fr); }
  .avgrid { grid-template-columns: repeat(4, 1fr); }
  .lb-row, .lb-mine { grid-template-columns: 22px 24px 1fr auto auto; }
  .lb-rank { display: none; }
}

/* The legal links under the menu. Small, quiet, and always reachable —
   an imprint that can only be found from a footer nobody scrolls to is
   an imprint that has not been published. */
.menu-legal {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 4px 14px; margin-top: 18px; padding-top: 16px;
  border-top: 1px solid var(--line);
}
.menu-legal a {
  font-size: 11.5px; color: var(--ink-faint); text-decoration: none;
  transition: color 0.18s var(--ease);
}
.menu-legal a:hover { color: var(--accent); }

/* ═══════════════ a player's page ═══════════════
   Opened from any leaderboard entry. Everything on it is already public
   — name, avatar, join date, results — so it needs no session and reads
   no cookie. */

/* One place for the grade colours. They were only defined on
   .rank-badge, so the letter beside every leaderboard row rendered in
   body ink and told you nothing at a glance. */
:root {
  --rank-SS: #ffe08a;
  --rank-S: #ffd166;
  --rank-A: #7bf5b2;
  --rank-B: #7cc4ff;
  --rank-C: #b79bff;
  --rank-D: #ff8fa8;
}
.rSS { color: var(--rank-SS); }
.rS  { color: var(--rank-S); }
.rA  { color: var(--rank-A); }
.rB  { color: var(--rank-B); }
.rC  { color: var(--rank-C); }
.rD  { color: var(--rank-D); }

/* A board entry is a door now, so it has to look like one. */
.lb-row[data-user], .lb-mine[data-user], .pod[data-user] {
  cursor: pointer;
  transition: background 0.16s var(--ease), transform 0.16s var(--ease);
}
.lb-row[data-user]:hover, .lb-mine[data-user]:hover { background: rgba(77, 166, 255, 0.16); }
.pod[data-user]:hover { transform: translateY(-3px); }
.lb-row[data-user]:focus-visible, .lb-mine[data-user]:focus-visible,
.pod[data-user]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.pf { display: flex; flex-direction: column; gap: 18px; }

.pf-head { display: flex; align-items: center; gap: 14px; }
.pf-face { line-height: 0; }
.pf-face svg { border-radius: 16px; display: block; }
.pf-who { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.pf-who b {
  font-family: var(--font-display); font-size: 21px; font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pf-who b i { font-style: normal; color: var(--accent); font-size: 12px; margin-left: 6px; }
.pf-who small { font-size: 12px; color: var(--ink-faint); }

.pf-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; }
.pf-tile {
  padding: 11px 13px; border-radius: 11px;
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--line);
}
.pf-tile b {
  display: block; font-family: var(--font-display); font-size: 20px; font-weight: 700;
  font-variant-numeric: tabular-nums; line-height: 1.15;
}
.pf-tile span {
  display: block; margin-top: 3px; font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.09em; color: var(--ink-faint);
}

.pf h4 {
  margin: 0 0 9px; font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-dim);
}

/* ---- the spread of grades ---- */
.pf-rankbar {
  display: flex; height: 9px; border-radius: 5px; overflow: hidden;
  background: rgba(255, 255, 255, 0.05);
}
.pf-rankbar span { display: block; background: currentColor; }
.pf-ranklegend {
  display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 8px; font-size: 11.5px;
  color: var(--ink-faint);
}
.pf-ranklegend span { display: inline-flex; align-items: center; gap: 5px; }
.pf-ranklegend i { width: 8px; height: 8px; border-radius: 3px; background: currentColor; }
.pf-ranklegend b { color: var(--ink); font-variant-numeric: tabular-nums; }

/* ---- badges ---- */
.pf-achcount {
  float: right; font-family: var(--font-display); color: var(--accent);
  letter-spacing: 0.04em;
}
.pf-achlist {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px;
}
.pf-ach {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 10px 12px; border-radius: 11px;
  background: rgba(255, 255, 255, 0.03); border: 1px solid var(--line);
  opacity: 0.55;
}
.pf-ach.got {
  opacity: 1;
  background: rgba(255, 209, 102, 0.09);
  border-color: rgba(255, 209, 102, 0.28);
}
.pf-ach-mark { font-size: 17px; line-height: 1.1; color: var(--ink-faint); }
.pf-ach.got .pf-ach-mark { color: var(--gold); text-shadow: 0 0 14px rgba(255, 209, 102, 0.5); }
.pf-ach-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.pf-ach-text b { font-size: 12.5px; font-weight: 700; }
.pf-ach-text small { font-size: 11px; color: var(--ink-faint); line-height: 1.45; }
.pf-ach-bar {
  display: block; height: 3px; margin-top: 5px; border-radius: 2px;
  background: rgba(255, 255, 255, 0.08); overflow: hidden;
}
.pf-ach-bar i { display: block; height: 100%; background: var(--accent); border-radius: 2px; }
.pf-ach-count {
  font-size: 10px; color: var(--ink-faint); font-variant-numeric: tabular-nums; margin-top: 3px;
}

/* ---- best runs ---- */
.pf-scorelist { list-style: none; margin: 0; padding: 0; }
.pf-score {
  display: grid;
  grid-template-columns: 1fr 54px 30px 26px 62px auto;
  gap: 9px; align-items: center;
  padding: 7px 8px; border-radius: 9px; font-size: 12.5px;
}
.pf-score:nth-child(odd) { background: rgba(255, 255, 255, 0.028); }
.pf-song { display: flex; flex-direction: column; min-width: 0; }
.pf-song b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.pf-song small { font-size: 10.5px; color: var(--ink-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pf-hands { font-size: 10.5px; color: var(--ink-faint); }
.pf-rank { font-family: var(--font-display); font-weight: 700; font-size: 11.5px; }
.pf-fc { font-size: 9px; font-weight: 800; color: var(--accent-3); }
.pf-acc { color: var(--ink-faint); font-size: 11.5px; font-variant-numeric: tabular-nums; }
.pf-pts { font-family: var(--font-display); font-variant-numeric: tabular-nums; text-align: right; }

.pf-empty { padding: 26px 0; text-align: center; color: var(--ink-faint); font-size: 13px; }

@media (max-width: 720px) {
  .pf-tiles { grid-template-columns: repeat(2, 1fr); }
  .pf-achlist { grid-template-columns: 1fr; }
  /* Hand mode and accuracy go, and the title takes their width. At five
     columns a phone left roughly 90px for a name like "Ode To Dennis -
     Jack Black", which is an ellipsis with a word in front of it. */
  .pf-score { grid-template-columns: 1fr 26px 24px auto; }
  .pf-hands, .pf-acc { display: none; }
}

/* ═══════════════ playing without an account ═══════════════
   A guest has a number and a name to be called by. Everything here is
   local to the device — the label is not an account, and the styling is
   deliberately quieter than a signed-in one so it does not read as one. */

#menu-account.as-guest #menu-account-name {
  color: var(--ink-faint);
  font-weight: 500;
}

/* ---- the block on the results screen ---- */
.rguest {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  padding: 13px 16px; border-radius: 12px;
  background: rgba(122, 162, 255, 0.10);
  border: 1px solid rgba(122, 162, 255, 0.30);
  text-align: center;
}
.rguest b { font-family: var(--font-display); font-size: 14px; font-weight: 700; }
.rguest span { font-size: 12px; line-height: 1.5; color: var(--ink-dim); max-width: 40ch; }
.rguest .btn { margin-top: 4px; }

/* ---- the modal ---- */
.gp-who {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 14px; margin-bottom: 16px; border-radius: 12px;
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--line);
}
.gp-face { line-height: 0; color: var(--ink-faint); }
.gp-face svg { width: 26px; height: 26px; display: block; }
.gp-name { font-family: var(--font-display); font-size: 17px; font-weight: 700; }

.gp-lead { margin: 0 0 14px; font-size: 13.5px; line-height: 1.6; color: var(--ink-dim); }

.gp-list { list-style: none; margin: 0 0 14px; padding: 0; display: grid; gap: 8px; }
.gp-list li {
  display: grid; grid-template-columns: 18px 1fr; gap: 9px; align-items: start;
  font-size: 13px; line-height: 1.5;
}
/* The mark is drawn rather than written, so no glyph has to survive
   thirteen languages and a font fallback. */
.gp-list li::before {
  content: ''; width: 14px; height: 14px; margin-top: 3px; border-radius: 50%;
  border: 1.5px solid currentColor;
}
.gp-list li.no { color: var(--hot); }
.gp-list li.no::before {
  background:
    linear-gradient(45deg, transparent 44%, currentColor 44%, currentColor 56%, transparent 56%),
    linear-gradient(-45deg, transparent 44%, currentColor 44%, currentColor 56%, transparent 56%);
}
.gp-list li.yes { color: var(--accent-3); }
.gp-list li.yes::before { background: currentColor; }
.gp-list li span { color: var(--ink-dim); }

.gp-foot { margin: 0; font-size: 12px; line-height: 1.55; color: var(--ink-faint); }

/* The dismissal sits apart from the two real choices rather than beside
   them, so "never" is not one click away from "sign up". */
.modal-foot.gp-foot-row { display: flex; align-items: center; gap: 10px; }
.modal-foot.gp-foot-row .alink { margin-right: auto; font-size: 12px; }

@media (max-width: 560px) {
  .modal-foot.gp-foot-row { flex-wrap: wrap; }
  .modal-foot.gp-foot-row .alink { order: 3; margin-right: 0; width: 100%; text-align: center; }
}
