From f674a06a082ae48bc4fa31aa75738817e10c9cce Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Fri, 7 Aug 2026 14:45:15 +0200 Subject: [PATCH] fix(client/apple): the tray blur keeps its shape, and the tab pill turns to glass Two follow-ups from the second on-glass pass: - The tray blur's pop-in survived the geometryGroup: the full-bleed growth (negative padding + safe-area expansion) rode the push's transaction, and safe-area resolution sits outside a geometry group. The scrim now pins its own geometry out of any animation - the layer fade/slide still carries it, only its SHAPE can never animate. The bottom overshoot grows 32 -> 72 pt (the tray sits over scrolling rows plus the detail line; the blur influence starts well above the legend now) and the mask holds strength longer before dissolving. - The selected tab pill is a Liquid Glass surface (accent-tinted through consoleGlass, material fallback pre-26/tvOS) - the strip wears the same material language as the rows below it. The matched-geometry travel between pills is unchanged. --- .../PunktfunkClient/Home/GamepadChrome.swift | 14 +++++++++++--- .../PunktfunkClient/Home/GamepadHomeView.swift | 8 ++++---- .../Settings/GamepadSettingsView.swift | 8 +++++--- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/clients/apple/Sources/PunktfunkClient/Home/GamepadChrome.swift b/clients/apple/Sources/PunktfunkClient/Home/GamepadChrome.swift index 8391a3b1..44334423 100644 --- a/clients/apple/Sources/PunktfunkClient/Home/GamepadChrome.swift +++ b/clients/apple/Sources/PunktfunkClient/Home/GamepadChrome.swift @@ -385,15 +385,23 @@ struct GamepadTrayScrim: View { LinearGradient( stops: [ .init(color: .black, location: 0), - .init(color: .black.opacity(0.9), location: 0.5), + .init(color: .black.opacity(0.92), location: 0.55), .init(color: .clear, location: 1), ], startPoint: fromEdge, endPoint: toContent) } // Grow past the tray so the fade-to-clear happens OUTSIDE its bounds — the tray's own - // text always sits on the strong part, rows blur out before they reach it. - .padding(edge == .top ? .bottom : .top, -32) + // text always sits on the strong part, rows blur out before they reach it. The bottom + // gets the longer runway: its tray sits over SCROLLING rows plus the detail line, and + // the field verdict on the short reach was rows colliding visibly with the legend. + .padding(edge == .top ? .bottom : .top, edge == .top ? -44 : -72) .ignoresSafeArea() + // This view's geometry must NEVER animate: mounted inside a pushed shell layer, the + // full-bleed growth above (the negative padding and the safe-area expansion) rode the + // push's transaction, so the blur visibly entered at content bounds and grew into + // place — and `.geometryGroup()` on the layer does not reach safe-area resolution. + // The layer's own fade/slide still carries the scrim; only its SHAPE is pinned. + .transaction { $0.animation = nil } } } diff --git a/clients/apple/Sources/PunktfunkClient/Home/GamepadHomeView.swift b/clients/apple/Sources/PunktfunkClient/Home/GamepadHomeView.swift index 8c7a6eef..8a826ad1 100644 --- a/clients/apple/Sources/PunktfunkClient/Home/GamepadHomeView.swift +++ b/clients/apple/Sources/PunktfunkClient/Home/GamepadHomeView.swift @@ -124,10 +124,10 @@ struct GamepadHomeView: View { #if os(iOS) if let screen = topScreen { screenLayer(screen) - // Resolve the screen's internal layout (safe-area trays, the scrims' - // `.ignoresSafeArea()` full-bleed) BEFORE the insertion animates: without - // this the tray blurs entered at their content bounds and visibly grew to - // the screen edges mid-push. + // Settle the screen's internal layout before the insertion animates, so + // descendants never lerp from a half-resolved first frame. (Not sufficient + // for the tray blurs on its own — safe-area expansion resolves outside a + // geometry group; GamepadTrayScrim pins its own geometry too.) .geometryGroup() .zIndex(1) .id(screen.id) diff --git a/clients/apple/Sources/PunktfunkClient/Settings/GamepadSettingsView.swift b/clients/apple/Sources/PunktfunkClient/Settings/GamepadSettingsView.swift index b044af86..4358cddc 100644 --- a/clients/apple/Sources/PunktfunkClient/Settings/GamepadSettingsView.swift +++ b/clients/apple/Sources/PunktfunkClient/Settings/GamepadSettingsView.swift @@ -257,10 +257,12 @@ struct GamepadSettingsView: View { .padding(.vertical, 7) .background { // One shared capsule that MOVES between pills, rather than one per pill fading - // in and out — the highlight travels the way the press did. + // in and out — the highlight travels the way the press did. A Liquid Glass + // surface (accent-tinted through consoleGlass), so the strip wears the same + // material language as the rows it sits above. if selected { - Capsule() - .fill(ink.accent(0.85)) + Color.clear + .consoleGlass(Capsule(), tint: ink.accent(0.85)) .matchedGeometryEffect(id: "tab", in: tabHighlight) } }