# Spec: Premium award UI, icons, and code-review hardening ## Requirement: Hardening before premium UI The system MUST correct lifecycle and state-integrity defects before premium visual work is considered complete. ### Scenario: hardening gate precedes visual rollout - GIVEN premium UI work starts - WHEN implementation tasks are planned - THEN tests for listener lifecycle, favorite consistency, reorder persistence, playback state, timer cancellation, and error reporting MUST be written first - AND premium UI tasks SHALL NOT be marked complete until those tests pass with `flutter test` ### Scenario: failures are observable - GIVEN an async operation fails in playback, favorites, or loading - WHEN the failure reaches app state - THEN the system MUST expose a user-visible or test-observable error path - AND it MUST NOT silently swallow the failure without state feedback ## Requirement: Lifecycle-safe subscriptions The system MUST own and cancel every stream subscription/listener created by widgets or app shell. ### Scenario: app error stream is subscribed once - GIVEN dependencies change more than once - WHEN one error message is emitted - THEN the app MUST show at most one SnackBar for that message ### Scenario: visualizer disposes cleanly - GIVEN an audio visualizer or playback indicator is removed - WHEN `estadoStream` emits later - THEN no disposed widget SHALL call `setState` - AND its subscription MUST be cancelled ## Requirement: Consistent favorites and ordering The system MUST derive favorite UI from global state and persist complete ordering after reorder. ### Scenario: reorder persists full list order - GIVEN favorites `[A, B, C]` - WHEN the user moves `A` after `C` - THEN persisted favorites MUST reload as `[B, C, A]` - AND every item SHALL have a deterministic order ### Scenario: favorite state stays in sync - GIVEN the same station appears in card and player surfaces - WHEN favorite is toggled from either surface - THEN all visible favorite icons MUST reflect the updated global state ## Requirement: Playback source of truth The player MUST reconcile route input with `EstadoRadio` current playback state and MUST NOT keep acting on stale station snapshots. ### Scenario: active station changes while player is open - GIVEN the player was opened for station `A` - AND global playback changes to station `B` - WHEN controls or favorite actions render - THEN they MUST target the effective current station - AND labels/artwork/actions SHALL remain consistent ## Requirement: Premium visual system The system MUST define reusable visual tokens for “Ondas vivas globales”: deep violet, electric magenta, warm coral, dark glass surfaces, subtle neumorphism, controlled glow, radius, spacing, and motion. ### Scenario: screens consume tokens - GIVEN a premium screen is rendered - WHEN colors, surfaces, shadows, or motion are applied - THEN they MUST come from shared tokens or theme extensions - AND one-off hardcoded styling SHOULD be avoided ## Requirement: Premium icon system The app MUST use custom PluriWave iconography for primary navigation, playback, favorite, search, settings, live/error/loading, and radio fallback states. ### Scenario: icon states are coherent - GIVEN an icon supports inactive, selected, and active playback states - WHEN each state is displayed - THEN outline, filled, and glow variants MUST preserve the same rounded wave geometry - AND tappable icons MUST keep accessible labels ## Requirement: Five-screen premium refresh Inicio, Buscar, Reproductor, Favoritos, and Ajustes MUST share the premium language, with Reproductor as the strongest reference composition. ### Scenario: mockup scope is implemented coherently - GIVEN the five primary screens are reviewed together - WHEN navigation moves between them - THEN tokens, icon style, hierarchy, empty states, and loading states SHALL feel like one product - AND no primary screen SHOULD fall back to generic Material-only presentation ## Requirement: Accessibility and verification The system MUST preserve accessibility while adding premium visuals. ### Scenario: premium visuals remain usable - GIVEN large text, reduced motion, or high-contrast needs - WHEN premium UI is rendered - THEN content MUST remain readable and controls MUST remain reachable - AND verification MUST use `flutter test`, never `flutter build`