[PC TV] Apple-TV-style depth on focused cards#4580
Draft
david-gonzalez-a8c wants to merge 17 commits into
Draft
Conversation
Three pieces that work together to give focused cards more depth, in the spirit of the Apple TV home screen carousels: - New `focusedCardDepth(isFocused:cornerRadius:)` view modifier that layers a soft drop shadow and a diagonal "lit from above" sheen on a focused card surface. - RootView background swapped from a flat fill to a subtle top→bottom gradient (new `pcBackgroundTop` / `pcBackgroundBottom` tokens). The gradient is a touch lighter than `pcBackgroundSurface` at the top so the new shadows have something to read against. - Applied the modifier to `DiscoverCategoryCell`, `PlaylistCell`, and `DiscoverFeaturedPodcastCell`, with explicit `RoundedRectangle` clips on the first two (the existing `.clipped()` was a bare rectangle). Co-Authored-By: Claude <noreply@anthropic.com>
- pcBackgroundActive steps back from the white/black extremes (#FBFBFC → #D4D6DB in dark, #161718 → #2A2D31 in light) so focused cards read as silvery/charcoal and let the depth treatment do the lifting instead of raw brightness. - Sheen gradient stops bumped (top white .22 → .45, bottom black .10 → .28) and blend mode switched from .plusLighter to .overlay; the old mode was silently swallowing the dark side of the gradient. - Shadow opacity .45 → .6, radius 32 → 44, y-offset 20 → 26. Co-Authored-By: Claude <noreply@anthropic.com>
…ills Extend the depth treatment to the three pill types that were missing it from the Home screen: - `DiscoverVideoEpisodeCell` (Made for TV row) - `NowPlayingRowLabel` (currently-playing pill) - `EpisodeRow` (Up Next pills, also picked up wherever EpisodeRow is used elsewhere) Also push the inner sheen harder: highlight stop bumped to .85 and the gradient now ramps through .45 → .15 → clear → .45 black so the lit edge has a more pronounced glint rather than a uniform glow. Co-Authored-By: Claude <noreply@anthropic.com>
The full diagonal sheen looks great on artwork cards but muddies the cover and text on content-heavy cards. Split the modifier into two styles sharing the same drop shadow: - `.surface` (default): the existing full diagonal sheen, for cards that are mostly artwork or a flat colour. - `.content`: a thin inner stroke that lights the top edge and lays a subtle rim line at the bottom, leaving the body of the card alone. `DiscoverVideoEpisodeCell`, `NowPlayingRow`, and `EpisodeRow` switch to `.content`. The other three (DiscoverCategoryCell, PlaylistCell, DiscoverFeaturedPodcastCell) keep `.surface` via the default. Co-Authored-By: Claude <noreply@anthropic.com>
…on bare covers Three tweaks following on-device review: - PlaylistCell switched to .content — the diagonal sheen was washing the "New playlist" / "Smart playlist" / episode-count text on the left side of the pill. - .surface highlight rebuilt as two stacked passes: a `.plusLighter` top-leading glint that's purely additive (always brightens, never darkens, so it pops on busy artwork) plus an `.overlay`-blended bottom-trailing falloff. The single `.overlay` pass was capping the highlight intensity against artwork; splitting makes it specular. - DiscoverPodcastRow's bare cover thumbnails now get the .surface treatment via a small `FocusedPodcastCover` wrapper that reads the `.card` button's `\.isFocused`. Co-Authored-By: Claude <noreply@anthropic.com>
The Podcasts tab grid was using `NavigationLink + PodcastImage + .buttonStyle(.card)` with no depth treatment, so its covers felt flat next to Discover rows like "You might like" (which I'd already wired up with the depth modifier). Added a parameterless `focusedCardDepth(cornerRadius:style:)` overload that reads `\.isFocused` from the environment, so any view sitting inside a Button/NavigationLink label can opt in without a wrapper struct. Used it for the Your Podcasts grid, and refactored the DiscoverPodcastRow wrapper away to share the same call shape. Co-Authored-By: Claude <noreply@anthropic.com>
The .surface specular was reading as too aggressive in the on-device review. Halved the plus-lighter highlight stops (.55/.25/.08 → .28/.12/ .04) and roughly halved the overlay falloff (.30/.55 → .16/.30) so it reads as a subtle gleam rather than a metallic sheen. In return, push the shared drop shadow harder across both styles — opacity .6 → .85, radius 44 → 60, y 26 → 36 — so cards feel more clearly lifted off the page now that the highlight is doing less of the lifting itself. Co-Authored-By: Claude <noreply@anthropic.com>
- Respect `accessibilityReduceTransparency`: skip the blend-mode sheen (the shadow still lifts the card, just without the translucent overlay). - Respect `accessibilityReduceMotion`: drop the easeInOut timing curve on focus state changes. - `FolderCardView` now also picks up `.surface` depth so folder cells match the podcasts they sit next to in the Podcasts grid. - Added a `#Preview` showing both styles side by side for future tuning. Co-Authored-By: Claude <noreply@anthropic.com>
`EpisodeRow` paints its own background, clip, and focused-card depth when used standalone (Up Next, podcast detail list, player button). Inside `EpisodeRowWithActions`, the outer container needs to be the single card surface so the depth treatment renders across both the row and the more-button gutter — previously the inner row's shadow got clipped by the wider outer clipShape, leaving the depth half-applied. Adds a `providesCardSurface` flag (default true) on `EpisodeRow` with a `fileprivate` init for same-file callers, and moves the card surface onto the outer container in `EpisodeRowWithActions`. Co-Authored-By: Claude <noreply@anthropic.com>
This reverts commit 3b4fb58.
3 tasks
Collaborator
Generated by 🚫 Danger |
The shared `radius: 60, y: 36` shadow pools nicely below roughly-square `.surface` cards but spills out the sides of wide `.content` pills, where the blur radius is comparable to the card's height. The shadow ends up reading as a horizontal halo rather than a downward pool. Split the shadow tuning by style: `.surface` keeps its existing values; `.content` gets a tighter, more directional shadow (opacity .7, radius 26, y 22) that stays under the card. Co-Authored-By: Claude <noreply@anthropic.com>
This reverts commit da4a201.
The focused-card drop shadow was being clipped at the bottom of these ScrollViews, leaving pills with a hard cut edge instead of the soft pool below that covers (which already had `.scrollClipDisabled()` via DiscoverPodcastRow) display. Match that pattern here. Co-Authored-By: Claude <noreply@anthropic.com>
Same root cause as the HomeView fix: every horizontal `ScrollView` that hosts a focused card needs `.scrollClipDisabled()` or its drop shadow gets sliced off at the scroll boundary. Audited the TV app for all `ScrollView(.horizontal)` callsites and added the modifier to the four remaining rows that were missing it: - DiscoverVideoEpisodesRow (Made for TV) - DiscoverFeaturedPodcastsRow (featured carousel) - DiscoverCategoriesRow (category cards) - DiscoverSinglePodcastRow (single-podcast content rows) `DiscoverPodcastRow` already had it from the start. Co-Authored-By: Claude <noreply@anthropic.com>
DiscoverVideoEpisodeCell scales 1.1x on focus (its own state-machine zoom), but Up Next / currently-playing pills scale only 1.02x via EpisodeRowButtonStyle. When the depth modifier sits before the scaleEffect, its shadow gets scaled along with the card — so the video cell's shadow renders ~10% larger than every other pill's, which read as visually oversized. Move `.focusedCardDepth(...)` after the `.scaleEffect(...)` on the video cell so the shadow renders at a consistent native size regardless of how the card itself scales on focus. Co-Authored-By: Claude <noreply@anthropic.com>
Shadow tuned down across the board: opacity .85 → .7, radius 60 → 36, y 36 → 22. At the old values the shadow read as oversized on larger-content cards (the video pill in particular), where the soft 60pt halo spilled well past the card's bottom edge. `.surface` highlight stops roughly halved again (top glint .28 → .16, bottom falloff .30 → .20) so the sheen on covers reads as a gentle gleam rather than a pronounced specular. Co-Authored-By: Claude <noreply@anthropic.com>
The previous `#2B2E32 → #171819` gradient sat very close to black, so the drop shadow on focused cards had little tonal headroom to fall into. Push the dark-mode stops up to `#3D4045 → #22252A` — still a dark surface, but bright enough for the shadow to read as a clear pool below the card. Light mode stops unchanged (already had plenty of contrast). Co-Authored-By: Claude <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.
Summary
Adds depth to focused cards across the tvOS app: each focused surface gets a soft drop shadow and a focus highlight tuned to its content (full diagonal sheen for artwork cards, edge-stroke highlight for text-heavy ones). A subtle top-to-bottom page gradient replaces the flat background so the shadows have something to read against, and
pcBackgroundActiveis stepped back from pure white/black so the focused surface reads as a silvery/charcoal material instead of raw brightness.What changed
focusedCardDepth(...)modifier (FocusedCardDepth.swift) with two styles —.surface(full diagonal specular sheen for artwork) and.content(1.5pt inner-stroke highlight for cover-plus-text cards). Both share the same drop shadow. Accessibility-aware: respectsaccessibilityReduceTransparency(drops the sheen, keeps the shadow) andaccessibilityReduceMotion(drops the easing).PlaylistCell,EpisodeRow,NowPlayingRow.RootViewbackground: flatpcBackgroundSurface→ top→bottomLinearGradientvia newpcBackgroundTop/pcBackgroundBottomtokens.pcBackgroundActiveretuned: dark#FBFBFC→#D4D6DB, light#161718→#2A2D31. Global focus-highlight token — touches every focused surface in the TV app.DiscoverCategoryCellandPlaylistCell(16pt) where they were previously.clipped()rectangles, so the depth overlay matches a real card shape.To test
Checklist
CHANGELOG.mdif necessary. (Visual refinement only; no behavioural change.)#PreviewinFocusedCardDepth.swift.)