/* ============================================================
   Themes, shared by every page. The theme is picked in the Chords
   trainer's options and stored in localStorage ('etude.theme'); each
   page applies it before first paint with the same inline script.
   Themes only override the palette tokens every page defines (--ink,
   --ivory, --gold…), plus a few chord-trainer specific fixes.
   ============================================================ */

/* Theme backdrops live on a fixed body::after; keep page content above it. */
body[data-theme] .app { position: relative; z-index: 2; }

/* ============================================================
   THEME VARIANTS — toggle via [data-theme] on <body>.
   The base palette in :root is the original "Ink" theme; each
   variant overrides the same tokens and lets the cascade flow.
   Piano keys remain skeuomorphic across themes (real keys are
   always ivory/black).
   ============================================================ */

/* — Urtext — Henle-style ivory paper, charcoal ink, deep gold. */
body[data-theme="urtext"] {
  --ink: #ede2ca;
  --paper: #e3d6b8;
  --ivory: #1a1410;
  --ivory-dim: #5a4f42;
  --gold: #8a6a2c;
  --gold-bright: #a8843a;
  --crimson: #7a2828;
  --sage: #4a6b4a;
  --line: #c4b69a;
  background: var(--ink);
}
/* Gradients live on a viewport-sized fixed pseudo with `translateZ(0)` so Chrome
   promotes them to their own compositor layer. Scroll doesn't tile-rasterize the
   gradient across the full document height — that was the source of mobile jank. */
body[data-theme="urtext"]::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  transform: translateZ(0);
  background-image:
    radial-gradient(ellipse at 50% -10%, rgba(138, 106, 44, 0.10), transparent 60%),
    radial-gradient(ellipse at 50% 110%, rgba(26, 20, 16, 0.06), transparent 50%);
}
/* Paper grain — only Urtext uses it (multiply blend on the cream paper turns
   the SVG turbulence into a subtle printing texture). Other themes don't
   declare ::before, so the pseudo-element doesn't exist for them. */
body[data-theme="urtext"]::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: var(--z-grain, 1);
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
  opacity: 0.18;
  mix-blend-mode: multiply;
}
/* The current-chord halo uses --ink as a solid center to occlude prev/next
   cards on dark themes — they share the same near-black, so the halo blends
   in. On urtext the paper texture (body::before, multiply) shows through
   everywhere except over the halo, leaving the halo as a visible cream patch.
   Replace the colour fill with a backdrop blur masked by the same elliptical
   shape: the texture stays continuous while prev/next cards still soften
   behind the current chord. */
