.panel {
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  box-shadow: var(--shadow-panel);
  margin-bottom: var(--space-4);
}
.panel-header {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--accent-neon);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin: 0 0 var(--space-3) 0;
  padding-bottom: var(--space-2);
  border-bottom: 1px dashed var(--panel-border);
}
.widget {
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  box-shadow: var(--shadow-panel);
  margin-bottom: var(--space-4);
}
.chrome-border {
  border: 2px solid var(--panel-border);
  border-style: outset;
}
.neon { color: var(--accent-neon); text-shadow: var(--glow-neon); }
.dim { color: var(--ink-dim); }
.mono { font-family: var(--font-mono); }
.tag {
  display: inline-block;
  padding: 2px var(--space-2);
  background: var(--bg-elev);
  border: 1px solid var(--panel-border);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--accent-cyan);
}
.divider-ascii {
  color: var(--ink-dim);
  font-family: var(--font-mono);
  text-align: center;
  margin: var(--space-6) 0;
}
.btn {
  display: inline-block;
  padding: var(--space-1) var(--space-3);
  background: var(--bg-elev);
  border: 1px solid var(--panel-border);
  color: var(--accent-cyan);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
}
.btn:hover { color: var(--accent-neon); border-color: var(--accent-neon); text-decoration: none; }
.seg-nav { display: flex; gap: var(--space-2); margin-bottom: var(--space-3); flex-wrap: wrap; }
.seg-btn.active { color: var(--accent-neon); border-color: var(--accent-neon); }
.seg-list { list-style: none; padding: 0; margin: 0; }
.seg-list li { padding: var(--space-1) 0; border-bottom: 1px dashed var(--panel-border); }
.badges { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.gb-preview { list-style: none; padding: 0; margin: 0 0 var(--space-3) 0; }
.gb-preview li { padding: var(--space-2) 0; border-bottom: 1px dashed var(--panel-border); }
.dade-fx-starfield {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}
.dade-fx-crt {
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
}
.fx-toggles { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.audio-mount { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.audio-mount canvas { background: #000033; border: 1px solid var(--panel-border); }
.arcade-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-4);
}
.arcade-grid canvas { margin: 0 auto; }
.arcade-score { margin: var(--space-3) 0 0 0; text-align: center; }
.webring-grid {
  width: 100%;
  border-collapse: separate;
  border-spacing: var(--space-3);
}
.webring-grid td { text-align: center; padding: var(--space-2); }
.link-list { list-style: none; padding: 0; margin: 0; }
.link-list li {
  padding: var(--space-2) 0;
  border-bottom: 1px dashed var(--panel-border);
  font-family: var(--font-mono);
}
.link-list li:last-child { border-bottom: 0; }
.link-list a { color: var(--accent-cyan); }
.link-list .desc { color: var(--ink-dim); margin-left: var(--space-2); }
.lcd {
  background: #0c1814;
  color: var(--accent-neon);
  font-family: var(--font-mono);
  padding: var(--space-2);
  border: 1px solid #072210;
  box-shadow: inset 0 0 4px #000;
  letter-spacing: 0.05em;
  font-size: var(--fs-sm);
}
.lcd-scroll { white-space: nowrap; overflow: hidden; }
.lcd-scroll span { display: inline-block; padding-left: 100%; animation: lcd-marquee 16s linear infinite; }
.lcd-scroll .sprite-glyph { padding-left: 0; animation: none; }
@keyframes lcd-marquee { 0% { transform: translateX(0); } 100% { transform: translateX(-100%); } }
.player-controls { display: flex; gap: var(--space-1); margin-top: var(--space-2); }
.player-controls .btn { padding: 2px 8px; min-width: 32px; text-align: center; }
input[type=range].vol { width: 100%; margin-top: var(--space-2); accent-color: var(--accent-neon); }
.sf-loading { color: var(--ink-dim); font-size: var(--fs-xs); margin-top: var(--space-1); }

/* ----------------------------------------------------------------------
   Winamp 2 chrome skin — sprite-sliced from the Base 2.91 .wsz pack.
   Every visible piece of chrome (titlebar art, recessed wells, transport
   buttons, volume/balance tracks + thumbs, EQ window, EQ thumbs) is
   painted by background-image + background-position from the bitmap
   sprite sheets that ship with the original skin. No CSS gradients —
   the bevels and gradients are baked into the bitmaps.

   Coordinate system follows the public Winamp 2 skin spec, which has
   been the canonical reference since ~1998. Sheet sizes after PNG
   conversion (preserved 1:1 from the BMP source):

     main.png      275x116    full main-window background
     cbuttons.png  136x36     5 transport buttons (23x18 each, eject 22x18)
                              top row y=0 normal, bottom row y=18 pressed
     volume.png    68x433     28 track frames 68x15 stacked + thumb at y=422
     balance.png   68x433     same layout, active 38px area centered
     eqmain.png    275x315    EQ window bg (top 116px) + thumb sprites
     numbers.png   99x13      10 digits 9x13 laid horizontally
     text.png      155x74     5x6 bitmap font (3 rows of 31 chars, plus extras)
     monoster.png  58x24      mono/stereo indicator pair
     shufrep.png   92x85      shuffle / repeat button states
     posbar.png    307x10     position-bar track + thumb
     titlebar.png  344x87     alt titlebar variants (focus / shaded)
     pledit.png    280x186    playlist editor chrome (titlebar, sides, bottom, scrollbar, close)
     eq_ex.png     275x82     extended EQ sprites
     playpaus.png  42x9       small play/pause/stop status indicator

   Pixel-perfect rendering requires `image-rendering: pixelated` on every
   sprite-backed element so the browser never bilinear-smooths the bitmaps
   when the layout DPR is non-integer.
   ---------------------------------------------------------------------- */

#winamp-stack {
  width: 275px;
  margin: 0;
  padding: 0;
  font-family: "VT323", "Courier New", Courier, monospace;
}

#winamp-chrome {
  position: relative;
  width: 275px;
  height: 116px;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/main.png");
  background-repeat: no-repeat;
  background-position: 0 0;
  background-size: 275px 116px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  color: #00FF66;
  font-family: "VT323", "Courier New", Courier, monospace;
  font-size: 10px;
  line-height: 1;
  user-select: none;
}
#winamp-chrome.shaded {
  height: 14px;
  background-image: url("../images/winamp-skin/base-2.91/titlebar.png");
  background-repeat: no-repeat;
  background-position: -27px -29px;
  background-size: 344px 87px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
#winamp-chrome.shaded > :not(.wa-titlebar) { display: none !important; }
#winamp-chrome.shaded .wa-titlebar { background-image: none; }

/* Title bar — the bitmap art in main.png paints the gradient, bolt and
   "WINAMP" wordmark. The .wa-titlebar element stays as a clickable spacer
   covering the same coords; its child labels are hidden because the
   wordmark is already in the sprite. */
#winamp-chrome .wa-titlebar {
  position: absolute;
  left: 0;
  top: 0;
  width: 275px;
  height: 14px;
  margin: 0;
  padding: 0;
  background: transparent;
  border: 0;
  cursor: move;
}
#winamp-chrome .wa-titlebar > * { display: none; }

/* Defense-in-depth — kill any inherited theme text (VT323 / --accent-neon)
   from leaking into titlebar children. Sprite backgrounds are unaffected
   because they paint via background-image; aria-labels remain readable to
   screen readers regardless of font-size. */
#winamp-chrome .wa-titlebar,
#winamp-chrome .wa-titlebar * {
  font-size: 0;
  line-height: 0;
  color: transparent;
}

/* The kbps/khz/stereo readouts ride on top of main.png as live HTML
   spans rendered with the text.png bitmap font (see sprite-glyph block
   below). Each child is positioned at its canonical Winamp coords:
   - .wa-bitrate at (111, 43) 15x6  — numeric only ("128 kbps" → "128")
   - .wa-srate   at (156, 43) 10x6  — numeric only ("44 kHz"  → "44")
   - .wa-channels at (212, 41) 56x12 — text node only drives monoster
     overlay; the text itself is invisible because the .wa-monoster
     sprite owns that screen region. */
