Skip to content

S10.8 part 1 — Now Playing polish (deviations ladder)#62

Merged
ramith merged 15 commits into
mainfrom
sprint/s10-8-polish
Jul 19, 2026
Merged

S10.8 part 1 — Now Playing polish (deviations ladder)#62
ramith merged 15 commits into
mainfrom
sprint/s10-8-polish

Conversation

@ramith

@ramith ramith commented Jul 18, 2026

Copy link
Copy Markdown
Owner

S10.8 part 1 — the Now Playing polish wave. Began as the founder-commissioned deviations audit (docs/sprints/s10-8-deviations-plan.md), then the visual truth moved to the founder's Realigned Target package (docs/design/now-playing-realigned/ — PNGs + live HTML mock + REALIGN_GUIDE): keep the app's layout, apply the designed styling on top. Executed as the PR-A…G ladder + a break-it round + a founder-round fix. R1 gates on this + the part-2 tab sweep.

Shipped (PR-A…G, all on audited Palette tokens with light variants through the R4 audit)

  • A — package + zero-risk batch: landed the realign package; pill width, signed +dB, waveform mark, headphones tooltip, row path tooltips, 18pt/r9 format chips.
  • B — capsule tab strip (D9 reopened): carved track + teal-gloss active capsule + hover/RM; onAccent → dark-on-teal #0C1413 (retires the flagged 2.5:1). Pill dropdown chevron.
  • C — one-row queue header: title · count · icon chips · Up Next/Recent capsule pair · compact filter pill; drag grips hover-only.
  • D — playing row: subtle 13% tinted card + ring + teal title + 3-bar sine mini-equalizer (stills on pause / Reduce Motion); card persists while paused.
  • E — floating inspector + TRUE peak: panel hugs content over a teal glow (320pt); the meter path upgrades from sample-peak to real inter-sample true peak by extracting the limiter's 8× polyphase kernel to TruePeakKernel.h (shared, oracle-verified) — the "True peak" label is now honest; amber + ▲ above −1 dBTP. Slim 4pt carved recipe everywhere.
  • F — hero badges → two chips: ● ENHANCED · 20% (pulsing dot) + MP3 · 48 kHz (format is new); all other signal states preserved.
  • G — styled-glass bands: chrome + footer fill-strata (dark-only sheen, no blur — founder decision 2); play button shares the teal gloss; footer dot pulses.

Quality

  • 5 new R4 contrast suites (R4-TAB/CHIP/ROW/METER) sampled against the real glow-field composites; 50 token tests green. TOK-04 + LAY-01/02 re-verified.
  • C++ harness: the extracted true-peak kernel verified line-identical to the limiter's prior code (golden-master hash unchanged, libebur128 oracle green) + two new tests (Loudness_TruePeakKernel_InterSample, Loudness_MeterBridge_TruePeak); 122/0.
  • Break-it round (SwiftUI SME + adversarial QA): 10 real findings fixed same day — non-clickable chip hit-target, true-peak warning suppressed by the LUFS gate at track start, a filter that silently narrowed the next queue, Dynamic-Type headroom, and more (see docs/sprints/s10-8-realign-ledger.md).
  • Founder round 1: tab strip → chrome right edge; device pill widened to absorb the chevron.
  • Keyboard-cursor fix: arrowing the queue no longer moves the hero — the queue now has a view-local navigation cursor decoupled from the now-playing pointer (Return/click still play). Also retired 4 dead DesignSystem.Color/enum declarations the restyle orphaned.

Notes

  • 14 deliberate deviations from the mock are recorded in docs/sprints/s10-8-realign-ledger.md (each with rationale — e.g. card radius stays 22 for TOK-01's concentric chain; chip text stays AA-legible over the teal core vs the mock's white-60%).
  • Founder screenshot cells remain OPEN — the implementing session had no screen-capture permission; the ledger's dark/light/RM/peak-hot cells are the founder's pass before part 1 closes.

