/* =====================================================================
   kc-music-engine.css - shared styles + design tokens for the Music engine
   (assets/js/kc-music-engine.js) that all Music-page versions skin.

   NOTE: assets/kc-music.css belongs to the ten existing /music/ pages and is
   deliberately untouched; this file is the engine's own layer.

   THEMING. Tokens live on :root (light). Dark values apply when EITHER
   the site convention html[data-mode="batman"] OR the generic
   html[data-theme="dark"] is set; with neither attribute present the OS
   preference decides. A version page re-skins by overriding the --mus-*
   tokens; component rules below only ever reference tokens.

   The token VALUES are the SITE's design system (.wt-shell tokens in
   cdo-watchtower.css): warm-paper light bg #f7f4ee, green-charcoal dark bg
   #161a18, the standard button (deep green #2c5f4e in light mode, mint
   #8fd0b4 in dark mode) and the site focus color. A version that uses the
   engine tokens automatically matches the rest of KeepCalm.org.

   NO RED, EVER (owner mandate, flagged twice): the ONLY accent family is
   the site green #2c5f4e (light mode) / mint #8fd0b4 (dark mode). No hover,
   active, focus, like or "danger" state may paint red; --mus-danger exists
   for compatibility but carries the accent family. The poster red #da0000
   lives ONLY inside the 6-color poster ART palette (kc-music-engine.js),
   never as a UI accent.

   Contrast (checked): light ink #26302b on #f7f4ee = 11.8:1; dark ink
   #ece7dc on #161a18 = 13.6:1; buttons #fffdf9 on #2c5f4e = 7.0:1 and
   #10140f on #8fd0b4 = 11.4:1 (the site's own pairs). Poster art ink is
   fixed by the 6-color system (white design on the dark variants, black
   design on the light variants); tile text is white over a bottom scrim
   deep enough to clear 4.5:1 on the lightest gradient stop at the text
   band (legibility beats aesthetics).
   ===================================================================== */

:root {
  --mus-bg: #f7f4ee;              /* site --wt-page-bg, warm paper */
  --mus-surface: #fffdf9;         /* site --wt-surface */
  --mus-surface-2: #ede7da;       /* site --wt-chip-bg */
  --mus-ink: #26302b;             /* site --wt-ink */
  --mus-ink-soft: #475048;
  --mus-ink-quiet: #5f6a60;
  --mus-rule: #e4ddcf;
  --mus-accent: #2c5f4e;          /* site --wt-btn-bg (standard button) */
  --mus-accent-ink: #fffdf9;      /* site --wt-btn-ink */
  --mus-accent-hover: #1f4638;    /* site --wt-btn-bg-hover */
  --mus-focus: #2c5f4e;           /* site --kc-focus */
  --mus-danger: #2c5f4e;          /* red purged (owner): carries the accent */
  /* ON-ART tokens: song art in light mode is a DARK poster color, so the
     button that sits on it is the mint (dark-mode) site button, and the
     poster design ink is white. Dark mode reverses both. */
  --mus-art-accent: #8fd0b4;
  --mus-art-accent-ink: #10140f;
  --mus-art-ink: #ffffff;         /* poster design (crown + text) ink */
  /* ON-ART play button, resting state. Light mode art is a DARK poster color,
     so the disc is white and the arrow black. Alphas are not free: the arrow
     keeps 6.87:1 over the darkest family (black) and 8.16:1 over red. */
  --mus-artbtn-bg: rgba(255, 255, 255, 0.58);
  --mus-artbtn-ink: rgba(0, 0, 0, 0.88);
  --mus-artbtn-glow: 0 0 18px 2px rgba(0, 0, 0, 0.42);   /* glow: 0 offset, never directional */
  --mus-artbtn-ring: rgba(0, 0, 0, 0.14);
  --mus-tile-bg: #2c5f4e;         /* tile fallback: a family color, NEVER cream */
  --mus-tile-ink: #ffffff;        /* tile text: white over the bottom scrim */
  --mus-shadow: 0 10px 30px rgba(38, 48, 43, 0.18);
  --mus-radius: 14px;
  --mus-radius-sm: 8px;
  --mus-bar-h: 84px;
}
html[data-mode="batman"], html[data-theme="dark"] {
  --mus-bg: #161a18;              /* site dark --wt-page-bg, warm green-charcoal */
  --mus-surface: #1e2522;
  --mus-surface-2: rgba(143, 208, 180, 0.10);
  --mus-ink: #ece7dc;
  --mus-ink-soft: #c2cabb;
  --mus-ink-quiet: #93a093;
  --mus-rule: #2c342f;
  --mus-accent: #8fd0b4;          /* site dark button: soft mint */
  --mus-accent-ink: #10140f;
  --mus-accent-hover: #b9e7d1;
  --mus-focus: #8fd0b4;
  --mus-danger: #8fd0b4;          /* red purged (owner): carries the accent */
  --mus-art-accent: #2c5f4e;      /* on LIGHT art: the deep-green site button */
  --mus-art-accent-ink: #fffdf9;
  --mus-art-ink: #161616;         /* the poster BLACK design on the light variants */
  /* dark mode reverses the disc: art here is a LIGHT poster shade, so the disc
     is black and the arrow white. Arrow keeps 5.16:1 over the lightest family
     (black's white shade) and 7.19:1 at the next worst (green). */
  --mus-artbtn-bg: rgba(0, 0, 0, 0.60);
  --mus-artbtn-ink: rgba(255, 255, 255, 0.92);
  --mus-artbtn-glow: 0 0 18px 2px rgba(255, 255, 255, 0.30);
  --mus-artbtn-ring: rgba(255, 255, 255, 0.22);
  --mus-tile-bg: #2c5f4e;         /* tiles keep their assigned color in dark mode too */
  --mus-tile-ink: #ffffff;
  --mus-shadow: 0 10px 30px rgba(0, 0, 0, 0.55);
}
@media (prefers-color-scheme: dark) {
  html:not([data-mode]):not([data-theme]) {
    --mus-bg: #161a18;
    --mus-surface: #1e2522;
    --mus-surface-2: rgba(143, 208, 180, 0.10);
    --mus-ink: #ece7dc;
    --mus-ink-soft: #c2cabb;
    --mus-ink-quiet: #93a093;
    --mus-rule: #2c342f;
    --mus-accent: #8fd0b4;
    --mus-accent-ink: #10140f;
    --mus-accent-hover: #b9e7d1;
    --mus-focus: #8fd0b4;
    --mus-danger: #8fd0b4;
    --mus-art-accent: #2c5f4e;
    --mus-art-accent-ink: #fffdf9;
    --mus-art-ink: #161616;
    --mus-artbtn-bg: rgba(0, 0, 0, 0.60);
    --mus-artbtn-ink: rgba(255, 255, 255, 0.92);
    --mus-artbtn-glow: 0 0 18px 2px rgba(255, 255, 255, 0.30);
    --mus-artbtn-ring: rgba(255, 255, 255, 0.22);
    --mus-tile-bg: #2c5f4e;
    --mus-tile-ink: #ffffff;
    --mus-shadow: 0 10px 30px rgba(0, 0, 0, 0.55);
  }
}

