Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
124 commits
Select commit Hold shift + click to select a range
54ed84e
Improve onboarding and location UX
Merkost Jun 12, 2026
73d7717
Handle map stats network failures
Merkost Jun 12, 2026
61f909b
Document solunar replacement plan
Merkost Jun 12, 2026
7662507
docs: add UI/UX modern-refresh spec, 12 implementation plans, progres…
Merkost Jun 12, 2026
ad11d57
Add Spacing design tokens (commonMain)
Merkost Jun 12, 2026
6081f25
Add Elevation design tokens (commonMain)
Merkost Jun 12, 2026
fca3876
Add Emphasis/alpha design tokens (commonMain)
Merkost Jun 12, 2026
cbc458b
Add Motion design tokens (commonMain)
Merkost Jun 12, 2026
72a3088
Add extraSmall shape + ShapeTokens.bottomSheet; canonical radius scale
Merkost Jun 12, 2026
5dc71d8
Color cleanup: privatise dead palette, add error roles + BrandGradien…
Merkost Jun 12, 2026
ca19cb6
Test token values: Spacing/Elevation/Emphasis/Motion/Shape/error role…
Merkost Jun 12, 2026
624f859
Address Plan 01A review: ReplaceWith imports, correct deprecation rol…
Merkost Jun 12, 2026
aad8633
Add real Nunito 400/500/600/700 weight files (OFL)
Merkost Jun 12, 2026
fdcd84e
Type.kt: per-weight Nunito mapping, tuned lineHeight/letterSpacing, f…
Merkost Jun 12, 2026
37efc7d
Remove obsolete single-weight nunito.ttf
Merkost Jun 12, 2026
4b94fa1
Add AppButton + AppButtonStyle core primitive
Merkost Jun 12, 2026
d51a7ce
Add AppIconButton with enforced 48dp target and required contentDescr…
Merkost Jun 12, 2026
4b7f88c
Add AppText + AppTextStyle + TextWithLeadingIcon with role-mapping test
Merkost Jun 12, 2026
cb1982b
Add AppCard + SectionCard single tokenized card primitives
Merkost Jun 12, 2026
5f7f3ba
Add FormTextField + PickerField input primitives
Merkost Jun 12, 2026
6a98c48
Add no_places_added/no_photos_added empty-state strings (both already…
Merkost Jun 12, 2026
90b9a09
Plan 02A review fixes: clickable SectionCard, IconSize tokens, testab…
Merkost Jun 12, 2026
685193c
Add EmptyState/ErrorState/LoadingState/InlineLoader/ListAppendLoader …
Merkost Jun 12, 2026
83685bf
Add SkeletonBox/SkeletonLine + CardSkeleton/ListItemSkeleton primitives
Merkost Jun 12, 2026
7b81eb7
Add ScreenStateContent<T> crossfade over BaseViewState; uses Motion.m…
Merkost Jun 12, 2026
026d4d4
Add PagedListScaffold<T> generic paged-list state machine
Merkost Jun 12, 2026
d515276
Add AppButtonStyle contract test; verify component library builds + i…
Merkost Jun 12, 2026
bb0e0d2
Add string resources for formatters, banners, and a11y descriptions
Merkost Jun 12, 2026
5e038ac
Add MeasurementFormatter with unit tests
Merkost Jun 12, 2026
b4be6f7
Add UnitFormatter, DateLabels, errorToMessage formatters
Merkost Jun 12, 2026
e32beb6
Add AppNavTransitions and slideUpFadeIn entrance modifier
Merkost Jun 12, 2026
b394706
Fix MeasurementFormatter to round (not truncate) — avoids 0.07->0.06 …
Merkost Jun 12, 2026
b943643
Add surface-colored AppTopBar (small + large variants)
Merkost Jun 12, 2026
3fbaee3
Add AppTabRow and TabbedPager surface tab components
Merkost Jun 12, 2026
f6ebc8c
Add AppBottomNavigation (M3 NavigationBar with branded indicator)
Merkost Jun 12, 2026
c15673d
Add AppScaffold with overlay sync banner and snackbar host
Merkost Jun 12, 2026
00986fc
Add BottomActionBar save/confirm bar
Merkost Jun 12, 2026
adbfa6a
Add EditBottomSheetScaffold edit-sheet shell
Merkost Jun 12, 2026
3a9364f
Add SortOptionsSheet and SettingsSelectionDialog generic selectors
Merkost Jun 12, 2026
25daf0d
Add BrandGradientCard and BrandGradientBackground
Merkost Jun 12, 2026
1eeef49
Add BrandFab with single canonical FabSize
Merkost Jun 12, 2026
5863401
Add FloatingControlSurface and FloatingIconButton
Merkost Jun 12, 2026
5997f5a
Add IconStatChip, CountBadge, StatusLabel chips with badge-state tests
Merkost Jun 12, 2026
f5d7a08
Add InlineBannerCard with Info/Warning/Error tones
Merkost Jun 12, 2026
4165be0
Add AvatarWithBadge with accessible edit badge
Merkost Jun 12, 2026
3353658
Add StatTile, StatTileSkeleton, and StatRow
Merkost Jun 12, 2026
d3a29cc
Add ChartCard with brand-tinted Vico column chart
Merkost Jun 12, 2026
426627d
Add WeatherTrendChart Vico line trend chart
Merkost Jun 12, 2026
c13a1c2
Add WeatherMetric, WeatherStatGrid, WeatherDailyForecastRow, Location…
Merkost Jun 12, 2026
5180b46
Add AppHeroHeader, VersionLabel, LabeledIconButton
Merkost Jun 12, 2026
77d9cb0
Add first-run strings (get started, sign-in cancelled/generic error)
Merkost Jun 12, 2026
9d1cf33
AnimatedResource: a11y description param + placeholder/error fallback
Merkost Jun 12, 2026
db39892
Login: adopt design system (brand gradient, AppButton+icon, inline er…
Merkost Jun 12, 2026
6470711
Onboarding: AppButton + Spacing tokens, 48dp skip, decorative hero, G…
Merkost Jun 12, 2026
966ccee
Home: replace bespoke bottom bar with AppBottomNavigation (48dp, role…
Merkost Jun 12, 2026
0b4d76f
Home shell: route content through AppScaffold so sync banner overlays…
Merkost Jun 12, 2026
ee2fb7e
Add localized short-month and Notes a11y/paging string resources
Merkost Jun 12, 2026
592b5c8
Add KMP-safe localized short-month label formatter with tests
Merkost Jun 12, 2026
d6270a5
Make Notes sort action data-driven via TabItem.hasSortAction
Merkost Jun 12, 2026
eaac91a
Rebuild Notes container on AppTopBar/TabbedPager/SortOptionsSheet
Merkost Jun 12, 2026
341f9b6
Migrate UserCatchesScreen onto shared PagedListScaffold
Merkost Jun 12, 2026
345d44b
Migrate UserPlacesScreen onto shared PagedListScaffold
Merkost Jun 12, 2026
d891f1c
Harden Notes rows: show_on_map a11y label + hide-on-zero CountBadge
Merkost Jun 12, 2026
f8596f0
Migrate Statistics onto ScreenStateContent/StatTile/ChartCard
Merkost Jun 12, 2026
3f10839
feat(weather): add string resources and WeatherFormatters utility
Merkost Jun 12, 2026
0b46653
feat(weather): add WeatherSkeleton loading placeholder
Merkost Jun 12, 2026
4afef72
refactor(weather): replace inline stats/charts with WeatherStatGrid a…
Merkost Jun 12, 2026
4f462bd
refactor(weather): migrate DailyWeatherScreen to AppTopBar and Sectio…
Merkost Jun 12, 2026
eaaf16c
feat(nav): add AppNavTransitions to DailyWeather composable destination
Merkost Jun 12, 2026
2f46a67
Unify weather states/top bar/banner; daily rows as WeatherDailyForeca…
Merkost Jun 13, 2026
8cfa385
Fix daily-screen null state; guard with EmptyState inside Scaffold
Merkost Jun 13, 2026
7b23de3
Add map control content-description strings
Merkost Jun 13, 2026
12d7548
Map FAB uses shared BrandFab + BrandGradients
Merkost Jun 13, 2026
a462f7e
FirstSpotPromptCard delegates to shared StatePromptCard
Merkost Jun 13, 2026
3ac1455
Map controls use shared FloatingControlSurface + FloatingIconButton
Merkost Jun 13, 2026
5c9f136
PlaceTileView uses shared GeocoderResultChip
Merkost Jun 13, 2026
9d6d399
MapScaffold uses DragDismissContainer/DragHandle, visible DismissScri…
Merkost Jun 13, 2026
def88d7
PlaceDetailsCard uses shared SkeletonBox/SkeletonLine + IconStatChip …
Merkost Jun 13, 2026
ec6eead
Map: token sweep (Spacing/Shape) + fabClearance + a11y descriptions
Merkost Jun 13, 2026
b4fc06a
Map: fix offset import in DragDismissContainer
Merkost Jun 13, 2026
fca4282
Add New Catch summary/badge/a11y string resources
Merkost Jun 13, 2026
ef0dbdd
Add CatchSummaryFormatter with unit tests
Merkost Jun 13, 2026
f1c26b4
Add local PlaceField and StatusFilterChip+ChipBadge components
Merkost Jun 13, 2026
d650463
Adopt PlaceField + CatchSummaryFormatter in Essentials section; delet…
Merkost Jun 13, 2026
1c9fe06
Replace DetailChip with StatusFilterChip + typed ChipBadge; single CT…
Merkost Jun 13, 2026
103b82c
Label interactive wind icon; make decorative weather icons explicitly…
Merkost Jun 13, 2026
92809c5
Consolidate numeric input on StepperField; delete legacy FishAmountAn…
Merkost Jun 13, 2026
f90104c
Add more_options and no_notes_added strings for detail screens
Merkost Jun 13, 2026
fbc0a77
Add AppBarOverflowMenu with localized content description
Merkost Jun 13, 2026
b968988
Add AddItemButton unifying the divergent add affordances
Merkost Jun 13, 2026
432ca13
Add LabeledValueRow for read-only display values
Merkost Jun 13, 2026
ca4771e
Add MetricItem unifying metric presentations
Merkost Jun 13, 2026
49b56ad
Add DetailHeader for detail-screen header rhythm
Merkost Jun 13, 2026
20ca91a
Migrate Catch detail sections to SectionCard/MetricItem/LabeledValueRow
Merkost Jun 13, 2026
f992074
Dedupe catch edit sheets via EditBottomSheetScaffold; drop 1dp Spacer…
Merkost Jun 13, 2026
8c89eb1
Migrate DefaultNoteView to SectionCard + LabeledValueRow
Merkost Jun 13, 2026
8a5ad80
Refactor Place detail views: DetailHeader, EmptyState, AddItemButton,…
Merkost Jun 13, 2026
c3a78e3
Add test guarding canonical %1\$s placeholder in delete-dialog strings
Merkost Jun 13, 2026
57164d6
Add parameterized register-date and edit-photo strings
Merkost Jun 13, 2026
882d73d
Wire EditProfile photo pick + upload via SavePhotosUseCase
Merkost Jun 13, 2026
8aeeed9
Test EditProfile photo upload-on-save behavior
Merkost Jun 13, 2026
48eadf5
Assert register-date formatter shape
Merkost Jun 13, 2026
59ac55e
Rebuild Profile + EditProfile on shared design-system components
Merkost Jun 13, 2026
c698487
Mark Plan 09 (Profile & Edit Profile) complete in tracker
Merkost Jun 13, 2026
dd8d9a3
Add app_version_format and about_this_app strings
Merkost Jun 13, 2026
a5022c4
Add luminance-aware contrastingCheckTint helper with tests
Merkost Jun 13, 2026
9a9acb1
Extract SelectableColorSwatch and ColorSwatchRow
Merkost Jun 13, 2026
f5bb7e7
Add SettingsSelectionDialog, ExpandableSettingsSection, SettingsNavLink
Merkost Jun 13, 2026
30ae8a1
Token SettingsComponents spacing and divider alpha
Merkost Jun 13, 2026
cc8d669
Rebuild SettingsScreen on SettingsSelectionDialog, swatches, InlineBa…
Merkost Jun 13, 2026
af9ef38
Rebuild AboutApp on AppHeroHeader, VersionLabel, LabeledIconButton
Merkost Jun 13, 2026
b2b45a6
Remove dead duplicate SettingsSelectionDialog overload
Merkost Jun 13, 2026
3c040c8
Mark Plan 10 (Settings & About) complete in tracker
Merkost Jun 13, 2026
7378c9e
Remove legacy button composables (replaced by AppButton/AppIconButton)
Merkost Jun 13, 2026
3ff9afe
Remove legacy text composables (replaced by AppText/TextWithLeadingIcon)
Merkost Jun 13, 2026
357b30a
Remove legacy card variants (replaced by AppCard/SectionCard)
Merkost Jun 13, 2026
f3eb9b1
Remove legacy NoContentView/NoInternetView/ErrorView (replaced by Emp…
Merkost Jun 13, 2026
dd0aeb6
Remove duplicate custom GoogleButton (Login uses kmpauth GoogleButton…
Merkost Jun 13, 2026
d285aa3
Consistency/a11y sweep: remove stray uppercase/hardcoded colors/off-g…
Merkost Jun 13, 2026
bacea52
Add regression fence asserting legacy composables stay removed
Merkost Jun 13, 2026
3ceceeb
Mark Plan 11 complete; document migration tail surfaced by grep gates
Merkost Jun 13, 2026
eeb1039
Migrate all call sites off legacy text/button/card wrappers
Merkost Jun 13, 2026
9dcfe13
Delete dead legacy wrappers; modernize NoContentView; extend fence
Merkost Jun 13, 2026
11c4c19
Mark Plan 13 complete; migration tail resolved
Merkost Jun 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
530 changes: 530 additions & 0 deletions docs/solunar-api-replacement.md

Large diffs are not rendered by default.

158 changes: 158 additions & 0 deletions docs/superpowers/plans/00-PROGRESS.md

Large diffs are not rendered by default.

815 changes: 815 additions & 0 deletions docs/superpowers/plans/2026-06-12-01-foundation-tokens-theme.md

Large diffs are not rendered by default.

1,360 changes: 1,360 additions & 0 deletions docs/superpowers/plans/2026-06-12-02-core-components-primitives-state.md

Large diffs are not rendered by default.

2,492 changes: 2,492 additions & 0 deletions docs/superpowers/plans/2026-06-12-03-core-components-chrome-brand-content.md

Large diffs are not rendered by default.

767 changes: 767 additions & 0 deletions docs/superpowers/plans/2026-06-12-04-firstrun-app-shell.md

Large diffs are not rendered by default.

990 changes: 990 additions & 0 deletions docs/superpowers/plans/2026-06-12-05-notes.md

Large diffs are not rendered by default.

1,270 changes: 1,270 additions & 0 deletions docs/superpowers/plans/2026-06-12-06-weather.md

Large diffs are not rendered by default.

642 changes: 642 additions & 0 deletions docs/superpowers/plans/2026-06-12-07-new-catch.md

Large diffs are not rendered by default.

1,559 changes: 1,559 additions & 0 deletions docs/superpowers/plans/2026-06-12-08-detail-place-catch.md

Large diffs are not rendered by default.

901 changes: 901 additions & 0 deletions docs/superpowers/plans/2026-06-12-09-profile.md

Large diffs are not rendered by default.

1,121 changes: 1,121 additions & 0 deletions docs/superpowers/plans/2026-06-12-10-settings-about.md

Large diffs are not rendered by default.

668 changes: 668 additions & 0 deletions docs/superpowers/plans/2026-06-12-11-final-sweep.md

Large diffs are not rendered by default.

618 changes: 618 additions & 0 deletions docs/superpowers/plans/2026-06-12-12-map-screen.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Plan 13 — Legacy Wrapper Consolidation (migration tail)

**Goal:** Achieve full design-system adoption by migrating every remaining call site off the legacy text/button/card wrappers onto the shared `AppText`/`AppButton`/`AppIconButton`/`AppCard` primitives, then deleting the now-dead wrappers. This eliminates the parallel-component duplication the Plan 11 grep gates surfaced (incl. the all-caps `.uppercase()` button styling).

**Constraints (inherit from the whole migration):**
- KMP/iOS-safe: all edits stay in `commonMain`; no `android.*`/`java.*`/`com.google.android.gms` imports. `:shared:compileKotlinIosSimulatorArm64` must pass.
- **NEVER add code comments** (project CLAUDE.md). Remove existing stale comments in code you rewrite only if they are obviously dead; do not add new ones.
- Match surrounding style; keep imports tidy (remove now-unused legacy imports).

---

## Authoritative mapping table

All new components live in `com.mobileprism.fishing.ui.home.views` except `EmptyState*` (`com.mobileprism.fishing.ui.components.state`).

`AppText(text, modifier, style: AppTextStyle, color, textAlign, maxLines, overflow)` — `AppTextStyle { Display, Heading, Title, Subtitle, Body, BodySmall, Caption, Support }` mapping to `displaySmall/headlineSmall/titleLarge/titleMedium/bodyLarge/bodyMedium/bodySmall/labelMedium`. Default `color = LocalContentColor.current`, `textAlign = null` (Start), `overflow = Ellipsis`.

### Text wrappers → AppText
| Legacy | New | Notes |
|---|---|---|
| `BigText(text, textAlign?, textColor?)` | `AppText(text, style = AppTextStyle.Display, color = textColor, textAlign = textAlign)` | displaySmall. If caller omits textColor, omit color (defaults differ negligibly — `onSurface` ≈ default content). |
| `SubtitleText(text, textColor?, maxLines?, textAlign?)` | `AppText(text, style = AppTextStyle.Subtitle, color = onSurfaceVariant, maxLines, textAlign)` | titleMedium. Default color was `customColors.secondaryTextColor` → use `MaterialTheme.colorScheme.onSurfaceVariant`. |
| `PrimaryText(text, textAlign?, textColor?, maxLines?)` | `AppText(text, style = AppTextStyle.Title, color = textColor, textAlign, maxLines)` | titleLarge. No caller passes `fontWeight`, so it is dropped. If caller omits textColor, omit color. |
| `PrimaryTextSmall(text, textAlign?, maxLines?, textColor?)` | `AppText(text, style = AppTextStyle.BodySmall, color = textColor, textAlign, maxLines)` | bodyMedium. |
| `SecondaryText(text, maxLines?, textAlign?, textColor?)` | `AppText(text, style = AppTextStyle.Body, color = onSurfaceVariant, textAlign = TextAlign.Center, maxLines)` | bodyLarge. **Default textAlign is Center — preserve it: pass `TextAlign.Center` unless the caller passed a different align.** Default color → `onSurfaceVariant`. |
| `SecondaryTextSmall(text, maxLines?, textAlign?, textColor?)` | `AppText(text, style = AppTextStyle.BodySmall, color = onSurfaceVariant, textAlign = TextAlign.Center, maxLines)` | bodyMedium. **Same Center-default rule.** |
| `SupportText(text, style?, maxLines?)` | `AppText(text, style = AppTextStyle.BodySmall, color = onSurfaceVariant, maxLines = 1)` | bodyMedium; legacy forced `maxLines = 1` — keep `maxLines = 1`. |
| `SecondaryTextColored(text, style?, color?, maxLines?, textAlign?)` | `AppText(text, style = <see below>, color = <caller's color>, maxLines, textAlign)` | Per-site. **Only 2 callers:** `NotesViews` ItemDate chip → `style = AppTextStyle.BodySmall, color = MaterialTheme.colorScheme.inverseOnSurface`. `TextFields` helperText → `style = AppTextStyle.Caption, color = MaterialTheme.colorScheme.onSurfaceVariant`. |

When a caller passes an explicit `textColor`/`color`, forward it verbatim. When it passes an explicit `textAlign`, forward it (do not also force Center).

### Button wrappers → AppButton / AppIconButton
`AppButton(text, onClick, modifier, style: AppButtonStyle, enabled, loading, leadingIcon: Painter?)` — `AppButtonStyle { Filled, Tonal, Outlined, Text }`. Drops the legacy `.uppercase()` and hardcoded `tertiary` colors (uses theme).
`AppIconButton(onClick, icon: Painter, contentDescription: String /*required*/, modifier, enabled, tint)` — enforces ≥48dp.

| Legacy | New |
|---|---|
| `DefaultButton(icon?, text, enabled?, textColor?, onClick)` | `AppButton(text = text, onClick = onClick, style = AppButtonStyle.Text, enabled = enabled, leadingIcon = icon)` |
| `DefaultButtonSecondaryLight(icon?, text, enabled?, onClick)` | `AppButton(text, onClick, style = AppButtonStyle.Text, enabled, leadingIcon = icon)` |
| `DefaultButtonOutlined(icon?, text, enabled?, onClick)` | `AppButton(text, onClick, style = AppButtonStyle.Outlined, enabled, leadingIcon = icon)` |
| `DefaultButtonFilled(icon?, text, enabled?, onClick)` | `AppButton(text, onClick, style = AppButtonStyle.Filled, enabled, leadingIcon = icon)` |
| `DefaultIconButton(childModifier?, icon, contentDescription, tint?, onClick)` | `AppIconButton(onClick = onClick, icon = icon, contentDescription = contentDescription, modifier = childModifier, tint = tint)` — if a caller passes `contentDescription = null`, supply a real localized string instead. |

### Card wrapper → AppCard
`AppCard(modifier, onClick: (() -> Unit)?, shape, elevation, contentPadding, content: ColumnScope)` — whole-card clickable, fillMaxWidth, surface, `Elevation.card`.

| Legacy | New |
|---|---|
| `DefaultCardClickable(modifier, shape?, padding?, onClick, content)` | `AppCard(modifier = modifier, onClick = onClick, contentPadding = 0.dp) { content }` — **pass `contentPadding = 0.dp`**: the legacy content provides its own inner `.padding(12.dp)`, so AppCard must not add its 16dp default on top. Outer spacing the caller applied via `modifier.padding(...)` is preserved. |

### Inline empty primitive — `NoContentView` (KEEP, modernize)
`NoContentView` is an **inline** centered empty (fillMaxWidth), distinct from the full-screen `EmptyState` (fillMaxSize). It is NOT duplicative — keep it, but rebuild its body on design-system primitives: replace its raw `Text(... color = customColors.secondaryTextColor)` with `AppText(text, style = AppTextStyle.Body, color = onSurfaceVariant, textAlign = TextAlign.Center)` and its icon tint `customColors.secondaryIconColor` → `MaterialTheme.colorScheme.onSurfaceVariant`. Keep its signature `(modifier, text, icon: Painter)` and all call sites unchanged.

### Off-grid `.dp` (opportunistic, only in files you already touch)
While editing a file, replace off-grid spacing literals (`6/10/14/18/22.dp`) with the nearest `Spacing`/`IconSize` token (4→`Spacing.xs`, 8→`Spacing.sm`, 12→`Spacing.md`, 16→`Spacing.lg`, 24→`Spacing.xl`; icon sizes 16→`IconSize.sm`? confirm: `IconSize { sm=18, md=24, lg=32 }` — so 18→`IconSize.sm`, 24→`IconSize.md`). Do not chase off-grid values in files outside your assigned set.

---

## Execution
- **Phase A (parallel, per-file):** migrate every legacy call site in the assigned file(s) per the table. Do NOT run gradle (parallel builds conflict); make precise edits only. Fix imports.
- **Phase B (after barrier, controller):** modernize `NoContentView`; grep-gate-delete the now-dead wrappers (8 text, 5 button, 1 card); delete emptied files (`Text.kt`, `Buttons.kt`); extend the `LegacyComponentRemovalTest` regression fence; run `:shared:compileDebugKotlinAndroid` + `:shared:compileKotlinIosSimulatorArm64` + `:shared:testDebugUnitTest` + `:androidApp:installDebug`.

## File partition (Phase A)
1. `home/notes/NotesViews.kt` (14 — incl. DefaultCardClickable×4, DefaultIconButton, SecondaryTextColored, PrimaryText, SupportText)
2. `home/weather/WeatherViews.kt` (10) + `home/weather/WeatherScreen.kt` (3)
3. `home/views/Dialogs.kt` (6) + `home/views/PhotoViews.kt` (2) + `home/views/DefaultViews.kt` (any button caller)
4. `home/map/MarkerInfoDialog.kt` (5) + `home/map/NewPlaceBottomSheet.kt` (1) + `home/new_catch/NewCatchSections.kt` (2)
5. `home/views/TextFields.kt`, `home/views/Counters.kt`, `home/views/AppBar.kt`, `home/profile/Profile.kt`, `home/place/PlaceViews.kt`, `home/catch/Catch.kt`, `home/catch/CatchScreenDialogs.kt` (1 each)

## Success criteria
- Zero references to the 14 legacy wrapper symbols remain (grep-gate clean); their definitions deleted.
- Both targets compile; tests green; app installs.
- No `.uppercase()` introduced; no code comments added; no `customColors` left in the touched text/empty code paths.
Loading
Loading