#winamp-chrome .wa-readout {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: transparent;
}
#winamp-chrome .wa-bitrate {
  position: absolute;
  left: 111px;
  top: 43px;
  width: 15px;
  height: 6px;
  overflow: hidden;
  font-size: 0;
  line-height: 0;
}
#winamp-chrome .wa-srate {
  position: absolute;
  left: 156px;
  top: 43px;
  width: 10px;
  height: 6px;
  overflow: hidden;
  font-size: 0;
  line-height: 0;
}
#winamp-chrome .wa-channels {
  position: absolute;
  left: 212px;
  top: 41px;
  width: 56px;
  height: 12px;
  visibility: hidden;
}

/* Hidden helper elements that do not render any chrome. */
#winamp-chrome .wa-track-select,
#winamp-chrome .wa-viz { display: none !important; }

/* Sprite-fidelity spectrum analyser / oscilloscope canvas. Lives at the
   canonical Winamp 2 viz coords inside the 275x116 main window: a 76x16
   pixel well at (24, 43), immediately right of the play/pause/stop sprite
   stack and left of the LCD. The canvas backing store is 1:1 with the
   on-screen pixels (76x16 attributes match the CSS box) so no scaling
   ever happens; image-rendering: pixelated is defensive in case a
   non-integer DPR or zoom forces the browser to resample. Painting is
   driven by the inline `attachWaViz` IIFE in index.html which polls
   globalThis.__dadeAudioAnalyser and never edits audio/. No CSS
   gradients — every colour is a flat fill from the viscolor palette
   baked into the JS, matching the .wsz palette format. */
#winamp-chrome #wa-viz {
  position: absolute;
  left: 24px;
  top: 43px;
  width: 76px;
  height: 16px;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  cursor: pointer;
  z-index: 5;
}

/* Audio player mount becomes a coordinate space spanning the full chrome.
   Every interactive child is absolutely positioned at canonical Winamp
   pixel coordinates so the live controls land exactly on top of the
   sprite art. */
#winamp-chrome #audio-player-mount {
  position: absolute;
  left: 0;
  top: 0;
  width: 275px;
  height: 116px;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
}
#winamp-chrome #audio-player-mount h2.panel-header { display: none; }
#winamp-chrome #audio-player-mount .audio-mount {
  position: absolute;
  inset: 0;
  display: block;
  background: transparent;
  padding: 0;
  margin: 0;
  border: 0;
}
#winamp-chrome #audio-player-mount .audio-mount canvas { display: none !important; }

/* Track scroller — the inner [data-role=lcd] span is rebuilt by the
   sprite-text observer in index.html into a row of 5x6 text.png glyphs.
   The wrapping .lcd well clips at 154x6 and the inline JS animates the
   inner span via translateX (rAF, ~30 px/sec). The base .lcd-scroll
   keyframe animation defined earlier is overridden inside the chrome
   scope so it can't fight the rAF marquee or scroll our glyph spans. */
#winamp-chrome #audio-player-mount .lcd {
  position: absolute;
  left: 111px;
  top: 27px;
  width: 154px;
  height: 6px;
  margin: 0;
  padding: 0;
  background: transparent;
  border: 0;
  box-shadow: none;
  color: transparent;
  font-size: 0;
  line-height: 0;
  letter-spacing: 0;
  overflow: hidden;
  white-space: nowrap;
}
#winamp-chrome .lcd-scroll [data-role="lcd"] {
  display: inline-block;
  padding: 0;
  margin: 0;
  animation: none;
  white-space: nowrap;
  font-size: 0;
  line-height: 0;
  will-change: transform;
}

/* Time digits — sprite-sliced from numbers.png (9x13 cells) by the
   inline sprite-text observer. The colon between minutes and seconds
   is emitted from text.png (numbers.png has no colon glyph) and
   centered vertically in the 13px digit row via .sprite-time-colon.
   Wrapper .mono.dim is reset to position:static so the absolute
   coords on [data-role="time"] resolve against the .audio-mount /
   #audio-player-mount coordinate space (canonical Base 2.91 LCD well
   at left=48 top=26 inside the 275x116 chrome). */
#winamp-chrome [data-role="time"],
#winamp-chrome #audio-player-mount [data-role="time"] {
  position: absolute;
  left: 48px;
  top: 26px;
  width: 63px;
  height: 13px;
  margin: 0;
  padding: 0;
  font-size: 0;
  line-height: 0;
  color: transparent;
  letter-spacing: 0;
  white-space: nowrap;
  image-rendering: pixelated;
}
#winamp-chrome #audio-player-mount [data-role="time"] + .sf-loading,
#winamp-chrome #audio-player-mount [data-role="loading"] { display: none; }
#winamp-chrome #audio-player-mount .audio-mount > .mono.dim {
  position: static;
  margin: 0;
  padding: 0;
  background: transparent;
}

/* Bitmap-font glyph cells emitted by the sprite-text observer.
   .sprite-text reads text.png (155x74, 5x6 cells, FONT_LOOKUP from
   webamp/skinSprites.ts). .sprite-number reads numbers.png (99x13,
   9x13 cells, digits 0..9 at x=0,9,18,..,81). Both render with
   image-rendering:pixelated so the bitmaps stay crisp. The colon
   glyph is the text.png ':' centered in the 13-tall digit row via
   margin (numbers.png has no colon). */
.sprite-glyph {
  display: inline-block;
  background-repeat: no-repeat;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  vertical-align: top;
  font-size: 0;
  line-height: 0;
  color: transparent;
}
.sprite-text {
  width: 5px;
  height: 6px;
  background-image: url("../images/winamp-skin/base-2.91/text.png");
  background-size: 155px 74px;
}
.sprite-number {
  width: 9px;
  height: 13px;
  background-image: url("../images/winamp-skin/base-2.91/numbers.png");
  background-size: 99px 13px;
}
.sprite-time-colon {
  margin-top: 3px;
  margin-bottom: 4px;
}

/* Transport row — sprite-sliced from cbuttons.png. The sheet is 136x36:
   top row y=0 = normal, bottom row y=18 = pressed. X offsets per button:
   prev 0, play 23, pause 46, stop 69, next 92, eject 115. */
#winamp-chrome #audio-player-mount .player-controls {
  position: absolute;
  left: 16px;
  top: 88px;
  display: flex;
  gap: 0;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
}
#winamp-chrome #audio-player-mount .player-controls .btn {
  width: 23px;
  height: 18px;
  min-width: 0;
  padding: 0;
  margin: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/cbuttons.png");
  background-repeat: no-repeat;
  background-size: 136px 36px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  font-size: 0;
  line-height: 0;
  color: transparent;
  text-indent: -9999px;
  overflow: hidden;
  cursor: pointer;
}
#winamp-chrome #audio-player-mount .player-controls .btn[data-act="prev"]  { background-position:    0px 0; }
#winamp-chrome #audio-player-mount .player-controls .btn[data-act="play"]  { background-position: -23px 0; }
#winamp-chrome #audio-player-mount .player-controls .btn[data-act="pause"] { background-position: -46px 0; }
#winamp-chrome #audio-player-mount .player-controls .btn[data-act="stop"]  { background-position: -69px 0; }
#winamp-chrome #audio-player-mount .player-controls .btn[data-act="next"]  { width: 22px; background-position: -92px 0; }
#winamp-chrome #audio-player-mount .player-controls .btn[data-act="prev"]:active  { background-position:    0px -18px; }
#winamp-chrome #audio-player-mount .player-controls .btn[data-act="play"]:active  { background-position: -23px -18px; }
#winamp-chrome #audio-player-mount .player-controls .btn[data-act="pause"]:active { background-position: -46px -18px; }
#winamp-chrome #audio-player-mount .player-controls .btn[data-act="stop"]:active  { background-position: -69px -18px; }
#winamp-chrome #audio-player-mount .player-controls .btn[data-act="next"]:active  { background-position: -92px -18px; }
#winamp-chrome #audio-player-mount .player-controls .btn:hover { background-color: transparent; }
#winamp-chrome #audio-player-mount .player-controls .btn:focus-visible {
  outline: 1px dotted #FFCC33;
  outline-offset: 0;
}

