/* ky-pulse — the Pulse Pill's stylesheet. Pairs with ky/ky-pulse.js and
   REPLACES ky/ky-island.css (the integrator removes that link and the
   ky-island.js tag; this module owns the collapsed state from then on).
   ===========================================================================
   COEXISTS WITH ky-music.css, never forks it: the expanded row is that file's
   (02)–(09) untouched. This file adds only (a) the --kyp-* token contract,
   (b) the two-layer shell (canvas + collapsed face over the existing row),
   (c) the deletions the spec calls for — .kym-art and the old collapsed puck
   are display:none'd HERE rather than edited out of files this module does
   not own.

   GEOMETRY IS WRITTEN BY THE JS, per frame, onto #ky-music's own element
   style — never :root (measured on this page: 7.675ms per root custom-prop
   write vs 0.025ms scoped). This sheet therefore declares REST dimensions as
   tokens for the JS to resolve (probe trick, on resize only) and must kill
   ky-music.css's `transition:width .5s`, which would smear every per-frame
   width write into a lag that never catches up.

   COLOUR LAW (same as ky-music.css): every colour mixes from the theme's own
   fg/bg pair, so all themes work with zero per-theme CSS. Theme packs may
   override any --kyp-* token on html. Contrast, computed with contrast.py
   (the repo's one luminance source): bars-on-surface 14.44:1 Honey & Ink,
   16.35:1 Noir; chevron rest (62% ink on surface) 7.44:1 Honey & Ink — past
   the 3:1 UI floor everywhere the theme's own text passes 4.5:1, because the
   pair IS the theme's text pair.

   Numbering is parenthetical, (01)…(07), like the rest of the site. */

/* ── (01) token contract ─────────────────────────────────────────────── */
html[data-glass] #ky-music{
  --kyp-ink:    var(--color-foreground, #14110A);
  --kyp-plate:  color-mix(in srgb, var(--color-background, #F7EDD3) 92%, transparent);
  --kyp-bar:    var(--kyp-ink);                                    /* canvas-read */
  --kyp-wave:   color-mix(in srgb, var(--kyp-ink) 45%, transparent); /* canvas-read */
  --kyp-accent: var(--color-accent-600, var(--kyp-ink));           /* canvas-read */
  --kyp-muted:  color-mix(in srgb, var(--kyp-ink) 62%, transparent);
  --kyp-glow:   0;      /* 0..1, canvas-read — dark theme packs set ~0.6 */
  --kyp-amp:    1;      /* 0.6..1.4, canvas-read — idle/procedural amplitude */
  --kyp-speed:  1;      /* 0.6..1.4, canvas-read — procedural time rates */
  --kyp-w-pill: 148px;
  --kyp-h-pill: 44px;
  --kyp-r-pill: 22px;
  /* the expanded box defers to ky-music.css's own tokens so every breakpoint
     in that file stays authoritative — this sheet never re-states them */
  --kyp-w-bar:  var(--kym-w, min(640px, 100vw - 120px));
  --kyp-h-bar:  60px;
  --kyp-r-bar:  var(--kym-r, 30px);
  --kyp-ease:   cubic-bezier(.51,.92,.24,1.15);
  --kyp-press:  60ms cubic-bezier(.2,.9,.3,1);
}
@media (max-width:680px){
  html[data-glass] #ky-music{
    --kyp-w-pill:132px; --kyp-h-pill:40px; --kyp-r-pill:20px; --kyp-h-bar:54px;
  }
}
/* dark themes glow. Keyed off data-glass-lum — the same luminance probe the
   inline switcher stamps for liquid-glass.css — so all five dark classics
   (Noir/Cobalt/Lime/Ultraviolet/Ember) light up with zero per-theme CSS, and
   any experience pack re-stamping the attribute inherits the right answer. */
html[data-glass][data-glass-lum="dark"] #ky-music{--kyp-glow:.6;}

/* ── (01b) plate consumer ────────────────────────────────────────────── */
/* --kyp-plate is the pill's declared background token — every world that
   sets it expects the collapsed face to wear it — but nothing consumed it:
   the pill's actual paint is liquid-glass.css's
   `background: color-mix(in srgb, var(--lg-surface) var(--lg-tint), transparent)`,
   and --lg-surface stays the CLASSIC theme's --color-background regardless
   of which wallpaper world is mounted (ky-mode.css's wallmode accent-fold
   only tints 16% of the wallpaper accent into it), so the pill kept
   rendering Honey & Ink amber under every world while only the canvas-drawn
   wave picked up the world's colour. Re-pointing --lg-surface on #ky-music
   itself feeds the SAME mix the engine already runs — no new background
   rule, no specificity war. #ky-music's id selector outguns ky-mode.css's
   (2b) wallmode fold (html.ky-wallmode[data-glass]:not(...), no id) outright.
   Falls back to whatever --lg-surface already resolved to when a world
   doesn't declare --kyp-plate, so worlds that never set the token are
   unaffected. */
html.ky-wallmode[data-glass] #ky-music.lg-surface{
  --lg-surface: var(--kyp-plate, var(--lg-surface));
}

/* ── (02) shell state ────────────────────────────────────────────────── */
/* ky-music.css transitions width for its own fold; the spring writes width
   per frame and a .5s transition on top of that is a low-pass filter that
   makes the morph land half a second late. Scoped to .kyp-on so a page
   without the module keeps the shipped behaviour. */
html[data-glass] #ky-music.kyp-on{transition:none;}

/* SPEC DELETIONS, made here rather than in files this module doesn't own:
   the 40x40 art tile (and its CSS-ladder fallback inside it) is gone — the
   canvas is the living layer now, and play/pause consolidates on .kym-play.
   The old always-collapsed puck class is neutralised in case anything still
   stamps it. */