/* ---------- shared primitives ---------- */
/* Visually hidden, still read by screen readers. position: fixed pins the
   1px clip box to the viewport origin so it can never land past the edge of
   a scroll container (an absolute box with no positioned ancestor could, and
   caused page-level horizontal scroll inside wide rails). */
.mus-sr {
  position: fixed; top: 0; left: 0; width: 1px; height: 1px;
  padding: 0; margin: 0; border: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* The [hidden] attribute always wins over engine display rules
   (.mus-btn and friends set display: inline-flex/flex/grid, which would
   otherwise override the UA's [hidden] { display: none }). */
[class^="mus-"][hidden], [class*=" mus-"][hidden] { display: none !important; }

.mus-btn {
  font: inherit; font-weight: 700; letter-spacing: 0.02em; cursor: pointer;
  padding: 11px 22px; border-radius: 999px; border: 0;
  background: var(--mus-accent); color: var(--mus-accent-ink);
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px;
}
.mus-btn svg { width: 18px; height: 18px; flex: 0 0 auto; }
.mus-btn:hover { background: var(--mus-accent-hover); }
.mus-btn:focus-visible { outline: 3px solid var(--mus-focus); outline-offset: 2px; }
.mus-btn[disabled] { opacity: 0.55; cursor: default; }
.mus-btn--ghost { background: transparent; color: var(--mus-ink); border: 1.5px solid var(--mus-rule); }
.mus-btn--ghost:hover { background: transparent; border-color: var(--mus-ink-soft); }

.mus-iconbtn {
  font: inherit; cursor: pointer; border: 1.5px solid var(--mus-rule);
  background: var(--mus-surface); color: var(--mus-ink-soft);
  width: 40px; height: 40px; border-radius: 50%; padding: 0;
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
}
.mus-iconbtn svg { width: 18px; height: 18px; }
.mus-iconbtn:hover { color: var(--mus-ink); border-color: var(--mus-ink-soft); }
.mus-iconbtn:focus-visible { outline: 3px solid var(--mus-focus); outline-offset: 2px; }
.mus-iconbtn[disabled] { opacity: 0.4; cursor: default; }
/* liked hearts fill with the site accent (green/mint), NEVER red */
.mus-like.is-on, .mus-like[aria-pressed="true"] { color: var(--mus-accent); border-color: currentColor; }

.mus-playbtn {
  font: inherit; cursor: pointer; border: 0; padding: 0;
  background: var(--mus-accent); color: var(--mus-accent-ink);
  width: 48px; height: 48px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
  box-shadow: var(--mus-shadow);
}
.mus-playbtn svg { width: 22px; height: 22px; }
.mus-playbtn:hover { background: var(--mus-accent-hover); }
.mus-playbtn:focus-visible { outline: 3px solid var(--mus-focus); outline-offset: 2px; }

/* ---------- the ON-ART play button (every thumbnail) ----------
   Kaʻo's spec, Apple's pattern: translucent and backdrop-blurred at rest so the
   art reads through the disc, turning FULL-opacity green on its own hover, and
   carrying a constant glow (dark in light mode, bright in dark mode) that is a
   glow and not a directional shadow.
   The glow does real work and is not decoration: the disc over RED art is only
   2.35:1 against the raw art, under the 3:1 floor. The halo is what the eye
   meets at the disc edge, and it carries that boundary to 4.93:1 (worst case,
   red). Measured, all six families, both modes: arrow-on-disc >= 5.16:1,
   disc-on-halo >= 4.93:1, focus-ring-on-art >= 5.27:1, arrow-on-green >= 7.24:1.
   Recompute all four if an alpha or a family color changes.
   ONE copy lives here and both the engine's cards and v17's cards wear it; the
   card rules below only POSITION it (they differ, 44px vs 42px). Do not fork
   the appearance back into either file. */
.mus-playbtn--art {
  background: var(--mus-artbtn-bg);
  color: var(--mus-artbtn-ink);
  /* blur ONLY, deliberately no saturate(): saturate pulls the family color up
     through the veil and the disc stops being the WHITE (light) / BLACK (dark)
     circle Kaʻo asked for, going green-on-green and pink-on-red. It also
     invalidates the contrast numbers above, which model a plain alpha
     composite. Blurring a flat poster color returns the same color, so with
     blur alone those numbers hold as rendered. */
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  box-shadow: var(--mus-artbtn-glow), inset 0 0 0 1px var(--mus-artbtn-ring);
}
/* hover/focus: full opacity, the site accent for whatever is UNDER it (mint on
   the dark posters, deep green on the light ones) = his "light green" in light
   mode and "dark green" in dark mode. 10.5:1 / 7.3:1 arrow on green. */
.mus-playbtn--art:hover, .mus-playbtn--art:focus-visible {
  background: var(--mus-art-accent);
  color: var(--mus-art-accent-ink);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
/* the site focus ring is the accent, which is INVISIBLE on same-family art
   (deep green on a deep green poster). The art ink always contrasts with both
   the art and the accent: 5.3:1+ light, 8.7:1+ dark. */
.mus-playbtn--art:focus-visible { outline-color: var(--mus-art-ink); }

/* ---------- equalizer-in-a-play-button (the PLAYING state) ----------
   Reusable dancing bars for a play FAB while its track plays (drop in via
   KCMusicEngine.EQ_ICO). Self-contained: the markup exists only while playing,
   so the bars animate unconditionally, no JS or audio wiring. scaleY (not
   height) keeps it GPU-cheap and off the layout path. Bars inherit currentColor
   so they read on the translucent art disc and the green hover state, both
   themes. Reduced motion freezes them at a legible mid height. */
.mus-eq { display: inline-flex; align-items: flex-end; gap: 2.5px; width: 20px; height: 18px; }
.mus-eq i {
  flex: 0 0 auto; width: 3px; height: 100%; border-radius: 2px;
  background: currentColor; transform-origin: bottom; transform: scaleY(0.3);
  animation: mus-eq 0.9s ease-in-out infinite alternate;
}
.mus-eq i:nth-child(1) { animation-duration: 1s; animation-delay: -0.2s; }
.mus-eq i:nth-child(2) { animation-duration: 0.75s; animation-delay: -0.5s; }
.mus-eq i:nth-child(3) { animation-duration: 1.15s; animation-delay: -0.1s; }
.mus-eq i:nth-child(4) { animation-duration: 0.85s; animation-delay: -0.35s; }
@keyframes mus-eq { from { transform: scaleY(0.28); } to { transform: scaleY(1); } }
/* reduced motion: no dancing, but a varied static shape still reads as an
   equalizer rather than a flat row of equal bars */
@media (prefers-reduced-motion: reduce) {
  .mus-eq i { animation: none; }
  .mus-eq i:nth-child(1) { transform: scaleY(0.5); }
  .mus-eq i:nth-child(2) { transform: scaleY(0.85); }
  .mus-eq i:nth-child(3) { transform: scaleY(0.4); }
  .mus-eq i:nth-child(4) { transform: scaleY(0.7); }
}

.mus-input {
  font: inherit; font-size: 1rem; color: var(--mus-ink);
  background: var(--mus-surface); border: 1.5px solid var(--mus-rule);
  border-radius: 999px; padding: 11px 16px; min-height: 44px; min-width: 0;
}
.mus-input::placeholder { color: var(--mus-ink-quiet); }
.mus-input:focus-visible { outline: 3px solid var(--mus-focus); outline-offset: 1px; border-color: var(--mus-focus); }

.mus-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.mus-chip {
  font: inherit; font-size: 0.88rem; font-weight: 600; cursor: pointer;
  color: var(--mus-ink-soft); background: var(--mus-surface);
  border: 1.5px solid var(--mus-rule); border-radius: 999px; padding: 8px 15px; min-height: 38px;
}
.mus-chip:hover { color: var(--mus-ink); border-color: var(--mus-ink-soft); }
.mus-chip:focus-visible { outline: 3px solid var(--mus-focus); outline-offset: 2px; }
.mus-chip.is-on { background: var(--mus-ink); color: var(--mus-bg); border-color: var(--mus-ink); }

.mus-empty, .mus-drawer__empty { color: var(--mus-ink-soft); padding: 14px 0; }

/* ---------- poster art: the STRICT 6-color, mode-flipped system ----------
   kc-music-engine.js snaps every track color to one of the 6 poster
   families and writes the pair onto the host as --mus-art-dark /
   --mus-art-light. These rules decide WHICH variant paints:
     site LIGHT mode -> the DARK variant + WHITE design (the classic poster)
     site DARK  mode -> the LIGHT variant + BLACK design (the wall's
                        dark-mode shades, locked Option 1 2026-06-14)
   A black design can never land on a dark background: the variant and the
   ink flip together, in CSS, so a live theme toggle restyles every poster. */
/* Fallbacks (family vars missing) are the NEUTRAL family: pure black
   #161616 in light mode, pure white #ffffff in dark mode - never cream or
   any off-white, and the strict flip still holds. */
.mus-crownart, .mus-poster {
  --mus-art-fill: var(--mus-art-dark, #161616);
  --mus-crown-w: inline;   /* white crown shows with the white design */
  --mus-crown-b: none;
}
html[data-mode="batman"] .mus-crownart, html[data-theme="dark"] .mus-crownart,
html[data-mode="batman"] .mus-poster, html[data-theme="dark"] .mus-poster {
  --mus-art-fill: var(--mus-art-light, #ffffff);
  --mus-crown-w: none;
  --mus-crown-b: inline;
}
@media (prefers-color-scheme: dark) {
  html:not([data-mode]):not([data-theme]) .mus-crownart,
  html:not([data-mode]):not([data-theme]) .mus-poster {
    --mus-art-fill: var(--mus-art-light, #ffffff);
    --mus-crown-w: none;
    --mus-crown-b: inline;
  }
}
.mus-art__bg { fill: var(--mus-art-fill); }
.mus-art__tx { fill: var(--mus-art-ink); }
.mus-art__cw { display: var(--mus-crown-w, inline); }
.mus-art__cb { display: var(--mus-crown-b, none); }

/* ---------- crown art (the square cover = the real poster) ---------- */
.mus-crownart {
  position: relative; display: block; width: 100%; aspect-ratio: 1 / 1;
  border-radius: var(--mus-radius-sm); overflow: hidden; flex: 0 0 auto;
  background: var(--mus-art-fill);
  /* hairline so the white/black covers stay visible on either surface */
  box-shadow: inset 0 0 0 1px rgba(128, 128, 128, 0.22);
}
.mus-crownart .mus-art { display: block; width: 100%; height: 100%; }
.mus-crownart--round { border-radius: 50%; }
.mus-crownart__mark {
  /* 62% (was 46%): the crown reads too small inside the creator circle
     (owner). Crown aspect 1.246:1 -> ~50% tall, still clear of the circle
     edge; the strict mode flip (dark circle + white crown in light mode,
     light circle + black crown in dark mode) is untouched. */
  position: absolute; left: 50%; top: 50%; width: 62%; aspect-ratio: 1.246 / 1;
  transform: translate(-50%, -50%);
  background: var(--mus-art-ink);
  -webkit-mask: url("/assets/logos/keepcalm-crown-white.svg?v=20260720") no-repeat center / contain;
  mask: url("/assets/logos/keepcalm-crown-white.svg?v=20260720") no-repeat center / contain;
}
/* empty placeholder inherits the neutral art fill (pure black / pure white
   via the fallback above) + the flipped design ink - never cream */
.mus-crownart--empty { display: inline-flex; align-items: center; justify-content: center; color: var(--mus-art-ink); }
.mus-crownart--empty svg { width: 40%; height: 40%; }

/* ---------- the actual poster (lockup SVG box) ---------- */
.mus-poster { display: block; width: 100%; line-height: 0; border-radius: var(--mus-radius-sm); overflow: hidden; background: var(--mus-art-fill); }
.mus-poster svg { width: 100%; height: auto; display: block; }

/* ---------- poster hover / focus overlay (loop video) ---------- */
.mus-hoverposter {
  position: absolute; inset: 0; z-index: 3;
  opacity: 0; pointer-events: none;
  transition: opacity 0.18s ease;
  display: flex; align-items: center; justify-content: center;
  /* clip the loop video to the SAME rounded corners as the poster art
     (.mus-crownart / .mus-poster) so hovering never squares off the tile */
  border-radius: var(--mus-radius-sm); overflow: hidden;
}
.mus-hoverposter.is-on { opacity: 1; pointer-events: auto; }
.mus-hoverposter__link { display: block; width: 100%; height: 100%; position: relative; }
.mus-hoverposter__link:focus-visible { outline: 3px solid var(--mus-focus); outline-offset: -3px; border-radius: var(--mus-radius-sm); }
/* the crossfaded loop clip is vertical 3:4. SITE RULE (Kaʻo 2026-07-21):
   portrait loop clips rendered SQUARE keep the BOTTOM square of the frame
   (crop the top) so people in the clips keep their heads. */
.mus-hovervid {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: bottom center;
  background: transparent;
  /* radius on the video itself too: Safari won't always clip a composited
     video through the parent's overflow: hidden */
  border-radius: var(--mus-radius-sm);
}
.mus-hoverposter .mus-poster { height: 100%; }
.mus-hoverposter .mus-poster svg { height: 100%; object-fit: cover; }
@media (prefers-reduced-motion: reduce) { .mus-hoverposter { transition: none; } }
/* ---------- hover = a MINI POSTER BACK, not a bare video ----------
   Layers inside the overlay link, bottom to top: the loop video, this scrim,
   the crown+phrase design (the play button, z-index 4, stays on top). The
   scrim values are the card backs' locked single source of truth
   (cdo-watchtower.css .kc-bc__scrim, /overlay-darkness review): LIGHT mode =
   black at 30% under the WHITE design; DARK mode = white at 60% under the
   BLACK design (same reversal as .kc-tone-dark). The design ink + crown
   variant ride the same --mus-art-* vars as every poster, so the mode flip
   stays contrast-safe and toggles live with the theme. */
.mus-hoverposter__scrim { position: absolute; inset: 0; pointer-events: none; background: rgba(0, 0, 0, 0.3); }
html[data-mode="batman"] .mus-hoverposter__scrim, html[data-theme="dark"] .mus-hoverposter__scrim { background: rgba(255, 255, 255, 0.6); }
@media (prefers-color-scheme: dark) {
  html:not([data-mode]):not([data-theme]) .mus-hoverposter__scrim { background: rgba(255, 255, 255, 0.6); }
}
/* the design layer is the normal square crown art with its solid fill and
   hairline stripped, so ONLY the crown + words sit over the scrimmed video */
.mus-crownart.mus-hoverposter__design {
  position: absolute; inset: 0; height: 100%;
  background: transparent; box-shadow: none; pointer-events: none;
}
.mus-hoverposter__design .mus-art__bg { fill: transparent; }

/* ---------- non-song tiles (playlists / mixes / stations / replay) ----------
   TWO treatments, per the owner (round-3b + mood correction):

   1. .mus-tile - the tile paints its ASSIGNED poster color (inline, from
      kc-music-engine.js; never cream). The BIG crown watermark is OFFSET TO
      THE RIGHT and cropped by the right edge (and by top + bottom), filling
      most of the tile height, painted as a same-hue TINT of the tile color
      (the family's light shade, inline from JS - never flat gray) at 20%
      opacity. A bottom scrim (below) keeps the title + subtitle legible.
   2. .mus-tile--mood (FIND YOUR MOOD) - its own slicker look: a dramatic
      vivid gradient (inline, from kc-music-engine.js) with a SMALL white
      crown pinned top-right, never the big cropped crown. Same scrim.

   Tile text is always white. The scrim is deep on purpose: legibility beats
   aesthetics (measured: at the text band, worst alpha 0.57 over the
   lightest gradient stop #ffd23f still clears 4.5:1 for white text). */
.mus-tile {
  font: inherit; text-align: left; text-decoration: none; cursor: pointer;
  position: relative; overflow: hidden; box-sizing: border-box;
  display: flex; align-items: flex-end;
  width: 100%; aspect-ratio: 1 / 1; padding: 12px;
  background: var(--mus-tile-bg); color: var(--mus-tile-ink);
  border: 0; border-radius: var(--mus-radius);
}
div.mus-tile { cursor: default; }
a.mus-tile:hover, button.mus-tile:hover { filter: brightness(1.08); }
.mus-tile:focus-visible { outline: 3px solid var(--mus-focus); outline-offset: 2px; }
/* the bottom scrim: dark -> transparent so the text always wins.
   0.65 at the foot, not 0.85: the deeper ramp read as a black band. */
.mus-tile::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.65), rgba(0, 0, 0, 0.38) 50%, rgba(0, 0, 0, 0) 78%);
}
.mus-tile__crown {
  position: absolute; pointer-events: none; z-index: 0;
  height: 130%; aspect-ratio: 1.246 / 1; top: -15%; left: auto; right: -40%;
  background: #ffffff; /* overridden inline with the family's light tint */
  /* opacity is set INLINE per family by tile(): a single value cannot look
     the same on all six. At a flat 0.2 the crown measured 1.10 contrast on
     red but 1.88 on black, so red read washed out and black read stark.
     Each family now carries the alpha that lands it on green's 1.405. */
  opacity: 0.2;
  -webkit-mask: url("/assets/logos/keepcalm-crown-white.svg?v=20260720") no-repeat center / contain;
  mask: url("/assets/logos/keepcalm-crown-white.svg?v=20260720") no-repeat center / contain;
}
/* Re-assert the tile ink ON THE TEXT, not just on .mus-tile.
   Tiles are always a DARK family color (or a dark mood gradient) with a
   0.85 black scrim behind this text, so the ink is white in BOTH themes.
   .mus-tile already sets color:var(--mus-tile-ink), but every version scopes
   `.xx-app a { color: inherit }` to kill link-purple, and that selector
   (0,1,1) outranks .mus-tile (0,1,0). Tiles render as <a>, so they inherited
   the site's ink instead: dark-on-dark at 1.1:1 in light mode, which made
   these titles unreadable. Setting it here beats that inheritance. */
.mus-tile__meta { position: relative; z-index: 2; display: flex; flex-direction: column; gap: 2px; min-width: 0; color: var(--mus-tile-ink); }
.mus-tile__title { font-weight: 800; font-size: 1.05rem; line-height: 1.2; }
.mus-tile__sub { font-weight: 600; font-size: 0.78rem; }
.mus-tile__title, .mus-tile__sub { text-shadow: 0 1px 6px rgba(0, 0, 0, 0.55); }
/* .mus-tile__tag - the retired "MUSIC" badge, kept for future podcasts:
.mus-tile__tag {
  position: relative; z-index: 2; align-self: flex-start;
  font-size: 0.62rem; font-weight: 800; letter-spacing: 0.08em;
  padding: 3px 6px; border-radius: 7px;
  background: rgba(0, 0, 0, 0.45); color: #ffffff;
}
*/
.mus-tile--mood { border: 0; }
.mus-tile--mood .mus-tile__crown {
  height: 30%; top: 9%; right: 9%; left: auto;
  background: #ffffff; opacity: 0.9;
}

/* the FIND YOUR MOOD row: a scrollable rail of gradient tiles */
.mus-moodrail {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(140px, 180px);
  gap: 14px; overflow-x: auto; padding: 4px 2px 12px; scroll-snap-type: x proximity;
}
.mus-moodrail > * { scroll-snap-align: start; }

/* ---------- reference track card ---------- */
.mus-grid {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.mus-rail {
  display: grid; grid-auto-flow: column; grid-auto-columns: 168px; gap: 14px;
  overflow-x: auto; padding: 4px 2px 12px; scroll-snap-type: x proximity;
}
.mus-rail > * { scroll-snap-align: start; }
.mus-card {
  background: var(--mus-surface); border: 1px solid var(--mus-rule);
  border-radius: var(--mus-radius); padding: 10px;
  display: flex; flex-direction: column; gap: 7px; position: relative;
  transition: transform 0.15s ease, border-color 0.15s ease;
}
.mus-card:hover { transform: translateY(-2px); border-color: var(--mus-ink-soft); }
.mus-card.is-current { border-color: var(--mus-accent); box-shadow: 0 0 0 2px var(--mus-accent); }
.mus-card__art { position: relative; }
/* POSITION only: the look is .mus-playbtn--art in the shared block above */
.mus-card__play {
  position: absolute; right: 8px; bottom: 8px; z-index: 4;
  width: 44px; height: 44px; opacity: 0; transform: translateY(6px);
  transition: opacity 0.16s ease, transform 0.16s ease, background 0.16s ease, color 0.16s ease;
}
.mus-card:hover .mus-card__play, .mus-card:focus-within .mus-card__play,
.mus-card.is-playing .mus-card__play { opacity: 1; transform: none; }
@media (hover: none) { .mus-card__play { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .mus-card, .mus-card__play { transition: none; } .mus-card:hover { transform: none; } }
.mus-card__title { font-size: 0.92rem; font-weight: 700; color: var(--mus-ink); margin: 2px 0 0; line-height: 1.25; }
.mus-card__creator { font-size: 0.82rem; color: var(--mus-ink-quiet); text-decoration: none; }
.mus-card__creator:hover { color: var(--mus-ink); text-decoration: underline; }
.mus-card__creator:focus-visible { outline: 3px solid var(--mus-focus); outline-offset: 2px; border-radius: 4px; }
.mus-card__row { display: flex; align-items: center; gap: 6px; margin-top: auto; }
.mus-card__row .mus-iconbtn { width: 36px; height: 36px; }
.mus-card__plays { margin-left: auto; font-size: 0.78rem; color: var(--mus-ink-quiet); }

/* ---------- creator page header ---------- */
.mus-creatorhd { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; margin: 8px 0 22px; }
.mus-creatorhd__avatar { width: 108px; }
.mus-creatorhd__name { font-size: 1.5rem; margin: 0; color: var(--mus-ink); }
.mus-creatorhd__user { margin: 2px 0 4px; color: var(--mus-ink-quiet); }
.mus-creatorhd__stats { margin: 0 0 12px; color: var(--mus-ink-soft); font-size: 0.92rem; }

/* ---------- persistent bottom now-playing bar ---------- */
/* Engine z-index map, ABOVE the site chrome (site mini header 1100, site
   drawer 1250): now-playing bar 1290 < popover 1330 < drawer 1340 < toast
   1350. Everything else in this file uses small local indexes (0-4) inside
   their own positioned cards/tiles/overlays and never competes with these. */
html.kc-has-musicbar body { padding-bottom: calc(var(--mus-bar-h) + env(safe-area-inset-bottom, 0px) + 12px); }
.mus-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 1290;
  box-sizing: border-box; /* --mus-bar-h measures the rendered box, padding and border included */
  min-height: var(--mus-bar-h);
  padding: 10px 14px calc(10px + env(safe-area-inset-bottom, 0px));
  background: var(--mus-surface); color: var(--mus-ink);
  border-top: 1px solid var(--mus-rule); box-shadow: var(--mus-shadow);
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) auto;
  align-items: center; gap: 14px;
}
.mus-bar__left { display: flex; align-items: center; gap: 10px; min-width: 0; }
.mus-bar__artlink { position: relative; display: block; width: 52px; flex: 0 0 auto; border-radius: var(--mus-radius-sm); }
.mus-bar__artlink:focus-visible { outline: 3px solid var(--mus-focus); outline-offset: 2px; }
.mus-bar__meta { display: flex; flex-direction: column; min-width: 0; }
.mus-bar__title { font-weight: 700; font-size: 0.92rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mus-bar__creator { font-size: 0.8rem; color: var(--mus-ink-quiet); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mus-bar__creator:hover { color: var(--mus-ink); text-decoration: underline; }
.mus-bar__creator:focus-visible { outline: 3px solid var(--mus-focus); outline-offset: 2px; border-radius: 4px; }
.mus-bar__center { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 0; }
.mus-bar__tx { display: flex; align-items: center; gap: 10px; }
.mus-bar__play { width: 44px; height: 44px; }
.mus-bar__scrub { display: flex; align-items: center; gap: 10px; width: 100%; max-width: 560px; }
.mus-bar__time { font-size: 0.76rem; color: var(--mus-ink-quiet); font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.mus-bar__range { flex: 1 1 auto; min-width: 0; accent-color: var(--mus-accent); height: 24px; cursor: pointer; background: transparent; }
.mus-bar__range:focus-visible { outline: 3px solid var(--mus-focus); outline-offset: 2px; border-radius: 4px; }
.mus-bar__right { display: flex; align-items: center; gap: 12px; }
.mus-bar__eq { display: inline-flex; align-items: flex-end; gap: 3px; height: 20px; width: 18px; }
.mus-bar__eq i { width: 4px; height: 14%; border-radius: 2px; background: var(--mus-accent); transition: height 0.05s linear; }
.mus-bar:not(.is-playing) .mus-bar__eq { opacity: 0.25; }
@media (prefers-reduced-motion: reduce) { .mus-bar__eq { display: none; } }
@media (max-width: 720px) {
  :root { --mus-bar-h: 118px; }
  .mus-bar { grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto auto; row-gap: 6px; }
  .mus-bar__left { grid-column: 1; grid-row: 1; }
  .mus-bar__right { grid-column: 2; grid-row: 1; }
  .mus-bar__center { grid-column: 1 / -1; grid-row: 2; }
}

/* ---------- add-to-playlist popover ---------- */
.mus-pop {
  position: fixed; z-index: 1330; background: var(--mus-surface); color: var(--mus-ink);
  border: 1px solid var(--mus-rule); border-radius: var(--mus-radius);
  box-shadow: var(--mus-shadow); overflow: hidden;
}
.mus-pop__list { display: flex; flex-direction: column; max-height: 60vh; overflow-y: auto; padding: 6px; }
.mus-pop__item {
  font: inherit; font-size: 0.92rem; cursor: pointer; text-align: left;
  background: none; border: 0; color: var(--mus-ink);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 11px 12px; border-radius: var(--mus-radius-sm); min-height: 44px;
}
.mus-pop__item:hover { background: var(--mus-surface-2); }
.mus-pop__item:focus-visible { outline: 3px solid var(--mus-focus); outline-offset: -3px; }
.mus-pop__item svg { width: 17px; height: 17px; flex: 0 0 auto; }
.mus-pop__item--new { font-weight: 700; justify-content: flex-start; }
.mus-pop__form { display: flex; gap: 8px; padding: 8px; }
.mus-pop__form .mus-input { flex: 1 1 auto; }

/* ---------- playlists drawer ---------- */
.mus-drawer { position: fixed; inset: 0; z-index: 1340; }
.mus-drawer__scrim { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.45); }
.mus-drawer__panel {
  position: absolute; top: 0; right: 0; bottom: 0; width: min(420px, 92vw);
  background: var(--mus-bg); color: var(--mus-ink);
  border-left: 1px solid var(--mus-rule); box-shadow: var(--mus-shadow);
  display: flex; flex-direction: column; overflow-y: auto;
}
.mus-drawer__hd {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px; border-bottom: 1px solid var(--mus-rule);
  position: sticky; top: 0; background: var(--mus-bg); z-index: 1;
}
.mus-drawer__hd h2 { font-size: 1.05rem; margin: 0; flex: 1 1 auto; }
.mus-drawer__body { padding: 14px 16px calc(20px + var(--mus-bar-h)); display: flex; flex-direction: column; gap: 10px; }
.mus-drawer__note { font-size: 0.85rem; color: var(--mus-ink-soft); margin: 0 0 4px; }
.mus-drawer__note a { color: var(--mus-ink); }
.mus-drawer__acts { display: flex; flex-wrap: wrap; gap: 8px; }
.mus-plrow {
  font: inherit; cursor: pointer; text-align: left;
  display: flex; align-items: center; gap: 12px;
  background: var(--mus-surface); border: 1px solid var(--mus-rule);
  border-radius: var(--mus-radius); padding: 10px; color: var(--mus-ink);
}
.mus-plrow:hover { border-color: var(--mus-ink-soft); }
.mus-plrow:focus-visible { outline: 3px solid var(--mus-focus); outline-offset: 2px; }
.mus-plrow .mus-crownart { width: 52px; }
.mus-plrow__meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.mus-plrow__meta strong { font-size: 0.95rem; }
.mus-plrow__meta span { font-size: 0.8rem; color: var(--mus-ink-quiet); }
.mus-drawer__rows { display: flex; flex-direction: column; gap: 6px; }
.mus-plsong {
  display: flex; align-items: center; gap: 10px;
  background: var(--mus-surface); border: 1px solid var(--mus-rule);
  border-radius: var(--mus-radius-sm); padding: 8px 10px;
}
.mus-plsong__n { font-size: 0.8rem; color: var(--mus-ink-quiet); width: 20px; text-align: right; flex: 0 0 auto; font-variant-numeric: tabular-nums; }
.mus-plsong__t { flex: 1 1 auto; min-width: 0; font-size: 0.9rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mus-plsong__acts { display: inline-flex; gap: 4px; }
.mus-plsong__acts .mus-iconbtn { width: 34px; height: 34px; }
.mus-plsong__acts .mus-iconbtn svg { width: 15px; height: 15px; }

/* ---------- toast ---------- */
.mus-toast {
  position: fixed; left: 50%; bottom: calc(var(--mus-bar-h) + 18px); z-index: 1350;
  transform: translate(-50%, 8px); opacity: 0; pointer-events: none;
  background: var(--mus-ink); color: var(--mus-bg);
  font-size: 0.9rem; font-weight: 600; padding: 10px 18px; border-radius: 999px;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.mus-toast.is-on { opacity: 1; transform: translate(-50%, 0); }
@media (prefers-reduced-motion: reduce) { .mus-toast { transition: none; } }

/* ---------- in-page dialog (our prompt/confirm, never the native one) ----------
   Sits above every engine layer (drawer 1340, toast 1350). Backdrop dims the
   page; the panel is the site surface with AA ink. Danger action carries the
   accent, not red (owner: no red UI). */
.mus-dialog {
  position: fixed; inset: 0; z-index: 1360;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  background: rgba(20, 24, 22, 0.55);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.mus-dialog__panel {
  width: min(420px, 100%); background: var(--mus-surface); color: var(--mus-ink);
  border: 1px solid var(--mus-rule); border-radius: var(--mus-radius);
  box-shadow: var(--mus-shadow); padding: 22px;
}
.mus-dialog__title { font-size: 1.15rem; font-weight: 800; margin: 0 0 6px; color: var(--mus-ink); }
.mus-dialog__msg { font-size: 0.92rem; color: var(--mus-ink-soft); margin: 0 0 14px; line-height: 1.45; }
.mus-dialog__form { margin: 4px 0 0; }
.mus-dialog__input { width: 100%; margin: 4px 0 0; }
.mus-dialog__actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 18px; }
/* "danger" (Delete) keeps the accent family, never red, and stays AA on it */
.mus-btn--danger { background: var(--mus-accent); color: var(--mus-accent-ink); }
.mus-btn--danger:hover { background: var(--mus-accent-hover); }
@media (prefers-reduced-motion: no-preference) {
  .mus-dialog__panel { animation: mus-dialog-in 0.16s ease; }
  @keyframes mus-dialog-in { from { opacity: 0; transform: translateY(6px) scale(0.99); } to { opacity: 1; transform: none; } }
}

/* the "..." share menu popover (Share / Copy Link / Copy Embed Code). Apple-
   style: every row carries an icon then a label. Fixed, positioned by JS under
   its anchor; above the bar/toast but below a dialog. */
.mus-menu {
  position: fixed; z-index: 1355; min-width: 196px;
  background: var(--mus-surface); color: var(--mus-ink);
  border: 1px solid var(--mus-rule); border-radius: 12px;
  box-shadow: var(--mus-shadow); padding: 6px;
}
.mus-menu__item {
  display: flex; align-items: center; gap: 11px; width: 100%; text-align: left; cursor: pointer;
  font: inherit; font-size: 0.9rem; font-weight: 600; color: var(--mus-ink);
  background: none; border: 0; padding: 10px 12px; border-radius: 8px;
}
.mus-menu__item svg { width: 18px; height: 18px; flex: 0 0 auto; color: var(--mus-ink-quiet); }
.mus-menu__item:hover { background: var(--mus-surface-2); }
.mus-menu__item:hover svg { color: var(--mus-ink); }
.mus-menu__item:focus-visible { outline: 3px solid var(--mus-focus); outline-offset: -2px; }
.mus-menu__item:focus-visible svg { color: var(--mus-ink); }
@media (prefers-reduced-motion: no-preference) {
  .mus-menu { animation: mus-dialog-in 0.14s ease; }
}

/* ---------- touch targets ----------
   On touch devices and small screens every engine control meets the 44px
   minimum: bar prev/next, like and add-to-playlist (all .mus-iconbtn,
   including the 36px card-row and 34px drawer-song variants) and chips.
   Icon sizes inside stay as they are. Kept last in the file so it wins the
   equal-specificity variants above. */
@media (hover: none), (max-width: 720px) {
  .mus-iconbtn,
  .mus-card__row .mus-iconbtn,
  .mus-plsong__acts .mus-iconbtn {
    width: 44px; height: 44px; min-width: 44px; min-height: 44px;
  }
  .mus-chip { min-height: 44px; }
}

/* ---- title-row Create button (Posters + Music homes) ----
   Sits on the lockup's plane, right-aligned; the one prominent creation
   entry point Kaʻo asked for on both browsing homes. */
.am-hdrow { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.am-hdrow .am-h1 { margin-bottom: 0; }
/* the .am-app a / .pa-app a "color: inherit" rules outrank a bare class, so the
   button selectors carry the app scopes too; colors come from the per-mode
   accent tokens (dark mode is mint with near-black ink, never white-on-mint) */
a.am-create-btn, .am-app a.am-create-btn, .pa-app a.am-create-btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 11px 20px; border-radius: 999px;
  background: var(--mus-accent); color: var(--mus-accent-ink);
  font-weight: 700; font-size: 14.5px; text-decoration: none;
  white-space: nowrap; box-shadow: 0 1px 2px rgba(0, 0, 0, .12);
}
a.am-create-btn:hover, .am-app a.am-create-btn:hover, .pa-app a.am-create-btn:hover { background: var(--mus-accent-hover); }
.am-create-btn:focus-visible { outline: 3px solid var(--mus-ink); outline-offset: 2px; }
.am-create-btn__plus { font-size: 17px; line-height: 1; font-weight: 800; }