/* Eject button — audio/player.js does not emit one (architecture lock),
   so the eject sprite is overlaid as a separate <button class="wa-eject">
   inside #winamp-chrome at the canonical webamp coords (left=136, top=89,
   22x16). Sprite frame is 22x16 (not 18 like the prev/play/pause/stop/next
   row) and sits at sx=114 in cbuttons.png; pressed sprite at sy=16. */
#winamp-chrome .wa-eject {
  position: absolute;
  left: 136px;
  top: 89px;
  width: 22px;
  height: 16px;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/cbuttons.png");
  background-repeat: no-repeat;
  background-size: 136px 36px;
  background-position: -114px 0;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  font-size: 0;
  line-height: 0;
  color: transparent;
  text-indent: -9999px;
  overflow: hidden;
  cursor: pointer;
}
#winamp-chrome .wa-eject:active {
  background-image: url("../images/winamp-skin/base-2.91/cbuttons.png");
  background-position: -114px -16px;
}
#winamp-chrome .wa-eject:focus-visible {
  outline: 1px dotted #FFCC33;
  outline-offset: 0;
}

/* Volume slider — track is sprite-sliced from volume.png at canonical
   x=107, y=57 (68x14). Frame index is updated via the --vol-frame CSS
   variable from the inline init script in index.html (input event only,
   no audio-graph changes). 28 frames of 15px tall stacked vertically;
   thumb sprite sits at y=422 (normal) / y=423 (pressed) in the sheet. */
#winamp-chrome #audio-player-mount input[type="range"].vol {
  position: absolute;
  left: 107px;
  top: 57px;
  width: 68px;
  height: 14px;
  margin: 0;
  padding: 0;
  border: 0;
  -webkit-appearance: none;
  appearance: none;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/volume.png");
  background-repeat: no-repeat;
  background-position: 0 calc(var(--vol-frame, 14) * -15px);
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  cursor: ew-resize;
}
#winamp-chrome #audio-player-mount input[type="range"].vol::-webkit-slider-runnable-track {
  width: 68px;
  height: 14px;
  background: transparent;
  border: 0;
}
#winamp-chrome #audio-player-mount input[type="range"].vol::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 11px;
  margin-top: 2px;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/volume.png");
  background-repeat: no-repeat;
  background-position: -15px -422px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  cursor: ew-resize;
}
#winamp-chrome #audio-player-mount input[type="range"].vol:active::-webkit-slider-thumb {
  background-position: 0 -422px;
}
#winamp-chrome #audio-player-mount input[type="range"].vol::-moz-range-track {
  width: 68px;
  height: 14px;
  background: transparent;
  border: 0;
}
#winamp-chrome #audio-player-mount input[type="range"].vol::-moz-range-thumb {
  width: 14px;
  height: 11px;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/volume.png");
  background-repeat: no-repeat;
  background-position: -15px -422px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  cursor: ew-resize;
}
#winamp-chrome #audio-player-mount input[type="range"].vol:active::-moz-range-thumb {
  background-position: 0 -422px;
}

/* Balance slider — sprite balance.png at canonical x=177, y=57 (38x14).
   Frame index = round(|balance| * 27). The active 38px region inside
   the 68px sheet starts at sx=9 (per webamp/js/skinSprites.ts BALANCE
   MAIN_BALANCE_BACKGROUND), so background-position-x is -9px. */
#winamp-chrome #audio-player-mount input[type="range"].bal {
  position: absolute;
  left: 177px;
  top: 57px;
  width: 38px;
  height: 14px;
  margin: 0;
  padding: 0;
  border: 0;
  -webkit-appearance: none;
  appearance: none;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/balance.png");
  background-repeat: no-repeat;
  background-position: -9px calc(var(--bal-frame, 0) * -15px);
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  cursor: ew-resize;
}
#winamp-chrome #audio-player-mount input[type="range"].bal::-webkit-slider-runnable-track {
  width: 38px;
  height: 14px;
  background: transparent;
  border: 0;
}
#winamp-chrome #audio-player-mount input[type="range"].bal::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 11px;
  margin-top: 2px;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/balance.png");
  background-repeat: no-repeat;
  background-position: -15px -422px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  cursor: ew-resize;
}
#winamp-chrome #audio-player-mount input[type="range"].bal:active::-webkit-slider-thumb {
  background-position: 0 -422px;
}
#winamp-chrome #audio-player-mount input[type="range"].bal::-moz-range-track {
  width: 38px;
  height: 14px;
  background: transparent;
  border: 0;
}
#winamp-chrome #audio-player-mount input[type="range"].bal::-moz-range-thumb {
  width: 14px;
  height: 11px;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/balance.png");
  background-repeat: no-repeat;
  background-position: -15px -422px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  cursor: ew-resize;
}
#winamp-chrome #audio-player-mount input[type="range"].bal:active::-moz-range-thumb {
  background-position: 0 -422px;
}

/* EQ / PL clutter toggles — overlaid at the canonical lower-right
   cluster (left=219, top=58). Sprite-sliced from shufrep.png (92x85):
     EQ normal       (0, 61)  23x12   (sprite art "EQ" off)
     EQ depressed    (46, 61) 23x12   (mid-press)
     EQ selected     (0, 73)  23x12   (toggled on, lit green)
     EQ sel+pressed  (46, 73) 23x12   (toggled on AND pressed)
     PL normal       (23, 61) 23x12
     PL depressed    (69, 61) 23x12
     PL selected     (23, 73) 23x12
     PL sel+pressed  (69, 73) 23x12
   aria-pressed=true selects the lit row; :active selects the pressed
   columns. Wiring lives in the existing inline IIFE that flips
   aria-pressed on click — no audio/* edits needed. */
#winamp-chrome .wa-clutter-bar {
  position: absolute;
  left: 219px;
  top: 58px;
  display: flex;
  gap: 0;
  padding: 0;
  margin: 0;
  background: transparent;
  border: 0;
}
#winamp-chrome .wa-clutter {
  width: 23px;
  height: 12px;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/shufrep.png");
  background-repeat: no-repeat;
  background-size: 92px 85px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  color: transparent;
  font-size: 0;
  line-height: 0;
  text-indent: -9999px;
  cursor: pointer;
  overflow: hidden;
}
#winamp-chrome .wa-clutter:focus-visible {
  outline: 1px dotted #FFCC33;
  outline-offset: 0;
}
#winamp-chrome #wa-eq                                    { background-position:    0px -61px; }
#winamp-chrome #wa-eq:active                             { background-position: -46px -61px; }
#winamp-chrome #wa-eq[aria-pressed="true"]               { background-position:    0px -73px; }
#winamp-chrome #wa-eq[aria-pressed="true"]:active        { background-position: -46px -73px; }
#winamp-chrome #wa-pl                                    { background-position: -23px -61px; }
#winamp-chrome #wa-pl:active                             { background-position: -69px -61px; }
#winamp-chrome #wa-pl[aria-pressed="true"]               { background-position: -23px -73px; }
#winamp-chrome #wa-pl[aria-pressed="true"]:active        { background-position: -69px -73px; }

/* Title-bar OAIDV clutter buttons — main.png paints the inactive
   column at canonical (10, 22, 8, 43). Five overlay hit-targets sit on
   top and swap to the SELECTED sprite from titlebar.png on :active.
   Coordinates per webamp/css/main-window.css + skinSprites.ts:
     O selected (304, 47) 8x8   top=25 left=10
     A selected (312, 55) 8x7   top=33 left=10
     I selected (320, 62) 8x7   top=40 left=10
     D selected (328, 69) 8x8   top=47 left=10
     V selected (336, 77) 8x7   top=55 left=10
   Buttons are aria-hidden because they are decorative on this site. */