body[data-theme="urtext"] .chord-card.is-current::before {
  background: none;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  mask-image: radial-gradient(ellipse at center, #000 18%, transparent 70%);
}
/* On a paper background, black-translucent panel surfaces darken nicely.
   But the rgba(255,255,255,X) lighten gradients vanish — replace those
   spots with a faint warm-paper tint via a sibling override. */
body[data-theme="urtext"] .piano-wrap,
body[data-theme="urtext"] .guitar-wrap {
  background: rgba(26, 20, 16, 0.04);
}
/* Guitar dot strokes/labels reference --ink (the page background colour,
   which is cream in Urtext). On a dark theme that gives a dark outline;
   on cream paper it dissolves. Re-anchor to --ivory (the ink colour). */
body[data-theme="urtext"] .gtr-dot {
  stroke: var(--ivory);
}
body[data-theme="urtext"] .gtr-dot.open {
  stroke: var(--ivory);
}
body[data-theme="urtext"] .gtr-dot-label {
  fill: var(--ivory);
}

/* — Boudoir — library/lounge: warm reading-lamp pool, leather-corner
   vignettes, vertical curtain fall (subtle velvet ribbing). No grain. */
body[data-theme="boudoir"] {
  --ink: #1a1410;
  --paper: #25201a;
  --line: #3a302a;
  background: var(--ink);
}
/* Same trick as Urtext — gradients on a fixed, GPU-composited pseudo so the
   8-layer stack is rasterized once at viewport size, not tiled across the
   full body height on every scroll. */
body[data-theme="boudoir"]::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  transform: translateZ(0);
  background-image:
    /* warm reading-lamp pool, top-center */
    radial-gradient(ellipse 90% 55% at 50% -10%, rgba(var(--gold-rgb), 0.10), transparent 60%),
    /* secondary pool, bottom for balance */
    radial-gradient(ellipse 70% 40% at 50% 100%, rgba(var(--gold-rgb), 0.04), transparent 60%),
    /* leather darkening at the four corners */
    radial-gradient(ellipse 60% 60% at 0% 0%, rgba(0, 0, 0, 0.45), transparent 55%),
    radial-gradient(ellipse 60% 60% at 100% 0%, rgba(0, 0, 0, 0.45), transparent 55%),
    radial-gradient(ellipse 70% 70% at 0% 100%, rgba(0, 0, 0, 0.55), transparent 55%),
    radial-gradient(ellipse 70% 70% at 100% 100%, rgba(0, 0, 0, 0.55), transparent 55%),
    /* vertical "curtain" — soft dark folds spaced like velvet pleats */
    repeating-linear-gradient(
      to right,
      transparent 0,
      rgba(0, 0, 0, 0.13) 70px,
      transparent 140px
    ),
    /* vertical fall — top brighter, mid pooled, bottom darker */
    linear-gradient(180deg,
      rgba(0, 0, 0, 0) 0%,
      rgba(0, 0, 0, 0.10) 45%,
      rgba(0, 0, 0, 0.25) 100%);
}

/* — Marble — real black-marble photograph with gold veins. */
body[data-theme="marble"] {
  --ink: #07070a;
  --paper: #14141a;
  --line: #2a2a30;
  --gold: #d4a85e;
  --gold-bright: #f0c878;
  background-image: url("marble-background.png");
  background-color: var(--ink);
  background-attachment: fixed;
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
}

/* — Marble · Musical — same black marble but with an engraved gold
   treble clef and staves photographed into the surface. */
body[data-theme="marble-musical"] {
  --ink: #07070a;
  --paper: #14141a;
  --line: #2a2a30;
  --gold: #d4a85e;
  --gold-bright: #f0c878;
  background-image: url("marble-background-musical.png");
  background-color: var(--ink);
  background-attachment: fixed;
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
}

/* `background-attachment: fixed` on body forces full-document repaints on
   scroll and kills frame rates on mid-range phones. Marble themes still rely
   on it (single PNG, cheap to sample) — fall back to scrolling under 900px.
   Boudoir/Urtext don't appear here anymore: their gradients moved to a
   fixed `::after` pseudo with `translateZ(0)`, which gets its own compositor
   layer and isn't affected by scroll. */
@media (max-width: 900px) {
  body,
  body[data-theme="marble"],
  body[data-theme="marble-musical"] {
    background-attachment: scroll;
    position: relative; /* positioning context for ::before */
  }
  /* Urtext: the SVG turbulence grain blended with `mix-blend-mode: multiply`
     across the full document height repaints every scroll tile — drop it on
     mobile, the paper texture is barely noticeable on phone screens anyway. */
  body[data-theme="urtext"]::before {
    display: none;
  }
  /* Boudoir: even on the GPU-composited layer, 8 gradients are heavier to
     rasterize once than 2. Strip to just the warm pool + vertical fall —
     the look is preserved, the initial paint is cheaper. */
  body[data-theme="boudoir"]::after {
    background-image:
      radial-gradient(ellipse 90% 55% at 50% -10%, rgba(var(--gold-rgb), 0.10), transparent 60%),
      linear-gradient(180deg,
        rgba(0, 0, 0, 0) 0%,
        rgba(0, 0, 0, 0.10) 45%,
        rgba(0, 0, 0, 0.25) 100%);
  }
}