ramith added 15 commits July 19, 2026 03:20
…items

The S10.8 part-1 ladder opens with the audit's no-risk items
(docs/sprints/s10-8-deviations-plan.md §B PR-A):

- Device pill 252→288: the PR-6 rate slot had squeezed the name area to
  ~140pt, truncating common device names ("MacBook Pr…") — the audit's one
  fresh §1 catch. Tabs' fixed x-origin invariant preserved.
- Master gain readout SIGNED ("+4.0 dB", 8a) — display + spoken value.
- Logo mark: waveform glyph, radius-9 squircle (8a brand mark, was music.note/8).
- Headphones section: one line + .help tooltip for the long rationale;
  disabled-block opacity 0.55 per 8a.
- Bypass/Full-Blend captions → new Font.monoMicro (caption2 mono — Dynamic-
  Type-mapped, never the spec's fixed 9.5pt); labelTertiary stays (nearest
  audited token to the spec's 32% white — a bespoke pair isn't warranted).
- Queue rows: full file-path .help tooltip (AudioFile.id IS the URL).
- Format badge chip: fixed 18pt height, radius 9 (8a metrics).

205 tests / 34 suites green; strict-gate PASSED.
… PR-B..G

The founder's realignment handoff (PNGs + live HTML mock + REALIGN_GUIDE) moves in at
docs/design/now-playing-realigned/. It keeps the deviations ladder A–G and the app's
existing layout, and refines every target value on top; where it disagrees with the
triage plan, the package wins (deltas annotated in the plan, per the docs rule).
Notable reversal recorded: PR-D's mini-equalizer is the package's deterministic sine
TimelineView bars, not spectrum-driven.
…(D9 reopened)

The native segmented picker becomes the realigned carved track + teal active capsule
(png/01-toolbar.png): tabTrack token (dark both appearances, light re-derived per the
grammar), active capsule = the byte-identical iconFill gradient + shared specular rim +
dark-only tealMid glow, hover = the badgeFill wash re-exported as hoverWash. Tabs are
real Buttons (Tab focus + Space/Return; .isSelected trait; snappy selection move,
RM-gated). Device pill gains the mock's dropdown chevron.