#ky-music.kyp-on .kym-art{display:none;}
#ky-music.kyp-on.kym-min :is(.kym-meta,.kym-prog,.kym-vol,.kym-sk){display:flex;}

/* ── (03) the one canvas ─────────────────────────────────────────────── */
/* Sized by JS to the EXPANDED max box and centre-anchored, so the shell can
   morph around it with zero canvas writes per frame: the bar's own
   overflow:hidden is the crop. z-order: canvas under both content layers
   (the expanded wave is a 0.14-alpha backdrop UNDER the controls), content
   above; .lg2-spec's z:2 gloss stays where liquid-glass.css put it. */
#ky-music.kyp-on .kyp-viz{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  z-index:0; pointer-events:none;
}
#ky-music.kyp-on .kym-row{position:relative; z-index:1;}

/* ── (04) collapsed face ─────────────────────────────────────────────── */
#ky-music.kyp-on .kyp-face{position:absolute; inset:0; z-index:1;}
#ky-music.kyp-on .kyp-open{
  position:absolute; inset:0; width:100%; height:100%;
  border-radius:inherit;
  /* transparent on purpose: the wave IS the pill's entire face */
}

/* re-homed player chevrons. These are the SAME nodes the transport uses —
   ky-pulse.js moves them between .kym-ctl and this face at the morph's
   midpoint — so every rule here undoes the 30px-circle styling ky-music.css
   gives .kym-sk and rebuilds them as edge zones of the pill. The 44x44
   ::before hit pad from ky-music.css (01) still applies and is wanted. */
#ky-music.kyp-on .kyp-face .kym-sk{
  position:absolute; top:0; bottom:0; width:36px; height:auto;
  border-radius:0; z-index:1;
  color:var(--kyp-muted);
  transition:color .16s ease, opacity .16s ease;
}
#ky-music.kyp-on .kyp-face .kym-sk svg{display:none;}  /* glyph is the ::after */
#ky-music.kyp-on .kyp-face .kym-sk::after{
  content:""; width:9px; height:9px;
  border-right:1.5px solid currentColor; border-bottom:1.5px solid currentColor;
  transform:rotate(var(--kyp-rot,-45deg));
}
#ky-music.kyp-on .kyp-face .kym-next{right:0; --kyp-rot:-45deg;}
#ky-music.kyp-on .kyp-face .kym-prev{left:0; width:28px; --kyp-rot:135deg;}
#ky-music.kyp-on .kyp-face .kym-sk:hover,
#ky-music.kyp-on .kyp-face .kym-sk:focus-visible{
  color:var(--kyp-ink); background:none; transform:none;
}
/* hover-only prev, desktop pointers only — on touch, swipe covers prev and a
   permanently invisible tap target would be a trap */
#ky-music.kyp-on .kyp-face .kym-prev{display:none;}
@media (hover: hover) and (pointer: fine){
  #ky-music.kyp-on .kyp-face .kym-prev{display:flex; opacity:0;}
  #ky-music.kyp-on:hover .kyp-face .kym-prev,
  #ky-music.kyp-on .kyp-face .kym-prev:focus-visible{opacity:1;}
}
/* skip acknowledgement — ky-musicfx stamps .kym-nudge on click; its keyframes
   translate the (display:none'd) svg, so the face redeclares the same ±3px
   nudge on the ::after, composed with the chevron's own rotation. */
#ky-music.kyp-on .kyp-face .kym-sk.kym-nudge::after{
  animation:kypNudge .34s var(--kyp-ease);
}
@keyframes kypNudge{
  0%  {transform:rotate(var(--kyp-rot,-45deg));}
  34% {transform:translateX(var(--kym-nx,0)) rotate(var(--kyp-rot,-45deg));}
  100%{transform:rotate(var(--kyp-rot,-45deg));}
}
@media (max-width:680px){
  #ky-music.kyp-on .kyp-face .kym-next{width:34px;}
}

/* ── (05) layer visibility at rest ───────────────────────────────────── */
/* Opacity is crossfaded per frame by the JS; visibility is the REST state so
   focus can never land in a hidden layer (ky-island's proven discipline).
   During flight the JS holds inline visibility:visible on both, and clears
   it at commit so these rules take over. */
#ky-music.kyp-on.kyp-min .kym-row{visibility:hidden;}
#ky-music.kyp-on.kyp-bar .kyp-face{visibility:hidden;}

/* ── (06) fold (created by ky-pulse.js when absent) ──────────────────── */
/* .kym-tools/.kym-fold already carry full styling in ky-music.css (08); the
   markup just doesn't exist on this page (ky-dock.js, its old owner, is not
   loaded). Only the glyph's stroke setup is ours. */
#ky-music.kyp-on .kym-fold svg{
  width:13px; height:13px; fill:none; stroke:currentColor;
  stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round;
}

/* ── (07) reduced motion ─────────────────────────────────────────────── */
/* The JS swaps geometry instantly under this class (stamped from the media
   query, so the JS and CSS can never disagree) and flips opacity; the single
   120ms opacity-only crossfade is the one piece of motion that remains. */
#ky-music.kyp-rm .kyp-face,
#ky-music.kyp-rm .kym-row{transition:opacity 120ms ease;}
@media (prefers-reduced-motion: reduce){
  #ky-music.kyp-on .kyp-face .kym-sk.kym-nudge::after{animation:none;}
  #ky-music.kyp-on .kyp-face .kym-sk,
  #ky-music.kyp-on .kyp-face .kym-prev{transition:none;}
}
