aboutsummaryrefslogtreecommitdiff
path: root/working/music-svg-app-design/2026-07-19-music-config-ui-remodel-spec.org
diff options
context:
space:
mode:
Diffstat (limited to 'working/music-svg-app-design/2026-07-19-music-config-ui-remodel-spec.org')
-rw-r--r--working/music-svg-app-design/2026-07-19-music-config-ui-remodel-spec.org923
1 files changed, 923 insertions, 0 deletions
diff --git a/working/music-svg-app-design/2026-07-19-music-config-ui-remodel-spec.org b/working/music-svg-app-design/2026-07-19-music-config-ui-remodel-spec.org
new file mode 100644
index 00000000..6e68e104
--- /dev/null
+++ b/working/music-svg-app-design/2026-07-19-music-config-ui-remodel-spec.org
@@ -0,0 +1,923 @@
+#+TITLE: Music Config UI Remodel — Spec
+#+AUTHOR: Craig Jennings
+#+DATE: 2026-07-19
+#+TODO: TODO | DONE
+#+TODO: DRAFT READY DOING | IMPLEMENTED SUPERSEDED CANCELLED
+
+* DRAFT Music Config UI Remodel
+:PROPERTIES:
+:ID: bcbb9342-1884-4281-8821-89b06f6f8793
+:END:
+- 2026-07-19 Sun @ 16:03:13 -0500 — drafted from the approved Dupre Studios design session.
+
+** Prototype iterations
+
+The design session started with working HTML directions, moved through six
+distinct visual concepts, and then refined one receiver layout through paired
+playlist/radio boards. The last board is Craig's GIMP refinement and is the
+visual authority for this spec.
+
+- [[file:music-svg-directions.html][Initial working SVG directions]]
+- [[file:concept-board.html][Six-direction comparison board]]
+- [[file:concepts/01-champagne-receiver.png][01 Champagne Receiver]]
+- [[file:concepts/02-le-mans-night-cluster.png][02 Le Mans Night Cluster]]
+- [[file:concepts/03-geneva-playback-chronograph.png][03 Geneva Playback Chronograph]]
+- [[file:concepts/04-mastering-room-reel-console.png][04 Mastering Room Reel Console]]
+- [[file:concepts/05-perpetual-calendar-salon.png][05 Perpetual Calendar Salon]]
+- [[file:concepts/06-transatlantic-broadcast-navigator.png][06 Transatlantic Broadcast Navigator]]
+- [[file:concepts/07-functional-black-glass-receiver.png][07 Functional black-glass receiver]]
+- [[file:concepts/08-functional-black-glass-flipped.png][08 Playlist-flipped receiver]]
+- [[file:concepts/09-functional-black-glass-retro.png][09 Warmer retro receiver]]
+- [[file:concepts/10-warm-black-glass-player-volume.png][10 Player-volume receiver]]
+- [[file:concepts/11-illuminated-black-glass-controls.png][11 Illuminated controls]]
+- [[file:concepts/12-consolidated-functional-receiver.png][12 Consolidated functional receiver]]
+- [[file:concepts/13-black-silver-chronograph-receiver.png][13 Black-silver chronograph]]
+- [[file:concepts/14-corrected-luxury-chronograph-receiver.png][14 Corrected luxury chronograph]]
+- [[file:concepts/15-champagne-brass-digital-hifi.png][15 Champagne digital hi-fi]]
+- [[file:concepts/16-champagne-aluminum-radio-groups.png][16 Explicit radio grouping]]
+- [[file:concepts/17-dupre-coltrane-scrollbar.png][17 Long-playlist and scrollbar stress test]]
+- [[file:concepts/18-dupre-branding-control-study.png][18 Branding and control study]]
+- [[file:concepts/19a-dupre-playlist-state.png][19a Playlist state]] and [[file:concepts/19b-dupre-radio-state.png][19b radio state]]
+- [[file:concepts/20-dupre-playlist-radio-comparison.png][20 Long playlist / compact radio comparison]]
+- [[file:concepts/21-dupre-semantic-controls-comparison.png][21 Semantic control comparison]]
+- [[file:concepts/22-dupre-identity-bay-comparison.png][22 Identity-bay comparison]]
+- [[file:concepts/23-dupre-swapped-info-comparison.png][23 Swapped information comparison]]
+- [[file:concepts/24-dupre-full-brass-vu-comparison.png][24 Full-brass VU comparison]]
+- [[file:concepts/25-dupre-seamless-flush-comparison.png][25 Seamless flush comparison]]
+- [[file:concepts/26-dupre-studios-rounded-chrome-comparison.png][26 Dupre Studios comparison]]
+- [[file:concepts/27-dupre-studios-leather-analog-header-comparison.png][27 Leather and analog-header comparison]]
+- [[file:concepts/28-dupre-studios-balanced-controls-comparison.png][28 Balanced-control comparison]]
+- [[file:concepts/29a-dupre-studios-brass-seek-playlist.png][29 Brass seek-thumb pass]]
+- [[file:concepts/30a-dupre-studios-user-refined-playlist.png][30 Craig's near-final playlist board (visual authority)]]
+- [[file:prototypes/2026-07-19-music-config-ui-remodel-prototype-1.html][31 Functional local-playlist / radio prototype (acceptance candidate)]]
+
+* Metadata
+| Status | Not ready — first review found one functional-prototype blocker |
+|----------+------------------------------------------------------------------------|
+| Owner | Craig Jennings |
+|----------+------------------------------------------------------------------------|
+| Reviewer | Craig Jennings |
+|----------+------------------------------------------------------------------------|
+| Related | [[file:../../todo.org][music: SVG player application design and delivery]]; [[file:../../docs/specs/2026-07-06-fancy-music-player-ui-spec.org][implemented fancy player spec]]; [[file:../../docs/specs/music-config-without-emms-spec.org][EMMS-free architecture spec]] |
+|----------+------------------------------------------------------------------------|
+
+* Summary
+
+Replace the current text-and-image EMMS playlist surface with a realistic
+Dupre Studios receiver rendered inside Emacs. The interface uses a raster skin
+for leather, glass, brass, and machined controls, then draws all changing
+information and illumination in SVG. Emacs Lisp remains the application
+runtime and maps the SVG surface to the existing music-config commands.
+
+The remodel preserves the plain and fancy text views as fallbacks. It does not
+change M3U ownership, radio-browser behavior, or the current EMMS playback model.
+
+* Problem / Context
+
+The implemented fancy player improved names, artwork, and progress, but it is
+still a text playlist with a multi-line overlay. It cannot present the player
+as one coherent instrument. Controls are key hints rather than controls,
+playlist management is visually detached from playback, and active state is
+limited to text faces and a character-cell progress bar.
+
+Craig wants a bottom-docked application that looks like a manufactured object:
+black leather, black glass, champagne brass, lit analog meters, and discreet
+controls. The beauty has to explain state. A lamp, depressed key, moving
+needle, seek position, or selected row must correspond to real music-config or
+mpv behavior. Decorative AM/FM, tone, power, reload, manual URL, and other
+unsupported faceplate controls are prohibited.
+
+The final 1916×821 board settles the visual direction. The remaining design
+problem is how to preserve its realism without baking live state into a picture.
+An all-vector redraw would lose much of the leather and metal detail. A single
+clickable PNG would preserve the appearance but freeze track data, meter state,
+playlist rows, and button feedback. The chosen design separates the physical
+object from its information and behavior.
+
+* Goals and Non-Goals
+
+** Goals
+
+- Match Craig's near-final board closely enough that the running player reads as
+ the same manufactured receiver, not a simplified diagram of it.
+- Preserve the full music-config workflow: playback, seek, player volume,
+ playlist browsing and persistence, radio search, repeat/single/random/consume,
+ reordering, add, new, load, save, and delete.
+- Make every visible state honest. Meter needles use real program levels,
+ volume lamps use mpv volume, progress uses mpv position, and mode lamps use
+ current mode state.
+- Keep the hot path compact: album information and controls on the left,
+ fourteen playlist rows and playlist actions on the right.
+- Keep keyboard operation complete while adding direct mouse interaction.
+- Preserve the existing text render for TTY frames, unsupported SVG builds, and
+ opt-out/rollback.
+- Keep the renderer independent of EMMS objects so the planned EMMS-free/VAMP
+ work can replace the controller without replacing the visual layer.
+
+** Non-Goals
+
+- No music library browser, tag editor, lyrics view, waveform editor, or album
+ collection database.
+- No streaming-service integration.
+- No fake receiver functions such as AM/FM tuning, bass, treble, speakers, or
+ power.
+- No permanent faceplate controls for reload, editing the M3U file, or manual URL
+ entry. Existing keyboard and M-x access may remain.
+- No all-vector imitation of leather, brushed metal, or photographic reflections.
+- No EMMS removal or VAMP extraction in this project. Those remain separate
+ architecture efforts.
+- No alternate narrow/mobile layout in v1. The player scales as one panoramic
+ instrument.
+
+** Scope tiers
+
+- v1: neutral raster skin, SVG renderer, dedicated graphical view buffer,
+ complete keyboard/mouse command surface, playlist viewport, seek, persistent
+ mpv volume, real stereo VU telemetry, local-file and radio states, diagnostics,
+ fallbacks, tests, and live verification.
+- Out of scope: library browsing, ratings, per-track menus, editable metadata,
+ alternate skins, responsive reflow, and remote control.
+- vNext: multiple visual skins, a narrower alternate layout, richer motion
+ transitions, and reuse in a future standalone VAMP package.
+
+* Design
+
+** User view
+
+F10 opens the player in the existing bottom side-window position. In a
+graphical frame with the remodel enabled, the buffer is the Dupre Studios
+receiver. The same keys still work. The visible buttons also work with the
+mouse, the playlist scrolls inside its fourteen-row aperture, and selecting a
+row starts that track.
+
+A local file shows album art, title, artist, album, label, and year on separate
+lines when those fields exist. It shows elapsed and total time with a draggable
+seek control. A live station shows station art and two ON AIR indications: one
+under the art and one in the active station row. It never shows a seek control
+or invented time for a stream. Missing metadata produces no placeholder word.
+
+The interface behaves like hardware. Play/Pause sits depressed and glows green
+while playing. Momentary transport controls brighten while pressed. Active
+play modes illuminate the circumference of their brass buttons. Volume lamps
+fill continuously to the current mpv volume. VU needles move from the actual
+left and right audio levels.
+
+The interaction model is available in the [[file:prototypes/2026-07-19-music-config-ui-remodel-prototype-1.html][functional browser prototype]]. It
+switches between a 69-track local fixture and an 18-station radio fixture and
+wires transport, playback modes, radio search, playlist actions, row selection,
+seek, volume, wheel/keyboard browsing, scrollbar drag, empty state, and delete
+confirmation. Its built-in twelve-check behavior pass is green. Craig's
+hands-on acceptance remains the last prototype gate.
+
+** Research and visual sources
+
+The design session compared NAD restraint, Marshall's black-and-brass control
+language, McIntosh black glass and meter hierarchy, vintage stereo transport
+controls, automobile instrument clusters, and black/silver chronographs. The
+useful lessons were consistent: controls need one visual family, status lights
+need stable color meaning, labels belong on the faceplate, and ornament should
+make state easier to read.
+
+The local Dupre references are the implementation sources:
+
+- [[file:references/dupre-gallery.png][Dupre component gallery capture]]
+- [[file:references/waybar-redesign.png][Waybar redesign capture]]
+- [[file:README.org][Design-session decisions and critique log]]
+- [[file:concepts/30a-dupre-studios-user-refined-playlist.png][Near-final visual authority]]
+- [[file:../../../code/archsetup/docs/prototypes/gallery-widget.el][svg.el Dupre renderer proof of concept]]
+
+** Canonical geometry
+
+The source canvas is 1916×821 with a viewBox of =0 0 1916 821=. The renderer
+preserves that aspect ratio and scales it to the available window width. It
+does not reflow the playlist under the controls or move controls at runtime.
+Extra vertical room stays black below the instrument. A window too short for
+legible rendering falls back to the existing fancy text view rather than
+shrinking controls into unusable targets.
+
+Craig's final board defines the visual positions. Phase 1 records them in one
+geometry table, including every visual rectangle, label anchor, hit target, and
+playlist row. Rendering and hit testing use the same constants. No second
+hand-maintained map is allowed.
+
+The principal regions are:
+
+| Region | Approximate source bounds |
+|------------------------+---------------------------|
+| Complete instrument | 0,0 to 1916,821 |
+| Player upper glass | 50,50 to 1170,368 |
+| Lower brass deck | 69,372 to 1147,744 |
+| Playlist glass | 1170,52 to 1862,744 |
+| Branding field | 150,115 to 500,275 |
+| Artwork | 609,108 to 755,281 |
+| Metadata | 780,100 to 1125,275 |
+| Seek / ON AIR line | 608,302 to 1125,330 |
+| Playlist viewport | 1175,126 to 1835,658 |
+| Playlist actions | 1173,671 to 1850,733 |
+
+Exact measured values replace these orientation bounds in the geometry table.
+
+** Rendering layers
+
+The SVG is a scene graph with four layers.
+
+1. The physical shell is raster. It contains the leather chassis, compressed
+ seams, black glass texture, fine low-contrast champagne micro-brush, recessed
+ grooves, fixed branding,
+ engraved labels, neutral control bodies, neutral volume knob, and empty VU
+ scales. The application embeds the assets with =svg-embed= and caches their
+ encoded data for the Emacs session.
+
+2. Static vector geometry supplies clip paths, hit-region outlines used only in
+ debug mode, row separators, and any simple lines that need to stay sharp at
+ different scales.
+
+3. Dynamic SVG supplies album/station art, metadata, playlist header and rows,
+ progress, brass seek thumb, scrollbar, transport glyphs, pressed states,
+ lamps, VU needles, and meter light. No live text, needle, lamp, selected row,
+ scrollbar, or progress state is baked into the raster shell.
+
+4. Emacs Lisp supplies behavior. SVG rendered through librsvg does not run
+ browser JavaScript. A buffer-local keymap receives mouse events,
+ =posn-object-x-y= returns pixel coordinates inside the displayed image, and
+ one scale transform maps them back to the source coordinate system.
+
+The near-final PNG cannot be embedded unchanged. Phase 1 creates a neutral
+layered source by removing metadata, playlist text, active lamps, VU needles,
+progress, and selection from the final board. The source stays editable. The
+editable source stays one full-resolution instrument. Runtime rendering uses
+three aligned image regions: upper player glass, lower control deck, and
+playlist. A compact control sprite sheet and neutral VU face supplement those
+regions. The current 1916×821 art is treated as a two-times source for a typical
+roughly 958×410 rendered dock. Opaque runtime crops may be exported at their
+display size after a PNG/JPEG visual comparison. V1 does not upscale beyond the
+native source pixels.
+
+** Module and state boundary
+
+The SVG view lives in a new =modules/music-svg-ui.el= module. It requires
+=svg=, =dom=, and ordinary Emacs image support, but it does not require EMMS.
+Its pure entry points accept plain data:
+
+- =cj/music-svg-render= takes a state snapshot and viewport.
+- =cj/music-svg-hit-target= maps source coordinates to an action description.
+- =cj/music-svg-truncate= fits display text to a fixed pixel/character budget.
+- =cj/music-svg-scrollbar= computes thumb length and position.
+- =cj/music-svg-vu-angle= maps a smoothed dB value to the meter scale.
+
+=modules/music-config.el= remains the controller. It builds an ephemeral
+=cj/music-ui-state= snapshot from the current EMMS playlist and player state,
+then dispatches renderer actions back to existing commands. The snapshot owns
+no durable music data. EMMS and M3U files remain authoritative in v1.
+
+The snapshot contains:
+
+- playback status and track kind
+- current track identity and metadata
+- art path, elapsed time, duration, and seekability
+- playlist name/file, total count, rows, selected index, and viewport offset
+- repeat, single, random, and consume state
+- player volume
+- left/right meter values
+- transient pressed/focused target
+
+The graphical view is a dedicated =*Music Player*= special-mode buffer. The
+hidden EMMS playlist buffer continues to own playlist markers and track order.
+Controller helpers translate a visible row index to an EMMS buffer position
+before selection, playback, reorder, or deletion. This avoids making a single
+image character pretend to be fourteen editable EMMS rows, and it leaves a
+clean seam for the EMMS-free state API later.
+
+** Metadata and typography
+
+Berkeley Mono is the default instrument typeface because it is the Dupre token
+font and is installed on the target system. Missing font support falls back to
+=monospace=. The cursive Dupre Studios mark remains raster in the physical
+shell.
+
+Title, artist, album, label, and year each get one line. Empty values disappear
+without closing the line spacing above them. The title receives the largest
+width budget and truncates with a literal ellipsis. The renderer uses the
+fixed-width font metrics and the measured metadata box, not a guessed character
+count from the current window.
+
+The playlist shows fourteen one-line rows. Each row is number, title, artist,
+and duration on one line. The row text truncates before the duration column.
+Inactive text is soft white. The active row is amber and carries the triangular
+play marker. There are no decorative status dots.
+
+The header is the only coffee/cream instrument card. It shows the current
+collection or search name and item count, but never labels the source as a
+playlist or radio. Four concealed warm-light pools are part of the static skin,
+but the text is SVG because the name and count change. Its champagne surface is
+smooth metal with a fine linear micro-brush, never coarse or wavy wood grain.
+
+** Playlist viewport
+
+The UI keeps a buffer-local first-visible index. The current track is kept in
+view after track changes unless the user is actively browsing elsewhere. Mouse
+wheel moves three rows. Up/Down moves the UI cursor one row. Page Up/Page Down
+moves fourteen. Home/End goes to the first/last track. A row click selects and
+starts that track. The existing keyboard play command remains available.
+
+For =N= tracks and fourteen visible rows, the scrollbar thumb fraction is
+=min(1, 14/N)=. Its position is =offset/(N-14)= when =N > 14=. Dragging the
+thumb changes the viewport but never changes the playing track. No scrollbar
+appears for fourteen or fewer tracks.
+
+** Control behavior
+
+The visible controls map to existing behavior:
+
+| Surface | Action |
+|---------------+--------|
+| PREV | =cj/music-previous= |
+| PLAY/PAUSE | start selected/current track, or =emms-pause= while playing |
+| STOP | =emms-stop= |
+| NEXT | =cj/music-next= |
+| REPEAT | =emms-toggle-repeat-playlist= |
+| SINGLE | =emms-toggle-repeat-track= |
+| RANDOM | =emms-toggle-random-playlist= |
+| CONSUME | =cj/music-toggle-consume= |
+| NAME | =cj/music-radio-search-by-name= |
+| TAGS | =cj/music-radio-search-by-tag= |
+| ADD | =cj/music-fuzzy-select-and-add= |
+| NEW | =cj/music-playlist-clear=, including its file-association reset |
+| LOAD | =cj/music-playlist-load= |
+| SAVE | =cj/music-playlist-save= |
+| DELETE | =cj/music-delete-playlist= with its existing strong confirmation |
+
+Mouse press immediately renders the physical pressed state. Release inside the
+same target dispatches the command. Release elsewhere cancels it. The
+Play/Pause key remains depressed while playback is active. PREV and NEXT only
+brighten during a press. STOP has no latched light.
+
+The four play-mode controls are alternate-action pushbuttons, not lamps or
+rotary controls. Each has an unmarked spun-brass cap matching the volume cap, a
+fixed collar, and a narrow dark travel seam; the faceplate label identifies its
+function. Off stands slightly proud and casts a small lower shadow. On sits
+nearly flush, collapses that shadow, and illuminates a thin desaturated-green
+ring inside the cap/collar gap. Play/Pause uses the same warm instrument green
+through its cut-out symbol with a tight internal bloom; the depressed key
+remains the primary playing cue.
+
+The SVG mode retains the full existing keyboard surface, including commands not
+placed on the faceplate: manual station creation, reload, edit, append to another
+playlist, shuffle, track removal, and track reordering. Which-key/help text
+documents those commands. The faceplate stays limited to the approved controls.
+
+** Seek and volume
+
+Local files show elapsed time, total duration, an amber progress line, and a
+narrow vertical machined-brass grip. Clicking or dragging the slider sends an
+mpv =seek= command in
+=absolute-percent= mode. The displayed thumb is computed from mpv =time-pos=
+and =duration=. While dragging, the local preview follows the pointer; the next
+mpv response confirms or corrects it.
+
+URL tracks always use the radio presentation. The slider and times disappear.
+One red =ON AIR= line appears under the station art, and the active playlist row
+contains the second =ON AIR=. No other ON AIR label is rendered.
+
+Player volume is separate from the system mixer. Add
+=cj/music-player-volume=, default 100, and apply it to every new mpv process.
+The knob has no number or pointer. Its equally spaced lamps show the stored
+0–100 value. Click/drag around the arc sets volume, the mouse wheel changes it
+by five, and the existing +/− bindings call the same player-volume commands.
+Setting volume writes mpv's =volume= property and updates the stored value so a
+track change does not reset it.
+
+Every volume position is one fixed lamp well. Dark and illuminated states use
+the same center and mounting bezel; the lit state replaces the dark lens rather
+than adding another dot or adjacent glow. The neutral raster skin contains no
+baked lamp cores or light spill.
+
+** Real VU telemetry
+
+mpv starts with a labeled FFmpeg audio filter:
+
+#+begin_src text
+--af-add=@meter:lavfi=[astats=metadata=1:reset=1:measure_perchannel=RMS_level+Peak_level:measure_overall=none]
+#+end_src
+
+The UI reads =af-metadata/meter= over mpv JSON IPC. FFmpeg supplies
+=lavfi.astats.1.RMS_level= and =lavfi.astats.2.RMS_level= (plus peak values).
+Mono duplicates channel one to both meters. Missing or nonnumeric data rests
+the needles and records one diagnostic; it never invents motion.
+
+This path was verified locally on 2026-07-19 with mpv 0.41.0 and FFmpeg 8.1.2.
+A synthetic stereo source returned distinct left/right RMS and peak values
+through the labeled property. The official references are:
+
+- [[https://mpv.io/manual/master/#command-interface-af-metadata][mpv af-metadata property]]
+- [[https://ffmpeg.org/ffmpeg-filters.html#astats-1][FFmpeg astats filter]]
+
+The renderer maps dB to the printed meter scale (−40 through +3). A 300 ms
+attack and slower 600 ms release approximate a physical VU movement. Values
+below the scale rest at the left stop. Values above +3 clamp at the right stop.
+
+Telemetry uses one persistent, nonblocking IPC connection with request IDs and
+line-buffered JSON replies. It polls only while the player view is visible and
+audio is running. It closes when playback stops or the view is hidden. The
+existing one-shot IPC helpers remain valid for infrequent commands.
+
+** Refresh and render budget
+
+Hooks trigger immediate redraws for track, playlist, playback, mode, and art
+changes. Progress updates four times per second while a seekable file plays.
+Meters target ten updates per second while visible and playing. Paused, stopped,
+hidden, and TTY states run no animation timer.
+
+The [[file:prototypes/2026-07-19-music-config-ui-remodel-benchmark.org][prototype benchmark]] measured full-image and tiled refresh for one minute
+each at the real dock size. Full refresh failed at 133.616 ms median and
+139.822 ms p95. A display-sized lower-deck tile passed at 35.513 ms median and
+38.221 ms p95. The application therefore uses three aligned images: upper
+player glass, lower control deck, and playlist. Each image includes the
+matching raster crop. Meter ticks refresh only the lower deck; hooks refresh
+the other regions. The source geometry and user-visible layout do not change.
+
+** Errors and empty states
+
+An empty queue shows the receiver, =UNTITLED=, =0 TRACKS=, and fourteen blank
+rows. Playlist actions and radio search remain enabled. Transport, seek, and
+mode actions that require a track are visibly inactive and report a short
+message if invoked by key.
+
+Missing artwork uses the existing vinyl placeholder. Missing metadata is
+omitted. The UI never displays =Unknown=, =N/A=, a raw nil, or a raw stream URL
+as program information.
+
+If SVG, librsvg, the raster shell, or a minimum legible viewport is unavailable,
+F10 opens the implemented fancy/text playlist instead and reports why once. If
+mpv IPC is unavailable, seek, volume telemetry, and meters disable without
+stopping playback. A command reports the failed operation and the next step,
+for example: =Music seek unavailable: mpv IPC socket is not connected; start a
+track and try again.=
+
+=M-x cj/music-ui-doctor= reports graphical/SVG support, resolved assets and font,
+view size, last render time, mpv socket state, meter filter state, telemetry
+timer state, and the last telemetry error. It does not log private file paths
+or stream URLs unless called with a debug prefix.
+
+* Alternatives Considered
+
+** Hybrid raster skin plus dynamic SVG (chosen)
+
+- Good, because it preserves the leather, glass, brass grain, and machined
+ highlights from the approved board while keeping every changing value honest.
+- Bad, because the neutral raster source and SVG geometry must stay aligned.
+- Neutral, because the result is still one SVG application document even though
+ the document embeds raster assets.
+
+** Rebuild the complete receiver as vector geometry
+
+- Good, because every surface would scale without raster limits and theme tokens
+ could recolor everything.
+- Bad, because reproducing leather, brushed brass, glass, and irregular reflected
+ light would take much longer and would look less like the approved board.
+- Neutral, because simple Dupre controls still supply useful vector geometry
+ inside the hybrid renderer.
+
+** Use the final PNG as one clickable background
+
+- Good, because it would match the approved image immediately.
+- Bad, because the PNG contains one track, one playlist, lit volume segments,
+ meter needles, progress, and button state. Painting over those areas would
+ flatten the material texture and produce visible patches.
+- Neutral, because a cleaned neutral derivative of the PNG is the chosen shell.
+
+** Browser/xwidget application
+
+- Good, because browser SVG supports native DOM events and partial element
+ updates.
+- Bad, because it introduces a browser runtime inside Emacs, complicates window
+ integration, and weakens TTY and configuration portability.
+- Neutral, because browser prototypes remain useful before the svg.el port.
+
+** Replace the EMMS playlist buffer in place
+
+- Good, because no second buffer name or adapter is needed.
+- Bad, because EMMS commands depend on point and text markers while the SVG is
+ one displayed image glyph. Mixing invisible rows and image coordinates would
+ be brittle.
+- Neutral, because the dedicated view still delegates every operation to the
+ existing EMMS buffer in v1.
+
+* Decisions [10/10]
+
+** DONE Hybrid raster/SVG rendering
+- Context: the final board's realism comes from material texture and reflected
+ light, while live state must remain replaceable.
+- Decision: We will embed a neutral raster skin in an SVG scene and render all
+ changing information, needles, lights, and selection as SVG.
+- Consequences: easier, the running UI can closely match the board. Harder, the
+ asset export and SVG geometry need one measured coordinate system.
+
+** DONE Craig's final board is the visual authority
+- Context: the design session produced many useful directions, but implementation
+ needs one source for proportion and material treatment.
+- Decision: We will use concept 30, Craig's 1916×821 GIMP refinement, as the
+ layout and appearance authority.
+- Consequences: easier, visual disputes can be checked against one board. Harder,
+ the radio state must be derived without drifting from that hardware.
+
+** DONE Neutral physical shell
+- Context: the final flattened PNG contains transient information and active
+ state.
+- Decision: We will create an editable neutral source and export a clean shell,
+ control sprites, and neutral VU face. No live state remains in those assets.
+- Consequences: easier, texture stays realistic. Harder, Phase 1 includes careful
+ image cleanup before application code can look finished.
+
+** DONE Dedicated graphical view buffer
+- Context: EMMS playlist operations are point/marker based and cannot treat one
+ SVG image as fourteen text rows.
+- Decision: We will render into =*Music Player*= and use controller adapters to
+ operate on the hidden EMMS playlist buffer.
+- Consequences: easier, the SVG renderer stays clean and future-backend ready.
+ Harder, selection and reorder commands need explicit index-to-marker adapters.
+
+** DONE One geometry table for drawing and input
+- Context: separate hand-maintained visual and hit maps will drift.
+- Decision: We will measure the final board once and derive rendering, hit tests,
+ clipping, and scaling from the same constants.
+- Consequences: easier, controls stay clickable after scaling. Harder, geometry
+ extraction is a named deliverable rather than ad hoc coordinates in draw code.
+
+** DONE Direct control semantics
+- Context: every faceplate control must perform real music-config behavior.
+- Decision: We will map the approved transport, modes, radio search, playlist
+ actions, seek, and volume controls directly to their existing commands or the
+ named mpv additions in this spec.
+- Consequences: easier, the interface is self-explanatory. Harder, commands not
+ approved for the faceplate remain keyboard/M-x only and need discoverable help.
+
+** DONE Persistent per-player volume
+- Context: the existing +/- path can change the system mixer, while the design's
+ knob is the player's volume and mpv restarts for each track.
+- Decision: We will store volume in music-config, write mpv's volume property,
+ and apply the stored value when every new mpv process starts.
+- Consequences: easier, the knob is truthful and track changes preserve level.
+ Harder, one more piece of runtime state must stay synchronized with mpv.
+
+** DONE Real meter data through mpv astats
+- Context: random needle animation would violate the design's functional-lighting
+ rule.
+- Decision: We will read left/right RMS metadata from a labeled FFmpeg astats
+ filter over mpv IPC and apply physical needle smoothing.
+- Consequences: easier, the VUs convey real program level. Harder, a visible
+ view needs a small persistent IPC telemetry client and bounded refresh timer.
+
+** DONE Current text views remain fallbacks
+- Context: TTY frames and SVG/asset failures need a usable player, and the
+ implemented fancy text UI already works.
+- Decision: We will add an SVG enable flag and fall back to the current fancy or
+ plain text path without changing M3U or playback state.
+- Consequences: easier, rollout and rollback are safe. Harder, the text path
+ remains maintained alongside the SVG application.
+
+** DONE Three-region render path after measurement
+- Context: =svg-possibly-update-image= rerasterizes an SVG image, so ten full
+ receiver renders per second may exceed the dock's CPU budget.
+- Decision: The prototype benchmark measured the full receiver at 133.616 ms
+ median / 139.822 ms p95 and the display-sized lower-deck tile at 35.513 ms
+ median / 38.221 ms p95. We will use three aligned regions and refresh only
+ the lower deck at meter cadence.
+- Consequences: easier, meter animation passes the render budget with margin.
+ Harder, the renderer places three images and the asset export must hide their
+ boundaries exactly.
+
+* Review findings [0/1]
+
+** TODO The final interaction model has no working two-state prototype :blocking:
+
+The design session produced extensive static boards and established concept 30
+as the visual authority, but the final geometry has not been exercised as a
+working local-playlist and radio prototype. That leaves click targets, drag
+behavior, playlist scrolling, long-text clipping, local/radio state changes,
+and the full-image render budget unproven. Starting implementation now would
+make the first build phase answer product and performance questions that belong
+in the design gate.
+
+Smallest resolution: create one functional prototype using concept 30's
+geometry and neutral skin. It may be a browser prototype or an Emacs SVG proof,
+but it must switch between a long local playlist and a live-radio fixture; wire
+transport, modes, radio search, playlist actions, row and scrollbar navigation,
+seek, and volume interaction; show all pressed and latched states; stress long
+metadata; and record one minute of render timing at the intended dock size.
+Link the accepted prototype under Prototype iterations and Design, record any
+geometry or performance changes here, then repeat spec review.
+
+Progress on 2026-07-19: [[file:prototypes/2026-07-19-music-config-ui-remodel-prototype-1.html][prototype 1]] now supplies both fixtures and the named
+interactions; its twelve-check behavior pass is green. The [[file:prototypes/2026-07-19-music-config-ui-remodel-benchmark.org][librsvg benchmark]]
+records a full-render failure and a passing lower-deck tile, so the spec now
+requires the three-region renderer. Craig's hands-on acceptance is the only
+remaining part of this finding.
+
+* Implementation phases
+
+** Phase 1 — Neutral skin and geometry manifest
+
+Create the editable neutral source from concept 30. Export aligned upper-glass,
+lower-deck, and playlist crops plus control sprites and the VU face under final
+dated asset names. Record measured
+source rectangles, anchors, clip boxes, and hit targets in one Lisp geometry
+table. Add an asset/geometry debug command that renders target outlines over the
+skin. The phase ends with a static SVG in Emacs that matches the final board and
+contains no baked live state.
+
+** Phase 2 — Pure SVG renderer and view mode
+
+Add =modules/music-svg-ui.el=, the state structs, pure layout helpers, raster
+embedding cache, text clipping, dynamic node construction, and
+=cj/music-svg-mode=. F10 can show/hide the static graphical view while the
+existing fancy/text path remains available. Add unit tests for scale transforms,
+hit testing, truncation, scrollbar math, mode colors, and VU angle mapping.
+
+** Phase 3 — Controller snapshot and playlist viewport
+
+Build state snapshots from EMMS without exposing EMMS objects to the renderer.
+Render metadata, album art, header, fourteen rows, selection, and the exact
+scrollbar. Implement keyboard and mouse scrolling, row selection/play, and
+index-to-EMMS-marker adapters. Characterize existing reorder/removal behavior
+before routing those keys through the graphical view.
+
+** Phase 4 — Transport, modes, radio search, and playlist actions
+
+Wire the approved faceplate controls and pressed/latched rendering. Preserve
+the remaining keyboard-only commands and add a concise help surface. Cover
+empty-queue behavior, destructive Delete confirmation, command errors, and
+state refresh hooks. The phase ends with a complete functional control surface
+using the existing backend.
+
+** Phase 5 — Seek and persistent mpv volume
+
+Add player-owned volume state and apply it on process start. Route +/−, wheel,
+click, and drag through the same volume setters. Add absolute seek and drag
+confirmation using mpv time/duration. Render local progress and the exact brass
+thumb. Unit-test value/coordinate mapping and use a fake IPC ledger for command
+order.
+
+** Phase 6 — Stereo telemetry and timed refresh
+
+Add the labeled astats filter, persistent nonblocking telemetry connection,
+JSON request/reply routing, meter parsing, dB mapping, and needle ballistics.
+Run progress and meter timers only while visible and active. Measure the render
+budget for one minute and use the documented three-region fallback if needed.
+Test with the synthetic no-audio-output source used during spec research.
+
+** Phase 7 — Radio state, failures, and diagnostics
+
+Render the matched live-radio state with exactly two ON AIR labels and no seek
+surface. Handle missing art/metadata, unavailable SVG/assets/font, lost mpv IPC,
+missing meter metadata, hidden-window timer shutdown, and an empty queue. Add
+=cj/music-ui-doctor= and verify that fallback never mutates playback or playlist
+state.
+
+** Phase 8 — Integration, documentation, and live verification
+
+Run the focused music tests, batch load, byte compilation, TTY fallback, and GUI
+daemon verification. Exercise a long local playlist, a short radio playlist,
+seek, volume across track changes, every control, scrolling, reorder, deletion,
+and one-hour timer stability. Update music documentation and key hints. Make
+the SVG view the graphical default only after Craig accepts the live result.
+
+* Acceptance criteria
+
+- [ ] F10 opens the Dupre Studios receiver in the bottom side window on a
+ graphical frame and toggles it closed without changing playback.
+- [ ] The running receiver matches concept 30 in proportion, material character,
+ spacing, typography, and control placement at the normal dock size.
+- [ ] Leather, glass, brass, fixed engraving, and neutral hardware come from the
+ raster skin; live information and illumination are not baked into it.
+- [ ] The UI remains fully usable from the keyboard.
+- [ ] Every visible button maps to the command named in this spec.
+- [ ] Pressed, playing, and latched mode states are physically and chromatically
+ distinct.
+- [ ] Local metadata uses separate lines and omits missing values. No visible
+ program field says Unknown or N/A.
+- [ ] Long metadata and playlist rows truncate with an ellipsis before colliding
+ with adjacent fields.
+- [ ] The analog header card shows only the collection/search name and item
+ count; it never adds a PLAYLIST or RADIO type label.
+- [ ] Champagne surfaces use a fine low-contrast metallic micro-brush and never
+ read as wood grain.
+- [ ] The playlist shows fourteen one-line rows with artist inline, selected row
+ amber, and a functional scrollbar whose size and position follow the formulas.
+- [ ] Mouse wheel, keyboard navigation, scrollbar drag, row click/play, reorder,
+ and removal operate on the intended EMMS tracks.
+- [ ] ADD, NEW, LOAD, SAVE, and DELETE preserve current playlist/M3U semantics.
+- [ ] DELETE uses the existing strong confirmation and reports which playlist was
+ deleted.
+- [ ] A local track displays actual elapsed/duration and supports click/drag seek.
+- [ ] The seek thumb is brass and its position comes from mpv state.
+- [ ] A live station has no slider or times and shows exactly two ON AIR labels.
+- [ ] The volume knob controls mpv, not the system mixer, and persists across
+ track changes.
+- [ ] Volume segments fill cumulatively to the stored mpv volume and have no
+ numeric display.
+- [ ] VU needles use distinct real left/right RMS values, rest on missing data,
+ and never use random animation.
+- [ ] Paused, stopped, hidden, and TTY states run no meter/progress timer.
+- [ ] Full or tiled rendering meets the median/95th-percentile budget during a
+ one-minute meter run.
+- [ ] Empty playlist, missing art, missing metadata, missing SVG/assets, and lost
+ mpv IPC each have the fallback or actionable error defined in this spec.
+- [ ] =cj/music-ui-doctor= reports the renderer and telemetry state without
+ exposing file paths or stream URLs by default.
+- [ ] Setting the SVG enable flag off restores the implemented fancy/text UI.
+- [ ] Existing music-config tests pass, and new pure tests cover geometry,
+ snapshots, hit targets, clipping, scrolling, volume, seek, meter mapping, and
+ timer lifecycle.
+- [ ] Craig accepts both a long local-playlist state and a live-radio state in the
+ real Emacs side window before the SVG view becomes the default.
+
+* Readiness dimensions
+
+- Data model & ownership: EMMS and M3U remain authoritative. The SVG snapshot,
+ pressed target, viewport offset, meter smoothing, and render timing are
+ generated runtime state. Player volume is music-config runtime state applied
+ to each mpv process. Raster source assets are project-authored and versioned.
+- Errors, empty states & failure: defined in the Errors and empty states section.
+ Playback continues if rendering or meter telemetry fails. Destructive
+ playlist deletion retains the existing strong confirmation.
+- Security & privacy: no credentials are added. Diagnostics omit local paths and
+ stream URLs by default. Album art and radio favicons stay in the existing
+ local cache.
+- Observability: =cj/music-ui-doctor= exposes assets, font, viewport, render
+ timing, socket/filter/timer state, and last telemetry error. The UI itself
+ exposes player state through lamps, needles, progress, and selection.
+- Performance & scale: fourteen visible rows from playlists tested through at
+ least 1,000 tracks. SVG refresh has explicit median/95th-percentile budgets,
+ a one-minute test, and a pre-approved tiled fallback. Hidden views do no timed
+ work.
+- Reuse & lost opportunities: reuses the current music commands, EMMS state,
+ M3U/radio/art code, bottom side window, Dupre tokens, =svg.el=, and the gallery
+ widget proof. It deliberately does not wait for the EMMS-free/VAMP rewrite.
+- Architecture fit & weak points: new renderer module is pure at its boundary;
+ music-config owns EMMS adaptation and mpv effects. Weak points are raster/SVG
+ alignment, point-based EMMS adapters, full-image rerasterization, and telemetry
+ lifecycle. Geometry sharing, adapter tests, tiled fallback, and visibility-
+ scoped IPC mitigate them.
+- Config surface: add =cj/music-svg-ui= (boolean, default off until live acceptance,
+ then on) and =cj/music-player-volume= (integer 0–100, default 100). Keep
+ =cj/music-fancy-ui= as the fallback selector. Refresh rates and geometry are
+ internal until real use proves a customization need.
+- Documentation plan: update music-config commentary/docstrings, F10/keybinding
+ notes, the music VERIFY task, and the design README. The final spec and dated
+ runtime assets remain linked from the parent task.
+- Dev tooling: use the existing ERT/byte-compile commands, focused music test
+ files, Emacs daemon live verification, and a deterministic synthetic mpv meter
+ script/fixture with =ao=null=. No network or audible output in the normal
+ suite.
+- Rollout, compatibility & rollback: SVG is additive and initially disabled.
+ Fallback is automatic. Rollback is setting =cj/music-svg-ui= nil or reverting
+ the new renderer/controller changes; M3U files and cached art do not migrate.
+- External APIs & deps: built-in Emacs 30.2 =svg.el= and librsvg are the render
+ path. mpv 0.41 and FFmpeg 8.1 were checked locally. Official mpv and FFmpeg
+ documentation confirms labeled audio-filter metadata and astats keys.
+
+* Risks, Rabbit Holes, and Drawbacks
+
+- Cleaning a neutral skin from a flattened final board can produce visible
+ texture patches. Keep the layered source, use broad material samples rather
+ than small clone spots, and approve the neutral shell before wiring state.
+- Full-image librsvg refresh may be too expensive at meter cadence. Measure in
+ the prototype. Use the specified three-region split rather than lowering the
+ meter to a decorative crawl.
+- EMMS commands expect point in the playlist buffer. Keep every index-to-marker
+ translation in one controller adapter and test reorder/remove against the same
+ logical track.
+- SVG text metrics can differ from Emacs face metrics. Use the installed Dupre
+ fixed-width font, fixed boxes, clipping paths, and visual stress fixtures with
+ long titles.
+- An mpv filter may fail for an unusual audio format. Playback wins: leave the
+ meter at rest, show the failure in the doctor, and never stop the track.
+- The raster skin limits infinite scaling and alternate themes. V1 targets the
+ current dock and approved aesthetic. Multiple skins and responsive reflow are
+ separate work.
+
+* Testing / Verification / Rollout
+
+Pure ERT tests cover layout transforms, geometry/hit agreement, text fitting,
+playlist window/scrollbar math, state-to-color mapping, volume/seek conversion,
+VU dB/angle mapping, ballistics, and timer state. Controller tests use an EMMS
+fixture or stubs and an mpv IPC ledger so they do not play sound.
+
+Integration tests build representative local and radio snapshots, render SVG
+strings, and assert required IDs, text, clip paths, and state classes. They do
+not use pixel-perfect screenshots as the main contract because librsvg/font
+versions can change antialiasing. A small set of manual reference screenshots
+supports the visual acceptance step.
+
+The live pass runs in the real bottom side window with the normal long playlist
+and a radio playlist. It covers every faceplate control, keyboard parity,
+scrolling, long strings, seek, persistent volume, two-channel meters, exactly two
+ON AIR states, hidden-window timer shutdown, and fallback. The SVG flag changes
+to default-on only after that pass.
+
+* References / Appendix
+
+- [[file:../../docs/specs/2026-07-06-fancy-music-player-ui-spec.org][Implemented fancy music-player UI spec]]
+- [[file:../../docs/specs/music-config-without-emms-spec.org][Music-config without EMMS architecture spec]]
+- [[file:README.org][Music SVG design record]]
+- [[file:concepts/30a-dupre-studios-user-refined-playlist.png][Near-final playlist board]]
+- [[file:prototypes/2026-07-19-music-config-ui-remodel-prototype-1.html][Functional two-state prototype]]
+- [[file:prototypes/2026-07-19-music-config-ui-remodel-benchmark.org][Prototype librsvg benchmark]]
+- [[https://www.gnu.org/software/emacs/manual/html_node/elisp/SVG-Images.html][Emacs Lisp SVG images]]
+- [[https://mpv.io/manual/master/#json-ipc][mpv JSON IPC]]
+- [[https://mpv.io/manual/master/#command-interface-af-metadata][mpv audio-filter metadata]]
+- [[https://ffmpeg.org/ffmpeg-filters.html#astats-1][FFmpeg astats]]
+
+* Review and iteration history
+
+** 2026-07-19 Sun @ 19:11:57 -0500 — Codex (emacs-d) — hardware-depth correction
+- What: changed the upper boundary of the lower deck from a raised champagne
+ rim to a dark glass reveal descending into the brass faceplate. Unified all
+ four play-mode and both radio-search controls as blank, circularly machined
+ brass pushbutton caps. Removed the returned search glyphs and expanded then
+ tightened the source crop to preserve the volume knob's complete black
+ knurled skirt without importing the old faceplate halo.
+- Why: the prior neutral-faceplate overlay flattened the glass/metal depth,
+ allowed the small-control treatments to diverge, and clipped the knob at a
+ perfect circle that hid its physical knurling. These changes restore a
+ believable assembly hierarchy while retaining state-owned lamps.
+- Artifacts: updated [[file:prototypes/2026-07-19-music-config-ui-remodel-prototype-1.html][functional prototype 1]]; twelve-check interaction regression green.
+
+** 2026-07-19 Sun @ 18:43:00 -0500 — Codex (emacs-d) — prototype refinement
+- What: replaced the baked lower-deck faceplate with a neutral SVG-owned
+ champagne micro-brush surface, then restored only the approved volume knob
+ through a circular crop. Re-engraved the fixed control labels on the new
+ surface and reduced the volume arc to small dark wells with state-owned amber
+ cores and local glow. Verified both local and radio layouts and reran the
+ twelve-check headless interaction pass successfully.
+- Why: masking individual source-image lamps left visible baked illumination and
+ made the faceplate look patched. Owning the complete neutral deck surface in
+ SVG removes the conflicting lamp state and the woodlike raster grain while
+ retaining the realistic machined knob from the approved visual authority.
+- Artifacts: updated [[file:prototypes/2026-07-19-music-config-ui-remodel-prototype-1.html][functional prototype 1]]; local and radio state screenshots.
+
+** 2026-07-19 Sun @ 18:39:41 -0500 — Codex (emacs-d) — prototype refinement
+- What: applied Craig's second hands-on pass. Removed source-type words and the
+ separator from the analog card; changed radio fixture naming to =NAME SEARCH=;
+ replaced the circular seek ornament with a vertical machined-brass grip;
+ removed all mode-cap glyphs and matched their smooth spun-brass finish to the
+ volume cap; and rebuilt the volume arc as dark recessed wells whose amber core
+ and glow exist only for lit positions.
+- Why: the card should identify the current collection/search rather than report
+ an internal playlist/radio type. The prior seek coin had no hardware model,
+ the mode symbols duplicated their faceplate labels, and baked light spill made
+ some nominally dark volume positions glow. The spec now also rejects coarse,
+ wavy champagne texture that reads as wood grain.
+- Artifacts: updated [[file:prototypes/2026-07-19-music-config-ui-remodel-prototype-1.html][functional prototype 1]]; Craig's 18:29–18:32 screenshots.
+
+** 2026-07-19 Sun @ 18:19:28 -0500 — Codex (emacs-d) — prototype refinement
+- What: incorporated Craig's first hands-on notes. Rebuilt play modes as
+ alternate-action brass pushbuttons with engraved glyphs, visible travel, and
+ a restrained inset green ring; tightened Play/Pause illumination; aligned
+ each volume lamp's dark and lit state to one physical well; restored four
+ concealed warm-light pools on a darker coffee/cream playlist card; and made
+ the prototype's synthetic-VU / production-signal distinction explicit.
+- Why: the prior controls read as glowing domes, the green looked like a neon
+ outline, the flattened source and live volume arcs produced double lamps, and
+ the playlist card had lost its analog illumination model. Production VUs
+ remain tied to real mpv astats RMS data as already specified.
+- Artifacts: updated [[file:prototypes/2026-07-19-music-config-ui-remodel-prototype-1.html][functional prototype 1]]; Craig's 17:59–18:03 screenshots.
+
+** 2026-07-19 Sun @ 17:56:27 -0500 — Codex (emacs-d) — prototype author
+- What: built functional prototype 1 from concept 30 with local and radio
+ fixtures, all approved faceplate controls, long-string stress data, exactly
+ fourteen visible rows, scrollbar and seek/volume drag, pressed/latched states,
+ empty/delete flows, keyboard navigation, and synthetic stereo needle motion.
+ Its built-in twelve-check behavior pass is green. Measured librsvg for one
+ minute per path: full receiver 133.616 ms median / 139.822 ms p95 (fail),
+ display-sized lower deck 35.513 ms median / 38.221 ms p95 (pass).
+- Why: this supplies the interaction and performance evidence requested by the
+ first review finding. The measured result makes the three-region renderer a
+ requirement rather than a contingency. Craig's hands-on prototype acceptance
+ remains pending, so the finding stays open and the spec stays DRAFT.
+- Artifacts: [[file:prototypes/2026-07-19-music-config-ui-remodel-prototype-1.html][functional prototype 1]]; [[file:prototypes/2026-07-19-music-config-ui-remodel-benchmark.org][benchmark record]];
+ [[file:2026-07-19-music-config-ui-remodel-render-fixture.svg][full-render fixture template]].
+
+** 2026-07-19 Sun @ 16:16:57 -0500 — Codex (emacs-d) — reviewer
+- What: completed the first implementation-readiness review after reading the
+ current music-config render, EMMS playlist, radio, mpv IPC, and volume paths.
+ Assigned =Not ready= and recorded one blocking finding: the approved final
+ board is static, so its two application states, hit/drag/scroll behavior, and
+ rendering budget have not passed the project's functional-prototype gate.
+- Why: the architecture, ownership, failure handling, telemetry source, rollout,
+ acceptance criteria, and eight phase boundaries are otherwise specific enough
+ to implement. A working prototype is the smallest remaining test of the
+ design rather than an invitation to redesign it during Phase 1.
+- Artifacts: =* Review findings [0/1]= in this spec; source checks in
+ =modules/music-config.el=; Dupre =gallery-widget.el= SVG proof; verified mpv
+ =af-metadata/meter= / FFmpeg =astats= telemetry path.
+
+** 2026-07-19 Sun @ 16:03:13 -0500 — Codex (emacs-d) — author
+- What: drafted the Music Config UI Remodel spec from Craig's selected concept,
+ manual GIMP refinement, and hybrid raster/SVG decision. Verified the real VU
+ telemetry path against the installed mpv/FFmpeg stack and primary docs.
+- Why: the visual design is settled closely enough to define the renderer,
+ controller boundary, interaction surface, phases, and test contract before
+ implementation.
+- Artifacts: [[file:concepts/30a-dupre-studios-user-refined-playlist.png][concept 30]]; local mpv astats IPC check; parent music SVG task.