#winamp-chrome .wa-clutter-vbar {
  position: absolute;
  left: 10px;
  top: 22px;
  width: 8px;
  height: 43px;
  display: block;
  pointer-events: none;
}
#winamp-chrome .wa-clutter-vbar .wa-clutter-vbtn { pointer-events: auto; }
#winamp-chrome .wa-clutter-vbtn {
  position: absolute;
  left: 0;
  width: 8px;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/titlebar.png");
  background-repeat: no-repeat;
  background-size: 344px 87px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  cursor: pointer;
  opacity: 0;
}
#winamp-chrome .wa-clutter-vbtn:active { opacity: 1; }
#winamp-chrome .wa-clutter-vbtn[data-clutter="o"] { top:  3px; height: 8px; background-position: -304px -47px; }
#winamp-chrome .wa-clutter-vbtn[data-clutter="a"] { top: 11px; height: 7px; background-position: -312px -55px; }
#winamp-chrome .wa-clutter-vbtn[data-clutter="i"] { top: 18px; height: 7px; background-position: -320px -62px; }
#winamp-chrome .wa-clutter-vbtn[data-clutter="d"] { top: 25px; height: 8px; background-position: -328px -69px; }
#winamp-chrome .wa-clutter-vbtn[data-clutter="v"] { top: 33px; height: 7px; background-position: -336px -77px; }

/* Title-bar wordmark — main.png paints "WINAMP" baked into the gradient
   titlebar art, but we re-render it from text.png so the live HTML
   produces a crisp, sprite-true wordmark instead of a smeared bitmap
   bake. The sprite-text observer fills .wa-wordmark with 6 text.png
   glyphs; the wrapper sits centered horizontally and vertically inside
   the 14px-tall titlebar (6px glyphs → top:4px). */
#winamp-chrome .wa-titlebar > .wa-wordmark {
  display: block;
  position: absolute;
  left: 100px;
  top: 4px;
  width: 75px;
  height: 6px;
  text-align: center;
  font-size: 0;
  line-height: 0;
}

/* Mono / stereo indicator — overlaid at canonical (212, 41) inside
   the chrome. Sprite-sliced from monoster.png (58x24):
     STEREO selected (0,  0) 29x12   (top-left, lit)
     MONO   selected (29, 0) 27x12   (top-right, lit)
     STEREO inactive (0, 12) 29x12   (bottom-left, dim)
     MONO   inactive (29,12) 27x12   (bottom-right, dim)
   The .wa-monoster span shows BOTH segments (mono left, stereo right).
   data-mode toggles which segment is "selected" (lit) vs inactive.
   Default rendering is a span using two ::before/::after layers from
   the same sprite — left half = stereo region (29 wide), right half
   = mono region (27 wide), totalling 56 wide. */
#winamp-chrome .wa-monoster {
  position: absolute;
  left: 212px;
  top: 41px;
  width: 56px;
  height: 12px;
  display: block;
  pointer-events: none;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/monoster.png");
  background-repeat: no-repeat;
  background-size: 58px 24px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
#winamp-chrome .wa-monoster::after {
  content: '';
  position: absolute;
  left: 29px;
  top: 0;
  width: 27px;
  height: 12px;
  background-image: url("../images/winamp-skin/base-2.91/monoster.png");
  background-repeat: no-repeat;
  background-size: 58px 24px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
/* stereo mode: left "stereo" lit, right "mono" inactive */
#winamp-chrome .wa-monoster[data-mode="stereo"]        { background-position:   0px   0px; }
#winamp-chrome .wa-monoster[data-mode="stereo"]::after { background-position: -29px -12px; }
/* mono mode: left "stereo" inactive, right "mono" lit */
#winamp-chrome .wa-monoster[data-mode="mono"]          { background-position:   0px -12px; }
#winamp-chrome .wa-monoster[data-mode="mono"]::after   { background-position: -29px   0px; }

/* Position-bar cover — main.png paints a default position-bar art at
   (16, 72, 248, 10) that includes a thumb sprite mid-track, leaving an
   orange band visible because the audio module exposes no seek input.
   We overlay posbar.png cropped to its empty-track region (0, 0, 248,
   10) at the canonical x=16, y=72 inside #winamp-chrome — that's the
   "no thumb" empty-track sprite that was always shown when Winamp had
   no media loaded. The 29x10 thumb sprite at posbar.png x=248 stays
   off-screen so no thumb is rendered. */
#winamp-chrome .wa-posbar {
  position: absolute;
  left: 16px;
  top: 72px;
  width: 248px;
  height: 10px;
  display: block;
  pointer-events: none;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/posbar.png");
  background-repeat: no-repeat;
  background-position: 0 0;
  background-size: 307px 10px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}

/* Position-bar input — overlays .wa-posbar at the same canonical rect.
   audio/player.js exposes no seek API, so the input is decorative
   (pointer-events: none below). The runnable-track paints the empty
   crop sprite (0, 0, 248, 10) from posbar.png; the thumb (29x10 from
   posbar.png at sx=248 normal, sx=278 pressed) is gated on
   body.track-loaded so it only renders once the user has hit play. */
#winamp-chrome input[type="range"][data-role="posbar"] {
  position: absolute;
  left: 16px;
  top: 72px;
  width: 248px;
  height: 10px;
  margin: 0;
  padding: 0;
  border: 0;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  pointer-events: none;
  cursor: default;
}
#winamp-chrome input[type="range"][data-role="posbar"]::-webkit-slider-runnable-track {
  width: 248px;
  height: 10px;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/posbar.png");
  background-repeat: no-repeat;
  background-position: 0 0;
  background-size: 307px 10px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
#winamp-chrome input[type="range"][data-role="posbar"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 29px;
  height: 10px;
  margin-top: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/posbar.png");
  background-repeat: no-repeat;
  background-position: -248px 0;
  background-size: 307px 10px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  visibility: hidden;
}
#winamp-chrome input[type="range"][data-role="posbar"]:active::-webkit-slider-thumb {
  background-position: -278px 0;
}
#winamp-chrome input[type="range"][data-role="posbar"]::-moz-range-track {
  width: 248px;
  height: 10px;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/posbar.png");
  background-repeat: no-repeat;
  background-position: 0 0;
  background-size: 307px 10px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
#winamp-chrome input[type="range"][data-role="posbar"]::-moz-range-thumb {
  width: 29px;
  height: 10px;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/posbar.png");
  background-repeat: no-repeat;
  background-position: -248px 0;
  background-size: 307px 10px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  visibility: hidden;
}
#winamp-chrome input[type="range"][data-role="posbar"]:active::-moz-range-thumb {
  background-position: -278px 0;
}
body.track-loaded #winamp-chrome input[type="range"][data-role="posbar"]::-webkit-slider-thumb {
  visibility: visible;
}
body.track-loaded #winamp-chrome input[type="range"][data-role="posbar"]::-moz-range-thumb {
  visibility: visible;
}

/* Slider tooltips — bitmap-font glyph rows rendered above the volume
   and balance sliders by the inline IIFE in index.html. Visible only
   while the slider is being interacted with (input event); hides 1200ms
   after blur. Position is absolute inside #winamp-chrome at the
   canonical x of each slider, top=43 (~14 px above the slider track at
   top=57). The element itself only provides positioning + clipping;
   glyph cells inside come from the shared .sprite-text class
   (text.png 5x6 cells). */
#winamp-chrome .wa-tooltip {
  position: absolute;
  top: 43px;
  height: 6px;
  display: block;
  margin: 0;
  padding: 0;
  background: transparent;
  border: 0;
  font-size: 0;
  line-height: 0;
  color: transparent;
  pointer-events: none;
  white-space: nowrap;
  z-index: 2;
}
#winamp-chrome .wa-tooltip[hidden] { display: none; }
#winamp-chrome .wa-tooltip[data-for="vol"] { left: 107px; width: 100px; }
#winamp-chrome .wa-tooltip[data-for="bal"] { left: 130px; width: 130px; }

/* SFX toggle moved to the right-sidebar #fx-toggles-mount widget so it
   sits next to CRT + STARS as a third .btn sibling. The element keeps
   its byte-identical id+class so the inline wiring (and audio/sfx.js
   localStorage key) remain untouched. No extra widget styling needed —
   the shared .btn class above paints it the same as its siblings. */

/* ----------------------------------------------------------------------
   Equalizer window — sprite-sliced from eqmain.png. The full sheet is
   275x315; the top 116px is the EQ window background (titlebar + preset
   row + 10 fader tracks + curve area). Below y=116 lives the sprite
   strip for fader thumbs and other controls. Per the public spec:

     fader thumb normal  = 11x11 at (1, 164)
     fader thumb pressed = 11x11 at (1, 176)

   The 10 fader inputs (7 wired + 3 decorative) are absolutely positioned
   over the painted track area at canonical x coordinates. The eqmain.png
   art draws the recessed track grooves so we don't paint our own.
   ---------------------------------------------------------------------- */
#winamp-eq {
  position: relative;
  width: 275px;
  height: 116px;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/eqmain.png");
  background-repeat: no-repeat;
  background-position: 0 0;
  background-size: 275px 315px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  color: transparent;
  font-size: 0;
  line-height: 0;
}
#winamp-eq.shaded {
  height: 14px;
  background-image: url("../images/winamp-skin/base-2.91/eq_ex.png");
  background-repeat: no-repeat;
  background-position: 0 0;
  background-size: 275px 82px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
#winamp-eq.shaded > :not(.eq-titlebar) { display: none !important; }
#winamp-eq.shaded .eq-titlebar { background-image: none; }
#winamp-eq[hidden] { display: none; }

/* Hide every chunk of the existing EQ markup whose look is already
   painted by eqmain.png (preset row, dB scale, fader labels). We keep
   the inputs as the only interactive overlays. */
#winamp-eq .eq-presets,
#winamp-eq .eq-scale,
#winamp-eq .eq-fader-label { display: none; }

#winamp-eq .eq-fader-row {
  position: absolute;
  left: 0;
  top: 0;
  width: 275px;
  height: 116px;
  display: block;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  box-shadow: none;
  pointer-events: none;
}
#winamp-eq .eq-faders,
#winamp-eq .eq-faders-decor {
  display: contents;
}
#winamp-eq .eq-fader { pointer-events: auto; }

/* Per-band fader cell — 14 wide, 63 tall, top edge at y=38 of the EQ
   window. 10 bands at 18px pitch starting at x=78 (matches eqmain.png
   painted track positions). 7 wired bands first, then 3 decorative. */
#winamp-eq .eq-fader {
  position: absolute;
  top: 38px;
  width: 14px;
  height: 63px;
  margin: 0;
  padding: 0;
  display: block;
  background: transparent;
  flex: 0 0 auto;
  min-width: 0;
}
#winamp-eq .eq-faders > .eq-fader:nth-child(1) { left: 78px; }
#winamp-eq .eq-faders > .eq-fader:nth-child(2) { left: 96px; }
#winamp-eq .eq-faders > .eq-fader:nth-child(3) { left: 114px; }
#winamp-eq .eq-faders > .eq-fader:nth-child(4) { left: 132px; }
#winamp-eq .eq-faders > .eq-fader:nth-child(5) { left: 150px; }
#winamp-eq .eq-faders > .eq-fader:nth-child(6) { left: 168px; }
#winamp-eq .eq-faders > .eq-fader:nth-child(7) { left: 186px; }
#winamp-eq .eq-faders-decor > .eq-fader:nth-child(1) { left: 204px; }
#winamp-eq .eq-faders-decor > .eq-fader:nth-child(2) { left: 222px; }
#winamp-eq .eq-faders-decor > .eq-fader:nth-child(3) { left: 240px; }

#winamp-eq .eq-fader .eq-fader-track {
  position: absolute;
  inset: 0;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  box-shadow: none;
}

/* Decorative fader thumb — placeholder sprite for the bands that don't
   have a wired native input. Sprite-sliced from eqmain.png. */
#winamp-eq .eq-fader .eq-fader-thumb {
  position: absolute;
  left: 1px;
  top: 26px;
  width: 11px;
  height: 11px;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/eqmain.png");
  background-repeat: no-repeat;
  background-position: -1px -164px;
  background-size: 275px 315px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  border: 0;
}

/* Wired faders — native vertical range inputs. Track is transparent
   (eqmain.png paints the groove); the thumb is sprite-sliced. */
#winamp-eq .eq-fader input[type="range"] {
  -webkit-appearance: slider-vertical;
  appearance: slider-vertical;
  writing-mode: bt-lr;
  width: 14px;
  height: 63px;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: ns-resize;
}
#winamp-eq .eq-fader input[type="range"]::-webkit-slider-runnable-track {
  width: 14px;
  height: 63px;
  background: transparent;
  border: 0;
}
#winamp-eq .eq-fader input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 11px;
  height: 11px;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/eqmain.png");
  background-repeat: no-repeat;
  background-position: -1px -164px;
  background-size: 275px 315px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  cursor: ns-resize;
}
#winamp-eq .eq-fader input[type="range"]:active::-webkit-slider-thumb {
  background-position: -1px -176px;
}
#winamp-eq .eq-fader input[type="range"]::-moz-range-track {
  width: 14px;
  height: 63px;
  background: transparent;
  border: 0;
}
#winamp-eq .eq-fader input[type="range"]::-moz-range-thumb {
  width: 11px;
  height: 11px;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/eqmain.png");
  background-repeat: no-repeat;
  background-position: -1px -164px;
  background-size: 275px 315px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  cursor: ns-resize;
}
#winamp-eq .eq-fader input[type="range"]:active::-moz-range-thumb {
  background-position: -1px -176px;
}
#winamp-eq .eq-fader input[type="range"]:focus-visible {
  outline: 1px dotted #FFCC33;
  outline-offset: 0;
}

/* ----------------------------------------------------------------------
   EQ window chrome — sprites from eqmain.png (275×315) at the canonical
   captbaritone/webamp coordinates (skinSprites.ts EQMAIN block):

     EQ_TITLE_BAR             (0, 149) 275×14   inactive titlebar strip
     EQ_TITLE_BAR_SELECTED    (0, 134) 275×14   active titlebar strip
     EQ_CLOSE_BUTTON          (0, 116)   9×9
     EQ_CLOSE_BUTTON_ACTIVE   (0, 125)   9×9
     EQ_ON_BUTTON              (10, 119) 26×12   normal,  unselected
     EQ_ON_BUTTON_DEPRESSED   (128, 119) 26×12   pressed, unselected
     EQ_ON_BUTTON_SELECTED     (69, 119) 26×12   normal,  selected (lit)
     EQ_ON_BUTTON_SEL_DEPR    (187, 119) 26×12   pressed, selected
     EQ_AUTO_BUTTON            (36, 119) 32×12
     EQ_AUTO_BUTTON_DEPRESSED (154, 119) 32×12
     EQ_AUTO_BUTTON_SELECTED   (95, 119) 32×12
     EQ_AUTO_BUTTON_SEL_DEPR  (213, 119) 32×12
     EQ_PRESETS_BUTTON        (224, 164) 44×12
     EQ_PRESETS_BUTTON_SELECT (224, 176) 44×12   used while menu is open
     EQ_GRAPH_BACKGROUND        (0, 294) 113×19   decorative spectrum well

   On-window placement (per equalizer-window.css):
     titlebar                     (  0,  0) 275×14
     close button                 (264,  3)   9×9
     ON   button                  ( 14, 18)  26×12
     AUTO button                  ( 40, 18)  32×12
     PRESETS button               (217, 18)  44×12
     EQ graph background          ( 86, 17) 113×19
     preamp slider track          ( 21, 38)  14×63   (decorative here)
   ---------------------------------------------------------------------- */

#winamp-eq .eq-titlebar {
  position: absolute;
  left: 0;
  top: 0;
  width: 275px;
  height: 14px;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/eqmain.png");
  background-repeat: no-repeat;
  background-position: 0 -134px;
  background-size: 275px 315px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
#winamp-eq .eq-titlebar.is-inactive {
  background-position: 0 -149px;
}
#winamp-eq .eq-titlebar-close {
  position: absolute;
  left: 264px;
  top: 3px;
  width: 9px;
  height: 9px;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/eqmain.png");
  background-repeat: no-repeat;
  background-position: 0 -116px;
  background-size: 275px 315px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  font-size: 0;
  line-height: 0;
  color: transparent;
  cursor: pointer;
  overflow: hidden;
}
#winamp-eq .eq-titlebar-close:active { background-position: 0 -125px; }
#winamp-eq .eq-titlebar-shade {
  position: absolute;
  left: 254px;
  top: 3px;
  width: 9px;
  height: 9px;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/eq_ex.png");
  background-repeat: no-repeat;
  background-position: -1px -47px;
  background-size: 275px 82px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  cursor: pointer;
}
#winamp-eq .eq-titlebar-shade::before {
  content: '';
  position: absolute;
  top: -5px;
  right: -1px;
  bottom: -5px;
  left: -5px;
  background: transparent;
}
#winamp-eq.shaded .eq-titlebar-shade { background-position: -1px -38px; }
#winamp-eq .eq-shade-ui {
  display: none;
  position: absolute;
  left: 14px;
  top: 4px;
  height: 6px;
  gap: 8px;
  pointer-events: none;
}
#winamp-eq.shaded .eq-shade-ui {
  display: flex;
  align-items: center;
}