onAccent flips white → #0C1413 (dark-on-teal, the realigned identity) — retiring the
long-flagged 2.5:1 white-on-accent across logo/play/tab glyphs; gated by the new
R4-TAB-01 suite (track text both appearances + onAccent on the gradient's text stops).
…over-only

Realigned png/03: title + mono count + 28pt icon chips (trash/shuffle/repeat/jump) +
the Up Next·Recent mini capsule pair + the compact 190pt filter pill (right-aligned,
compressing before LAY-01's minimum queue width). The stacked header block, separate
segmented picker, and full-width filter bar are deleted. New audited chip tokens:
controlHover, controlActiveFill (accent-derived, TOK-04), segmentSelected (solid white
in light per the mock), accentText (#6FE0D0 dark / #0B5548 light) — R4-CHIP-01.

Drag grips vanish at rest and fade in on row hover (opacity-only: the grip keeps its
slot and stays a live drag source; RM-gated fade). Filter shows in Up Next only — a
Recently-Played filter would be new function, out of this styling wave.
…qualizer

Realigned png/04: rowNowPlaying retunes 25% → 13% (still accent-derived, TOK-04);
the card gains radius-10 corners + a 38% accent ring; title goes accentTitle
(#7EE8D8 dark / deep teal light), duration accentText, format badge the audited
controlActiveFill chip pair. The ▶ glyph is replaced by three deterministic sine
TimelineView bars (Kit constants; the paused: schedule + still-scale ternary is
the §3.4 posture in TimelineView form) — bars rest at 0.34 on pause AND under
Reduce Motion. The card now persists while paused (isPlaybackActive gates only
motion); VO says 'Current track, paused' for that state. New R4-ROW-01 audits
title/duration over the sampled glow field at every grid point.
… recipe

Realigned png/05: the panel stops stretching to the window bottom — it hugs its
measured content height (onGeometryChange cap; ScrollView still scrolls inside
the chrome when the region offers less, e.g. the 640pt minimum). Width 260 → 320
(LAY-01 re-verified: queue keeps 508pt at the minimum window). panelFill densifies
to rgba(30,32,37,.72). A dark-only teal radial glow (InspectorCardGlow, gated by
GlowFieldGate) bleeds 20pt past the card's bottom so the freed space reads
intentional. Section hairline dividers before LOUDNESS and HEADPHONES; disabled
headphone block 55% → 50%.

Shared carved recipe slims per the mock: 4pt groove (was 5), dark carve 13% (was
8%), and the progress fill becomes the mid→bright meterFill gradient — sliders,
meters (E2), and the footer scrubber's playing state share it (CarvedGroove
fillColor → fillStyle; paused/interrupted keep their solid state colors).

Card radius stays 22 (mock: 18) — TOK-01's concentric chain and the shipped
S10.7 tune; recorded as a deliberate deviation for the founder round.
…bel honest

Founder decision 3 (measurement before rename): the meter bridge's sample-peak
readout becomes real inter-sample TRUE peak. The limiter's 8× polyphase
windowed-sinc ISP detector extracts to include/TruePeakKernel.h (pure,
header-only) — the limiter delegates to it (its libebur128 oracle test keeps
covering the shared kernel; zero behavior change, 0 harness failures) and the
meter bridge runs the same kernel on the tap thread (24-tap shift registers per
channel, same visual decay). CLoudnessReadout.peakDb → truePeakDb (dBTP);
LoudnessSnapshot follows. New Loudness_TruePeakKernel_InterSample: an fs/4 +45°
sine whose sample grid under-reads by 3 dB must recover to −6.02 dBTP ±0.35.

The meters UI becomes the realigned rows (png/05): 82pt label + shared
CarvedGroove gradient bar + mono value; LUFS floor −42 / true-peak floor −12
reproduce the mock's fractions; label reads 'True peak' NOW that it is one.
Above −1 dBTP (= the limiter's ceiling) the tail + value turn amber: new
meterHot / meterHotText tokens (light variants per the split grammar, meterHotText
light DERIVES from statusWarningText), audited R4-METER-01 over panel⊕glow. The
old CLIP word retires with the sample-peak bar; the hot state is spoken as
'above the −1 dBTP ceiling' in the row's a11y label.
…ip + format·rate

Realigned png/02: ENHANCED becomes ONE teal chip ('● ENHANCED · 20%' — 6pt
accentBright dot pulsing 1.0→0.35/1.6s via the §3.4 conditional phaseAnimator,
frozen when paused or Reduce Motion; live intensity in the string, plain
ENHANCED at 0%). The rate chip gains the track's file FORMAT ('MP3 · 48 kHz',
mono) — new to the hero. The other states survive untouched: PURE monochrome
chip, crossfeed, Pure-unavailable warning, interrupted row; spoken summary
unchanged. TealBadgeCapsule reuses the audited controlActiveFill + accentText
pair; new R4-CHIP-02 audits it over the sampled glow field (the hero sits in
the teal core). Deviation recorded: format·rate text stays primary label, not
the mock's white-60% — R4-BADGE-01's dimmed-hierarchy rule.
Realigned png/01 + png/06 (founder decision 2: fill STRATA, not blur). New
chromeBand(lightFrom:) owns both bands: window base + dark-only sheen gradient
(white 5%→2%, lit from the header's top / the footer's bottom), a 1px specular
line always on the band's TOP edge, and the header's dark bottom seam; light
keeps the plain window + separating hairlines per the grammar. AppShell drops
its background+Hairline pairs (the Hairline view retires — last consumer gone).

ActiveTabCapsule generalizes to TealGloss<Shape>; the footer play button adopts
it (inner top rim + dark-only teal glow — the active tab's exact recipe). The
footer signal readout goes realigned: teal accentBright dot pulsing under the
§3.4 gate (playing + RM off), 'Enhanced' in accentText; Pure/fallback states
keep their established dots.
…filter trap

Two-reviewer adversarial pass (SwiftUI SME + QA breaker) over the whole wave;
every confirmed finding fixed:
- QueueIconButton chips are now clickable across their full 28pt (chip built
  INSIDE the Button label — outer frames never extend a button's hit region).
- Queue header survives the 880pt minimum: chips + mode switcher fixedSize()
  (control labels never truncate), the count subtitle is the designated
  truncation victim, filter min 110 → 90.
- Dynamic Type: @ScaledMetric heights across the header row, chips, switcher,
  filter pill, and FormatBadgeView (radius follows height) — the fixed frames
  clipped at accessibility sizes.
- True-peak row keys on its OWN −110 dB floor, not the integrated-LUFS gate:
  a hot transient at track start warned nothing for the gate's first 400 ms.
- ▲ prefixes the hot value — the visible non-color over-ceiling cue (A-M5),
  succeeding the retired CLIP word.
- Emptying the queue clears the filter (it silently narrowed the NEXT queue
  with reorder disabled).
- Footer Pure-fallback: neutral label beside the amber dot (was teal
  'Enhanced' next to a warning dot — two states in 12pt).
- Deprecated foregroundColor → foregroundStyle in new code; inert scrubber
  play↔pause ease removed (erased style TYPES can't interpolate).
- Mono tap path runs one ISP channel (was 2× identical work).
- NEW Loudness_MeterBridge_TruePeak: the C-ABI bridge end-to-end (multi-buffer
  history continuity, mono aliasing, dBTP mapping); harness now compiles
  LoudnessMeterBridge.cpp — 122/0.

Verified sound by the breaker with evidence: kernel extraction line-identical,
golden-master hash unchanged, oracle green. Ledger + sprint-plan §Status
updated; founder screenshot pass is the remaining part-1 close-out item.
…bs the chevron

Live-screenshot round on the realigned build: (1) the mock right-aligns the tab
strip (logo + device pill left, spacer, tabs on the chrome's right edge —
png/00/png/01); the implementation had kept the old left-packed order. (2) The
PR-B dropdown chevron ate ~14pt of the pill's fixed 288pt name area and
re-truncated 'MacBook Pro Spe…' — the same squeeze class as the PR-6 rate slot;
width 288 → 302 absorbs it exactly. Ledger updated (founder round recorded;
deviation 3 now reads 302).
…4 dead tokens

Founder bug: arrowing the queue changed the hero (and macOS Now Playing) without
changing playback. Cause — the ↑/↓ handler set viewModel.selectedTrackIndex, which
is the app-wide now-playing pointer (hero/footer/glow read it; its didSet fires the
Now Playing refresh). Fix: a view-local keyboard cursor (cursorIndex) in the queue,
distinct from selectedTrackIndex. Arrows move the cursor over the VISIBLE rows (also
fixes navigating onto filter-hidden rows), scroll it into view, and draw the focus
tint; Return plays the cursor row (or toggles the playing one); click lands the
cursor; Delete removes it. selectedTrackIndex — and thus the hero — changes only on
an actual play.

Also: retire dead code the restyle orphaned (periphery --strict, all masked by a
fail-fast gate whose exit code my earlier invocations hid — see the process fix):
TabSelection.icon (text-only tab strip since PR-B), DesignSystem.Color.statusError
(CLIP bar → true-peak amber, PR-E), .meterHot (gradient inlines the Kit token),
.panel (footer bg → styled-glass band, PR-G). Kit Palette tokens stay for R4.

Full strict-gate verified green END TO END (periphery + build + swift test + C++
harness + sanitizers + leaks) — the wave's first honestly-confirmed clean gate.
@ramith
ramith marked this pull request as ready for review July 19, 2026 18:41
@ramith
ramith merged commit 3d16077 into main Jul 19, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant