/* Rule 50 AI background music player.
   Injected into every build/*.html by tools/inject_nav.py, alongside r50-music.js.

   Every colour here is an existing site token (var(--green) etc. -- the same
   --green the RULE 50 AI wordmark and the nav brand use). The fallbacks after each
   comma repeat the token's own value from :root and exist only for the one page
   that might not declare them; they are not new colours.

   Targets are >=44px (WCAG 2.5.5 / Apple HIG) on every control, which is why the
   transport row is sized in px rather than em -- a 44px button must stay 44px when
   the user has bumped their browser's font size, not grow past the panel. */

.r50-music{
  --m-green:var(--green,#00ff41);
  --m-dim:var(--green-dim,#0a8f2f);
  --m-panel:var(--panel,#10151a);
  --m-line:var(--line,#1f2830);
  --m-ink:var(--ink,#d8e0e4);
  --m-muted:var(--muted,#8b979e);
  /* top/max-height follow the bar's MEASURED height, published as --r50-navh by
     the nav script. 3.3rem was a guess that stopped being true when the bar
     gained 44px tap targets -- it is 62.6px on a phone, so this panel's top
     edge sat about 10px behind the bar. The literal remains the fallback for a
     page whose nav script has not run. Two max-heights: calc() with a unit the
     browser does not know drops the whole declaration, so the vh line is what
     anything without dvh gets. */
  position:fixed;z-index:60;top:var(--r50-navh,3.3rem);right:0;left:0;
  max-height:calc(100vh - var(--r50-navh,3.3rem));
  max-height:calc(100dvh - var(--r50-navh,3.3rem));overflow-y:auto;
  overscroll-behavior:contain;padding-bottom:env(safe-area-inset-bottom,0px);
  background:var(--m-panel);border-bottom:1px solid var(--m-line);
  border-top:1px solid var(--m-line);
  box-shadow:0 10px 30px rgba(0,0,0,.55), 0 0 24px rgba(0,255,65,.05) inset;
  font-family:ui-monospace,"Cascadia Mono",Consolas,Menlo,monospace;
  color:var(--m-ink);font-size:.85rem;line-height:1.5;
  padding:.9rem 1rem 1.1rem;
  display:none;
}
body.music-open .r50-music{display:block}
@media(min-width:720px){
  .r50-music{left:auto;width:min(360px,calc(100vw - 2rem));margin-right:.5rem;
             border:1px solid var(--m-line);border-radius:0 0 8px 8px}
}

.r50-music .m-head{display:flex;align-items:center;justify-content:space-between;
  gap:.5rem;border-bottom:1px solid var(--m-line);padding-bottom:.6rem;margin-bottom:.8rem}
.r50-music .m-head h2,.r50-music .m-head .m-title-lbl{
  color:var(--m-green);font-size:.8rem;letter-spacing:.14em;margin:0;font-weight:400;
  text-shadow:0 0 10px rgba(0,255,65,.3)}
.r50-music .m-head h2::before{content:none}   /* site h2 adds "> "; not wanted here */

/* now playing */
.r50-music .m-now{margin:0 0 .7rem;min-height:2.6em}
.r50-music .m-now .m-track{color:var(--m-green);display:block;
  overflow-wrap:anywhere}
.r50-music .m-now .m-state{color:var(--m-muted);font-size:.75rem;letter-spacing:.08em}

/* seek bar + times */
.r50-music .m-seekrow{display:flex;align-items:center;gap:.6rem;margin-bottom:.5rem}
.r50-music .m-time{color:var(--m-muted);font-size:.75rem;
  font-variant-numeric:tabular-nums;flex:0 0 auto;min-width:3.4em}
.r50-music .m-time.m-dur{text-align:right}

.r50-music input[type=range]{
  -webkit-appearance:none;appearance:none;background:transparent;
  flex:1 1 auto;min-width:0;height:44px;margin:0;cursor:pointer;
  touch-action:none;   /* a drag on the slider must not scroll the page behind it */
}
.r50-music input[type=range]::-webkit-slider-runnable-track{
  height:4px;background:var(--m-line);border-radius:2px}
.r50-music input[type=range]::-moz-range-track{
  height:4px;background:var(--m-line);border-radius:2px}
.r50-music input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none;appearance:none;width:16px;height:16px;margin-top:-6px;
  border-radius:50%;background:var(--m-green);border:0;
  box-shadow:0 0 8px rgba(0,255,65,.55)}
.r50-music input[type=range]::-moz-range-thumb{
  width:16px;height:16px;border-radius:50%;background:var(--m-green);border:0;
  box-shadow:0 0 8px rgba(0,255,65,.55)}
.r50-music input[type=range]:focus-visible{outline:2px solid var(--m-green);
  outline-offset:-6px;border-radius:4px}
.r50-music input[type=range]:disabled{cursor:default;opacity:.5}

/* transport + toggles */
.r50-music .m-row{display:flex;align-items:center;gap:.35rem;flex-wrap:wrap}
.r50-music .m-row+.m-row{margin-top:.35rem}
.r50-music button{
  min-width:44px;min-height:44px;padding:.3rem .5rem;
  background:transparent;border:1px solid var(--m-line);border-radius:6px;
  color:var(--m-ink);font-family:inherit;font-size:1rem;line-height:1;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center}
.r50-music button:hover{border-color:var(--m-dim);color:var(--m-green)}
.r50-music button:focus-visible{outline:2px solid var(--m-green);outline-offset:2px}
.r50-music button[aria-pressed=true]{border-color:var(--m-green);color:var(--m-green);
  box-shadow:0 0 12px rgba(0,255,65,.18) inset}
.r50-music button.m-play{border-color:var(--m-dim);color:var(--m-green);
  box-shadow:0 0 14px rgba(0,255,65,.12) inset}
.r50-music button.m-mode{font-size:.72rem;letter-spacing:.06em;gap:.3rem}
.r50-music button.m-mode .m-mode-tag{font-size:.68rem;color:var(--m-muted)}
.r50-music button[aria-pressed=true].m-mode .m-mode-tag{color:var(--m-green)}
.r50-music .m-close{font-size:1.1rem}

/* track list */
.r50-music .m-list{list-style:none;margin:.9rem 0 0;padding:.8rem 0 0;
  border-top:1px solid var(--m-line);counter-reset:trk}
.r50-music .m-list li{counter-increment:trk;margin:0}
.r50-music .m-list button{
  width:100%;min-height:44px;justify-content:flex-start;gap:.7rem;
  border:0;border-radius:4px;padding:.4rem .5rem;text-align:left;
  font-size:.82rem;color:var(--m-ink)}
.r50-music .m-list button::before{
  content:counter(trk,decimal-leading-zero);color:var(--m-dim);flex:0 0 auto;
  font-size:.75rem;letter-spacing:.05em}
.r50-music .m-list button:hover{background:rgba(0,255,65,.05);color:var(--m-green)}
.r50-music .m-list .m-name{overflow-wrap:anywhere}
.r50-music .m-list .m-len{margin-left:auto;color:var(--m-muted);font-size:.72rem;
  font-variant-numeric:tabular-nums;flex:0 0 auto}
.r50-music .m-list button[aria-current=true]{
  background:rgba(0,255,65,.08);color:var(--m-green);
  box-shadow:inset 2px 0 0 var(--m-green)}
.r50-music .m-list button[aria-current=true]::before{color:var(--m-green)}

.r50-music .m-foot{color:var(--m-muted);font-size:.7rem;margin:.8rem 0 0;line-height:1.45}

/* The music button in the top bar itself, beside the hamburger (the operator, 2026-11-03),
   because it is the only thing on the site that starts music and it has to be in
   reach on every page. Deliberately matched to .topnav .burger -- same box, same
   border, same green -- because they are peers in that corner and should read as a
   set. The caret beside it opens the full controls; it is dimmer and narrower, so
   the pair reads as one primary action with an expander, not as two buttons. */
.topnav button.r50-music-toggle,
.topnav button.r50-music-panel-btn{
  background:none;border:1px solid var(--line,#1f2830);border-radius:6px;
  /* The accent's dim tone, not a fixed green. --green-dim is not themed by the
     case colour the visitor picks, so on any of the nine non-green swatches
     these two sat green beside an orange (or pink, or cyan) hamburger -- which
     is precisely what the comment above says must not happen. Seen on
     2026-11-04 in the operator's own screenshot, which is an orange theme. */
  color:var(--case-neon-dim,var(--green-dim,#0a8f2f));
  font-family:inherit;font-size:1.25rem;line-height:1;
  padding:.25rem .6rem;min-width:44px;min-height:44px;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center}
.topnav button.r50-music-toggle{margin-left:auto;margin-right:.3rem;position:relative}
/* The drawn icon. One eighth note; sound waves when it is playing, a diagonal
   slash when it is not -- off, paused and muted alike (the operator, 2026-11-04: "an
   eighth note when playing (optionally with small sound waves), and the note
   with a clean diagonal slash when off or muted, in the theme color").

   Marking silence at all is deliberate and predates this: nothing autoplays, so
   without a mark every first visit showed a bare note on a silent page -- a
   button that looked exactly like music already on. The mark is the thing the
   visitor can act on, and it goes the moment sound is actually coming out.

   Everything is currentColor, so the icon wears whichever of the ten accents is
   stored in the r50_case_color cookie. Geometry and the reason the slash is
   masked rather than overlaid are in noteIcon(), r50-music.js. */
.topnav button.r50-music-toggle .m-ico{
  width:1.25em;height:1.15em;display:block;fill:currentColor}
.topnav button.r50-music-toggle .m-ico .m-stroke{
  fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
/* The mask's cut. Black hides, so a zero width means no cut and the note is
   whole; it opens to a gap only when the slash is showing, and the gap is wider
   than the slash so the slash sits in clean space rather than touching the note. */
.topnav button.r50-music-toggle .m-ico .m-cut{
  stroke:#000;stroke-width:0;stroke-linecap:round}
.topnav button.r50-music-toggle.m-muted .m-ico .m-cut{stroke-width:3.4}
.topnav button.r50-music-toggle .m-ico .m-slash{
  stroke:currentColor;stroke-width:2;stroke-linecap:round;opacity:0}
.topnav button.r50-music-toggle.m-muted .m-ico .m-slash{opacity:1}
.topnav button.r50-music-toggle .m-ico .m-wave{opacity:0}
.topnav button.r50-music-toggle.m-playing .m-ico .m-wave{opacity:1}
/* Playing is the one state worth a little light, and it is the accent's own
   bright tone rather than the dim one the button rests at. */
.topnav button.r50-music-toggle.m-playing{
  color:var(--case-neon-text,var(--green,#39FF6A))}
.topnav button.r50-music-panel-btn{margin-right:.4rem;font-size:.9rem;
  padding:.25rem .4rem;opacity:.85}

/* The Music entry inside the dropdown. A <button>, because it opens a panel rather
   than going anywhere, which means it has to be dressed by hand to match
   `.topnav .menu a` -- those live in the per-page nav CSS that this file cannot
   reach, so the values here are copied from it deliberately. Hidden at >=720px,
   where the menu IS the top bar and the two buttons are already in it. */
.topnav .menu button.r50-music-menu-item{
  background:none;border:0;border-top:1px solid var(--line,#1f2830);
  font-family:inherit;font-size:1rem;color:#d8e0e4;text-align:left;
  padding:.85rem 1.25rem;width:100%;cursor:pointer;display:block}
.topnav .menu button.r50-music-menu-item:hover{color:var(--green,#00ff41)}
.topnav .menu button.r50-music-menu-item:focus-visible{
  outline:2px solid var(--green,#00ff41);outline-offset:-2px}
@media(min-width:720px){
  .topnav .menu button.r50-music-menu-item{display:none}
}
.topnav button.r50-music-toggle:hover,
.topnav button.r50-music-panel-btn:hover{color:var(--green,#00ff41);
  border-color:var(--green-dim,#0a8f2f);opacity:1}
.topnav button.r50-music-toggle:focus-visible,
.topnav button.r50-music-panel-btn:focus-visible{
  outline:2px solid var(--green,#00ff41);outline-offset:2px}
/* lit while music is playing, and while the panel is open */
.topnav button.r50-music-toggle.m-playing,
.topnav button.r50-music-panel-btn[aria-expanded=true]{
  color:var(--green,#00ff41);border-color:var(--green,#00ff41);
  text-shadow:0 0 10px rgba(0,255,65,.45);opacity:1}
@media(min-width:720px){
  /* The nav is justify-content:space-between and the menu joins the flow at this
     width, so without the auto margin the two buttons get spread across the bar
     instead of sitting with it. The auto margin eats the free space on the left and
     the pair packs against the menu, which is where they belong. */
  .topnav button.r50-music-toggle{margin-left:auto;margin-right:.3rem}
  .topnav button.r50-music-panel-btn{margin-right:.7rem}
}

@media (prefers-reduced-motion:reduce){
  .r50-music *{transition:none!important;animation:none!important}
}