/* ON / AUTO / PRESETS sprite-state buttons. Specificity beats the
   #winamp-eq base background-image inheritance because each rule sets
   background-image explicitly. aria-pressed=true selects the lit row. */
#winamp-eq .eq-on,
#winamp-eq .eq-auto,
#winamp-eq .eq-presets-btn {
  position: absolute;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/eqmain.png");
  background-repeat: no-repeat;
  background-size: 275px 315px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  font-size: 0;
  line-height: 0;
  color: transparent;
  text-indent: -9999px;
  overflow: hidden;
  cursor: pointer;
}
#winamp-eq .eq-on   { left:  14px; top: 18px; width: 26px; height: 12px; }
#winamp-eq .eq-auto { left:  40px; top: 18px; width: 32px; height: 12px; }
#winamp-eq .eq-presets-btn { left: 217px; top: 18px; width: 44px; height: 12px; }

#winamp-eq .eq-on                                   { background-position:  -10px -119px; }
#winamp-eq .eq-on:active                            { background-position: -128px -119px; }
#winamp-eq .eq-on[aria-pressed="true"]              { background-position:  -69px -119px; }
#winamp-eq .eq-on[aria-pressed="true"]:active       { background-position: -187px -119px; }

#winamp-eq .eq-auto                                 { background-position:  -36px -119px; }
#winamp-eq .eq-auto:active                          { background-position: -154px -119px; }
#winamp-eq .eq-auto[aria-pressed="true"]            { background-position:  -95px -119px; }
#winamp-eq .eq-auto[aria-pressed="true"]:active     { background-position: -213px -119px; }

#winamp-eq .eq-presets-btn                          { background-position: -224px -164px; }
#winamp-eq .eq-presets-btn:active,
#winamp-eq .eq-presets-btn[aria-expanded="true"]    { background-position: -224px -176px; }

#winamp-eq .eq-on:focus-visible,
#winamp-eq .eq-auto:focus-visible,
#winamp-eq .eq-presets-btn:focus-visible,
#winamp-eq .eq-titlebar-close:focus-visible,
#winamp-eq .eq-titlebar-shade:focus-visible {
  outline: 1px dotted #FFCC33;
  outline-offset: 0;
}

/* Decorative EQ spectrum well — paints the 113×19 graph background sprite
   at the canonical (86, 17) slot. Pure overlay, no live spectrum drawn. */
#winamp-eq .eq-graph {
  position: absolute;
  left: 86px;
  top: 17px;
  width: 113px;
  height: 19px;
  pointer-events: none;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/eqmain.png");
  background-repeat: no-repeat;
  background-position: 0 -294px;
  background-size: 275px 315px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}

/* Decorative preamp slider — sits over the preamp groove painted into the
   eqmain.png background at (21, 38). The thumb sprite reuses the standard
   EQ slider thumb at eqmain (0, 164) 11×11. No interaction wired; this is
   decorative because the audio graph has no preamp node. */
#winamp-eq .eq-preamp {
  position: absolute;
  left: 21px;
  top: 38px;
  width: 14px;
  height: 63px;
  pointer-events: none;
  background: transparent;
}
#winamp-eq .eq-preamp .eq-preamp-track {
  position: absolute;
  inset: 0;
  background: transparent;
}
#winamp-eq .eq-preamp .eq-preamp-thumb {
  position: absolute;
  left: 1px;
  top: 26px;
  width: 11px;
  height: 11px;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/eqmain.png");
  background-repeat: no-repeat;
  background-position: 0 -164px;
  background-size: 275px 315px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}

/* PRESETS dropdown menu. Positioned just below the PRESETS button at
   (217, 30); width auto-sized to the longest sprite-text label. Solid
   black background with a 1px panel border — no CSS gradients (forbidden
   inside #winamp-eq). Items are sprite-text rendered (text.png 5x6) so
   no font-family declaration is needed inside this scope. */
#winamp-eq .eq-presets-menu {
  position: absolute;
  left: 217px;
  top: 30px;
  min-width: 70px;
  padding: 2px 0;
  margin: 0;
  background-color: #000000;
  border: 1px solid #00FF66;
  z-index: 5;
  font-size: 0;
  line-height: 0;
  color: transparent;
}
#winamp-eq .eq-presets-menu[hidden] { display: none; }
#winamp-eq .eq-preset-item {
  display: block;
  padding: 2px 4px;
  cursor: pointer;
  background-color: transparent;
  white-space: nowrap;
  font-size: 0;
  line-height: 0;
}
#winamp-eq .eq-preset-item:hover {
  background-color: #00331a;
}

/* ───────────────────────────────────────────────────────────────────────
   Main-window titlebar — sprites from titlebar.png (344×87).
   Active strip: sx=27, sy=0, 275×14.   Inactive strip: sx=27, sy=15.
   Top-left 27×27 holds the bolt + min/shade/close cluster:
     bolt active   (0,  0) 9×9    bolt inactive (0,  9) 9×9
     min  normal   (9,  0) 9×9    min  pressed  (9,  9) 9×9
     shade normal  (0, 18) 9×9    shade pressed (9, 18) 9×9
     close normal  (18, 0) 9×9    close pressed (18, 9) 9×9
   Drawn at canonical main-window coords:
     bolt   (6,  3)        min  (244, 3)
     shade  (254, 3)       close (264, 3)
   The .wa-titlebar element re-paints the active strip on top of main.png
   so the same 14px row can be swapped active/inactive in a later run by
   toggling .is-inactive without touching main.png. The wordmark child
   (sprite-rendered "WINAMP" from text.png) keeps its existing rule
   above; this block adds the bolt, drag-handle marker, and the three
   right-side buttons. Click behaviour for min/shade/close is intentionally
   not wired in this run — they show their pressed sprite on :active and
   nothing else. */
#winamp-chrome .wa-titlebar {
  position: relative;
  width: 275px;
  height: 14px;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/titlebar.png");
  background-repeat: no-repeat;
  background-position: -27px 0;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
