Repository navigation
feat(web): dense TrackRow on Trending behind the track_rows flag - #14684
Merged
Merged
Conversation
Neue light/dark palettes rebuilt around neutral chrome and one accent: - every text pair passes WCAG AA (subdued was 3.5:1 dark / 2.6:1 light) - borders visible in dark mode (1.6:1, was 1.27:1) - primary purple #6A52E0 so white button text passes (5.4:1, was 4.26) - premium is green again (the Neue migration had mapped it to purple) - headings are plain text instead of a gradient - selected nav item sits on a neutral surface, not the accent Type: four weights (400/500/600/700). Body defaults to regular, title to demi-bold, heading/display to bold. Heavy is no longer used by variants. Web fonts: Inter Variable for UI text and Bricolage Grotesque Variable for display/heading, both self-hosted via @fontsource-variable, replacing the 242 KB base64 Avenir in the blocking CSS. Harmony now also emits harmony-no-fonts.css for apps that load fonts themselves (from #14623). Text sets --harmony-font-family on display elements so web's global font-family rule keeps the display face. Mobile picks up the palette and weights through harmony-native; its font files are unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
…ir fallback - Gradient headings and the purple selected nav stay on Classic and Matrix; only Neue gets plain headings and the neutral selected state. - Neue dark: text on the #6A52E0 accent (primary button, secondary hover, pill hover) uses staticWhite. static.white is dark there and gave 3.4:1. - Font stacks list Avenir after Inter, so embed, protocol-dashboard and distro (harmony.css, no Inter) keep rendering in Avenir. - Confetti canvas text uses Inter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dylanjeffers
force-pushed
the
design/track-row
branch
from
October 20, 2026 00:14
9ed0be5 to
3656c5f
Compare
The Neue dark text fix applied to every primary button, so the light green Buy button got near-white text. Only the accent background uses light text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Harmony gains `TrackRow`, a 56px single-line row: rank · 40px artwork · title and artist · plays · favorite · duration · overflow menu. Hover or keyboard focus swaps the rank for a play button and reveals the favorite and menu controls; the playing row shows an equalizer and an accent title. The row is presentational: the app passes links, artwork, formatted numbers and the menu. Web adds `TrackRowTile`, a connected row with the same props as the desktop `TrackTile`, so `TrackLineup` can swap between them with a new `tileVariant` prop. Narrow containers and mobile keep the tile. Trending renders rows when `FeatureFlags.TRACK_ROWS` (`track_rows`, default off) is enabled. At 1440x900 the page shows 11 tracks instead of 3 and a half. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Locked tracks show the price/unlock pill in place of plays, and gated or hidden tracks show their access label next to plays, like the tile. - Owners get no favorite button, matching the tile and the track menu. - Zero play counts render empty instead of "0". - Podcasts and audiobooks show "X left" and "Played", like the tile. - Rank column is 32px and ranks from 100 use a smaller size, so three digits fit. - track_rows defaults on, so pages don't swap tiles for rows once the Optimizely datafile loads. The remote flag is still the kill switch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dylanjeffers
force-pushed
the
design/track-row
branch
from
October 20, 2026 00:19
3656c5f to
4a2fc37
Compare
dylanjeffers
added a commit
that referenced
this pull request
Oct 21, 2026
…14685) ## What Stacked on #14684. The profile page's Tracks and Reposts lineups render Harmony `TrackRow` when `track_rows` is on. Default off, no change otherwise. - `TrackRow` gets an optional `context` node: one 12px line above the row, aligned with the title column, used here for "Artist Pick" with the pin icon. It adds 16px to that row only. - `TrackRowTile` takes `showArtistPick` and fills `context` when the track is the owner's pick, matching the tile's label. - `TrackLineup` no longer applies the two-column grid container in row mode (profile Tracks uses `LineupVariant.GRID` for small tiles; rows span the column). - `ProfilePage` (desktop) reads the flag and passes `tileVariant` to the artist Tracks lineup, the artist Reposts lineup and the user Reposts lineup. ## Feed is intentionally left on tiles A feed item is a post: who reposted it, inline playlists, comment activity. The tile carries that; a 56px row would strip it. Rows are for catalog surfaces (Trending, profiles, search, collections). Keeping Feed on tiles also leaves a control surface for reading the row experiment. ## Verified - `tsc` clean for harmony and web; eslint clean - Dev server, flag forced on: Ljazz profile Tracks shows the pinned track with the "Artist Pick" line, then rows at full column width; Reposts tab renders rows. Radio Juicy (no pick) renders plain rows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
dylanjeffers
added a commit
that referenced
this pull request
Oct 22, 2026
…14700) Phase 1 of the redesign on mobile: tracks in catalog lineups render as 64px rows instead of bordered tiles, matching web (#14684-#14690). Gated by the existing `track_rows` flag, which is on in production, so this reaches RC users through the RC OTA on merge. Feed keeps tiles. **Where:** Trending, Underground, profile Tracks and Reposts, search track results. Collections in mixed lineups (Reposts) stay tiles. Library already uses `TrackList` rows and is unchanged. **Row:** optional rank, 48px art, title, artist with badges, duration (or "12m left" / "Played" for podcasts and audiobooks), and a price/unlock button in place of the duration on locked tracks. - Tap plays (gated tracks open the purchase modal or locked-content drawer, same as the tile). - Long-press opens the track's actions, with a haptic. No kebab: the title gets the space. VoiceOver gets the same menu as a "More options" action. - The playing track gets an accent title and an equalizer on its art. **Code:** - `harmony-native/components/TrackRow`: presentational row. - `lineup-tile/TrackRowTile`: connected row. - `lineup-tile/useOpenTrackOverflow`: overflow actions now shared by `TrackTile` and the row (tile menu unchanged). Rows add share, favorite and repost since they have no inline buttons. - `TrackLineup` gets `tileVariant: 'tile' | 'row'`. **Tested** on the iOS 26.5 simulator (1.5.190 Release build with this bundle swapped in), signed in: Trending rows and ranks, tap to play and switch tracks, equalizer, long-press menu without starting playback, pagination to 50, profile Tracks rows, loading skeletons. Not tested: Android, search results, a locked track's price button, VoiceOver. Mobile `tsc` and eslint are clean locally (mobile CI only runs security checks). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Step two of the redesign, stacked on #14683 (tokens v2). A dense track row replaces the tile on Trending when the
track_rowsflag is on. No change when the flag is off, which is the default.Harmony
TrackRowpackages/harmony/src/components/track-row. Grid: 28px rank · 40px art · title/artist · plays · favorite · duration · menu. Presentational: the app passestitleandsubtitlenodes (links),artwork, pre-formattedplayCountandduration, and amenunode. States: hover/focus-within (surface-1 fill, play button replaces the rank, favorite and menu fade in),isActive(accent title,aria-current),isPlaying(3-bar equalizer, pause icon),isFavorited(heart stays visible in accent),isLoading(skeleton cells). The rank uses the display face. Reduced motion stops the equalizer.Clicking anywhere on the row that is not a link, button or the menu toggles playback, matching the tile.
Web
TrackRowTile(components/track/desktop) has the same contract as the desktopTrackTile: reads the track from the tanquery cache, drives play/pause through the lineup'stogglePlay, favorites throughtracksSocialActions, gated tracks open the locked-content modal, and the overflow menu is the sameTrackMenuconfig as the tile. Artwork comes fromuseTrackCoverArtat 150×150. Draggable like the tile.TrackLineuptakestileVariant?: 'tile' | 'row'. Rows render with no gap between list items; narrow containers and mobile still get the tile.TrendingPageContentreadsuseFeatureFlag(FeatureFlags.TRACK_ROWS)and passes the variant to both the tracks and underground lineups.FeatureFlags.TRACK_ROWS = 'track_rows', defaultfalse. The flag still needs to be created in Optimizely before rollout; locally it can be forced withlocalStorage.setItem('FeatureFlagOverride:track_rows', 'enabled').Verified
tscclean for harmony and web; eslint clean on all touched filesaria-current; light and dark.Not in this PR
🤖 Generated with Claude Code