/* Future-proof: a later run flips this class to swap active → inactive
   strip without re-deriving the offset.
#winamp-chrome .wa-titlebar.is-inactive {
  background-position: -27px -15px;
}
*/
#winamp-chrome .wa-titlebar > .wa-bolt {
  display: block;
  position: absolute;
  left: 6px;
  top: 3px;
  width: 9px;
  height: 9px;
  background-image: url("../images/winamp-skin/base-2.91/titlebar.png");
  background-repeat: no-repeat;
  background-position: 0 0;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  pointer-events: none;
}
/* Future-proof inactive bolt: background-position: 0 -9px; */
#winamp-chrome .wa-titlebar > .wa-title[data-role="drag-handle"] {
  display: block;
  position: absolute;
  left: 16px;
  top: 3px;
  width: 224px;
  height: 9px;
  background: transparent;
  cursor: move;
}
#winamp-chrome .wa-titlebar > .wa-min,
#winamp-chrome .wa-titlebar > .wa-shade,
#winamp-chrome .wa-titlebar > .wa-close {
  display: block;
  position: absolute;
  top: 3px;
  width: 9px;
  height: 9px;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/titlebar.png");
  background-repeat: no-repeat;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  cursor: pointer;
}
#winamp-chrome .wa-titlebar > .wa-min   { left: 244px; background-position:  -9px   0; }
#winamp-chrome .wa-titlebar > .wa-shade { left: 254px; background-position:   0  -18px; }
#winamp-chrome .wa-titlebar > .wa-close { left: 264px; background-position: -18px   0; }
#winamp-chrome .wa-titlebar > .wa-shade::before {
  content: '';
  position: absolute;
  top: -5px;
  right: -1px;
  bottom: -5px;
  left: -1px;
  background: transparent;
}
#winamp-chrome .wa-titlebar > .wa-min:active   { background-position:  -9px  -9px; }
#winamp-chrome .wa-titlebar > .wa-shade:active { background-position:  -9px -18px; }
#winamp-chrome .wa-titlebar > .wa-close:active { background-position: -18px  -9px; }
#winamp-chrome.shaded .wa-titlebar > .wa-shade { background-position: 0 -27px; }
#winamp-chrome.shaded .wa-titlebar > .wa-shade:active { background-position: -9px -27px; }
#winamp-chrome .wa-titlebar > .wa-min:focus-visible,
#winamp-chrome .wa-titlebar > .wa-shade:focus-visible,
#winamp-chrome .wa-titlebar > .wa-close:focus-visible {
  outline: 1px dotted #FFCC33;
  outline-offset: 0;
}
#winamp-chrome .wa-titlebar > .wa-shade-ui {
  display: none;
  position: absolute;
  left: 0;
  top: 0;
  width: 275px;
  height: 14px;
  pointer-events: none;
}
#winamp-chrome.shaded .wa-titlebar > .wa-shade-ui { display: block; }
#winamp-chrome .wa-shade-track {
  position: absolute;
  left: 26px;
  top: 4px;
  width: 136px;
  height: 6px;
  overflow: hidden;
  white-space: nowrap;
}
#winamp-chrome .wa-shade-track > span {
  display: inline-block;
  transform: translateX(0);
  will-change: transform;
}
#winamp-chrome .wa-shade-mini {
  position: absolute;
  top: 2px;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/titlebar.png");
  background-repeat: no-repeat;
  background-size: 344px 87px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  cursor: pointer;
  pointer-events: auto;
}
#winamp-chrome .wa-shade-mini[data-act="prev"]  { left: 169px; width: 7px;  height: 10px; background-position: -196px -29px; }
#winamp-chrome .wa-shade-mini[data-act="play"]  { left: 176px; width: 10px; height: 10px; background-position: -203px -29px; }
#winamp-chrome .wa-shade-mini[data-act="pause"] { left: 186px; width: 9px;  height: 10px; background-position: -213px -29px; }
#winamp-chrome .wa-shade-mini[data-act="stop"]  { left: 195px; width: 9px;  height: 10px; background-position: -222px -29px; }
#winamp-chrome .wa-shade-mini[data-act="next"]  { left: 204px; width: 10px; height: 10px; background-position: -231px -29px; }
#winamp-chrome .wa-shade-mini[data-act="prev"]:active  { background-position: -196px -42px; }
#winamp-chrome .wa-shade-mini[data-act="play"]:active  { background-position: -203px -42px; }
#winamp-chrome .wa-shade-mini[data-act="pause"]:active { background-position: -213px -42px; }
#winamp-chrome .wa-shade-mini[data-act="stop"]:active  { background-position: -222px -42px; }
#winamp-chrome .wa-shade-mini[data-act="next"]:active  { background-position: -231px -42px; }
#winamp-chrome .wa-shade-viz {
  position: absolute;
  left: 79px;
  top: 5px;
  width: 38px;
  height: 5px;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}

/* ----------------------------------------------------------------------
   Playlist window — sprite-sliced from pledit.png (280×186) and
   shufrep.png (92×85). Coordinates per webamp/js/skinSprites.ts PLEDIT
   + SHUFREP blocks; on-window placement per webamp/css/playlist-window.css
   default 275×232 layout.

   Tile-fill technique: every region that has to repeat a single source
   sprite (titlebar gap fills, side strips) is wrapped in an
   overflow:hidden parent with N inline-block / block child <i> cells,
   each cell sized exactly to one tile. The last cell is clipped by the
   parent box. Repeating the whole sheet via background-repeat would
   surface adjacent sprites that share columns/rows on the source sheet;
   the overflow + child-cell pattern keeps every painted pixel inside
   the desired sprite. Zero CSS gradients live inside this scope; all
   bevels / chrome art are baked into the source bitmaps. No font-family
   declaration either — every visible text inside #winamp-pl is rendered
   as text.png 5×6 sprite glyphs by the inline playlistInit IIFE via
   window.__waRenderText.
   ---------------------------------------------------------------------- */
#winamp-pl {
  position: relative;
  width: 275px;
  height: 232px;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: transparent;
  color: transparent;
  font-size: 0;
  line-height: 0;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  user-select: none;
}
#winamp-pl.shaded {
  height: 14px;
  background-image: url("../images/winamp-skin/base-2.91/pledit.png");
  background-repeat: repeat-x;
  background-position: -72px -57px;
  background-size: 280px 186px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
#winamp-pl.shaded > :not(.pl-titlebar) { display: none !important; }
#winamp-pl[hidden] { display: none; }

/* Titlebar — 275×20 painted from PLEDIT active sprites:
     PLAYLIST_TOP_LEFT_SELECTED            (  0,  0, 25, 20) at x=0
     PLAYLIST_TOP_TILE_SELECTED            (127,  0, 25, 20) tiled across gaps
     PLAYLIST_TITLE_BAR_SELECTED           ( 26,  0, 100, 20) centered at x=87
     PLAYLIST_TOP_RIGHT_CORNER_SELECTED    (153,  0, 25, 20) at x=250
     PLAYLIST_CLOSE_SELECTED               ( 52, 42,  9,  9) close button */
#winamp-pl .pl-titlebar {
  position: absolute;
  left: 0;
  top: 0;
  width: 275px;
  height: 20px;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/pledit.png");
  background-repeat: no-repeat;
  background-position: 0 0;
  background-size: 280px 186px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
#winamp-pl .pl-titlebar > .pl-tb-corner,
#winamp-pl .pl-titlebar > .pl-tb-fill,
#winamp-pl .pl-titlebar > .pl-tb-title-mid {
  display: none;
}
#winamp-pl .pl-tb-corner {
  position: absolute;
  top: 0;
  width: 25px;
  height: 20px;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/pledit.png");
  background-repeat: no-repeat;
  background-size: 280px 186px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
#winamp-pl .pl-tb-corner-l { left: 0;     background-position:    0    0; }
#winamp-pl .pl-tb-corner-r { left: 250px; background-position: -153px   0; }
#winamp-pl .pl-tb-title-mid {
  position: absolute;
  left: 87px;
  top: 0;
  width: 100px;
  height: 20px;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/pledit.png");
  background-repeat: no-repeat;
  background-position: -26px 0;
  background-size: 280px 186px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
#winamp-pl .pl-tb-fill {
  position: absolute;
  top: 0;
  height: 20px;
  display: block;
  overflow: hidden;
  font-size: 0;
  line-height: 0;
}
#winamp-pl .pl-tb-fill[data-side="l"] { left:  25px; width: 62px; }
#winamp-pl .pl-tb-fill[data-side="r"] { left: 187px; width: 63px; }
#winamp-pl .pl-tb-fill > i {
  display: inline-block;
  width: 25px;
  height: 20px;
  vertical-align: top;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/pledit.png");
  background-repeat: no-repeat;
  background-position: -127px 0;
  background-size: 280px 186px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
#winamp-pl .pl-titlebar-close {
  position: absolute;
  right: 3px;
  top: 3px;
  width: 9px;
  height: 9px;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/pledit.png");
  background-repeat: no-repeat;
  background-position: -52px -42px;
  background-size: 280px 186px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  font-size: 0;
  line-height: 0;
  color: transparent;
  cursor: pointer;
  overflow: hidden;
}
#winamp-pl .pl-titlebar-shade {
  position: absolute;
  right: 13px;
  top: 3px;
  width: 9px;
  height: 9px;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/pledit.png");
  background-repeat: no-repeat;
  background-position: -62px -42px;
  background-size: 280px 186px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  cursor: pointer;
}
#winamp-pl .pl-titlebar-shade::before {
  content: '';
  position: absolute;
  top: -5px;
  right: -1px;
  bottom: -5px;
  left: -5px;
  background: transparent;
}
#winamp-pl.shaded .pl-titlebar-shade { background-position: -150px -42px; }
#winamp-pl .pl-shade-title {
  display: none;
  position: absolute;
  left: 95px;
  top: 4px;
  width: 90px;
  height: 6px;
  overflow: hidden;
}
#winamp-pl.shaded .pl-titlebar { height: 14px; }
#winamp-pl.shaded .pl-titlebar {
  background-image: none;
}
#winamp-pl.shaded .pl-titlebar > :not(.pl-titlebar-shade):not(.pl-shade-title) {
  display: none !important;
}
#winamp-pl.shaded .pl-shade-title { display: block; }

/* Side strips — middle area y=20..194 (174 tall). Left=12 wide tile
   (PLAYLIST_LEFT_TILE  0, 42, 12, 29); right=20 wide tile
   (PLAYLIST_RIGHT_TILE 31, 42, 20, 29). Six block child <i> cells stack
   vertically (6 × 29 = 174); last cell clipped by overflow:hidden. */
#winamp-pl .pl-side {
  position: absolute;
  top: 20px;
  height: 174px;
  display: block;
  overflow: hidden;
  font-size: 0;
  line-height: 0;
}
#winamp-pl .pl-side-l { left: 0;     width: 12px; }
#winamp-pl .pl-side-r { left: 255px; width: 20px; }
#winamp-pl .pl-side > i {
  display: block;
  width: 100%;
  height: 29px;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/pledit.png");
  background-repeat: no-repeat;
  background-size: 280px 186px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
#winamp-pl .pl-side-l > i { background-position:    0  -42px; }
#winamp-pl .pl-side-r > i { background-position: -31px -42px; }

/* Bottom strip — y=194..232 (38 tall). Two non-tiled halves:
     PLAYLIST_BOTTOM_LEFT_CORNER  (  0, 72, 125, 38) at x=0
     PLAYLIST_BOTTOM_RIGHT_CORNER (126, 72, 150, 38) at x=125 */
#winamp-pl .pl-bottom {
  position: absolute;
  left: 0;
  top: 194px;
  width: 275px;
  height: 38px;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/pledit.png");
  background-repeat: no-repeat;
  background-position: 0 -72px;
  background-size: 280px 186px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
#winamp-pl .pl-bottom-l,
#winamp-pl .pl-bottom-r {
  position: absolute;
  top: 0;
  height: 38px;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/pledit.png");
  background-repeat: no-repeat;
  background-size: 280px 186px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
}
#winamp-pl .pl-bottom > .pl-bottom-l,
#winamp-pl .pl-bottom > .pl-bottom-r {
  display: none;
}
#winamp-pl .pl-bottom-l { left:   0; width: 125px; background-position:    0  -72px; }
#winamp-pl .pl-bottom-r { left: 125px; width: 150px; background-position: -126px -72px; }

/* List area — between the side strips with 3px top padding so the first
   row lines up with the titlebar's bottom recess (matches webamp's
   .playlist-middle-center `padding: 3px 0`). The inner wrapper drives
   scroll via translateY; the parent clips. */
#winamp-pl .pl-list {
  position: absolute;
  left: 12px;
  top: 23px;
  width: 243px;
  height: 168px;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: #000000;
  overflow: hidden;
  font-size: 0;
  line-height: 0;
  color: transparent;
  cursor: default;
}
#winamp-pl .pl-list-inner {
  position: relative;
  width: 100%;
  will-change: transform;
}
#winamp-pl .pl-row {
  position: relative;
  height: 13px;
  margin: 0;
  padding: 0 3px;
  font-size: 0;
  line-height: 0;
  white-space: nowrap;
  overflow: hidden;
  background-color: transparent;
  display: flex;
  align-items: center;
}
#winamp-pl .pl-row-selected {
  background-color: #002A5C;
}
#winamp-pl .pl-row .pl-row-text { display: inline-block; }

/* Scrollbar — 8 wide thumb sliding inside the right-tile groove. The
   right tile (bg position -31, -42) bakes the empty groove into the
   side strip at element x=255+5=260. Thumb sprite 8x18 from
   PLAYLIST_SCROLL_HANDLE (52, 53). Selected (drag) variant at (61, 53). */
#winamp-pl .pl-scrollbar {
  position: absolute;
  left: 260px;
  top: 23px;
  width: 8px;
  height: 168px;
  background: transparent;
  pointer-events: none;
}
#winamp-pl .pl-scroll-thumb {
  position: absolute;
  left: 0;
  top: 0;
  width: 8px;
  height: 18px;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/pledit.png");
  background-repeat: no-repeat;
  background-position: -52px -53px;
  background-size: 280px 186px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  cursor: ns-resize;
  pointer-events: auto;
}
#winamp-pl .pl-scroll-thumb.is-dragging,
#winamp-pl .pl-scroll-thumb:active {
  background-position: -61px -53px;
}

/* SHUFFLE / REPEAT sprite states from shufrep.png (92×85). Both buttons
   are 15 tall (NOT 12 like the EQ/PL clutter further down the same
   sheet). aria-pressed="true" selects the lit row; :active selects the
   pressed row. Position in the bottom-right region of the playlist. */
#winamp-pl .pl-shuffle,
#winamp-pl .pl-repeat {
  position: absolute;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../images/winamp-skin/base-2.91/shufrep.png");
  background-repeat: no-repeat;
  background-size: 92px 85px;
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  font-size: 0;
  line-height: 0;
  color: transparent;
  cursor: pointer;
  overflow: hidden;
}
#winamp-pl .pl-shuffle { left: 164px; top: 209px; width: 47px; height: 15px; }
#winamp-pl .pl-repeat  { left: 212px; top: 209px; width: 28px; height: 15px; }
#winamp-pl .pl-shuffle                              { background-position: -28px   0; }
#winamp-pl .pl-shuffle:active                       { background-position: -28px -15px; }
#winamp-pl .pl-shuffle[aria-pressed="true"]         { background-position: -28px -30px; }
#winamp-pl .pl-shuffle[aria-pressed="true"]:active  { background-position: -28px -45px; }
#winamp-pl .pl-repeat                               { background-position:    0    0; }
#winamp-pl .pl-repeat:active                        { background-position:    0  -15px; }
#winamp-pl .pl-repeat[aria-pressed="true"]          { background-position:    0  -30px; }
#winamp-pl .pl-repeat[aria-pressed="true"]:active   { background-position:    0  -45px; }

#winamp-pl .pl-titlebar-close:focus-visible,
#winamp-pl .pl-titlebar-shade:focus-visible,
#winamp-pl .pl-shuffle:focus-visible,
#winamp-pl .pl-repeat:focus-visible {
  outline: 1px dotted #FFCC33;
  outline-offset: 0;
}

/* Time + track count — text.png 5×6 glyphs via window.__waRenderText.
   Positioned inside the bottom-strip region (y >= 194). The shared
   .sprite-glyph + .sprite-text rules (defined further up) paint each
   character cell from text.png. */
#winamp-pl .pl-time-display {
  position: absolute;
  left: 96px;
  top: 213px;
  height: 6px;
  font-size: 0;
  line-height: 0;
  color: transparent;
  white-space: nowrap;
  display: none;
}
#winamp-pl .pl-track-count {
  position: absolute;
  left: 8px;
  top: 213px;
  height: 6px;
  font-size: 0;
  line-height: 0;
  color: transparent;
  white-space: nowrap;
  display: none;
}

/* ----------------------------------------------------------------------
   Draggable window roots — the three Winamp windows are reparented at
   runtime into #winamp-root (a direct <body> child) and pinned via
   position: fixed so their (x, y) is viewport-relative. Inline style
   writes from the windowDragInit IIFE in index.html drive left/top;
   z-index: 50 floats the stack above the starfield/CRT canvases (which
   sit at z-index: 0/1). margin: 0 neutralises any residual stack-layout
   margins that were in force while these windows lived inside
   #winamp-stack. The drag handle is the full titlebar on each window;
   child glyph buttons (shade/close/min) keep their own cursor: pointer
   rules so only the bare titlebar region shows cursor: move.
   ---------------------------------------------------------------------- */
#winamp-root {
  position: static;
}
#winamp-chrome,
#winamp-eq,
#winamp-pl {
  position: fixed;
  z-index: 50;
  margin: 0;
}
#winamp-eq .eq-titlebar,
#winamp-pl .pl-titlebar {
  cursor: move;
}
