f88961885c
VYNDR 2.0 conversion, Phase F (mobile is the PWA we launch first). Frontend-only; zero backend changes. - BottomTabBar rewritten to the §6 5-tab spec: Slate/Terminal/Scan/Ledger/More, with Scan as the prominent raised grade-green action. Shown for anon too (only mobile nav). Integrated More bottom sheet (sheet-up, backdrop dismiss, 48px mono rows). iOS safe-area + 44px touch targets. - Nav hamburger retired on mobile (tab bar owns nav). - globals.css mobile section: tab-bar hidden >=768, main bottom padding, grade-hero 80px, terminal-grid stacks, game-lines horizontal scroll. - PWA: manifest shortcuts (Slate/Scan/Terminal) + categories; viewport-fit=cover. Gotcha: `as const` on the TABS array broke type-check (distinct literal types); fixed with a shared TabDef interface. 19 new tests. Backend 1853 -> 1872, 145 suites, zero regressions. Web build clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
24 lines
1.1 KiB
JSON
24 lines
1.1 KiB
JSON
{
|
|
"name": "VYNDR — Sports Prop Intelligence",
|
|
"short_name": "VYNDR",
|
|
"description": "Grade your props with intelligence the books don't want you to have.",
|
|
"start_url": "/dashboard",
|
|
"scope": "/",
|
|
"display": "standalone",
|
|
"background_color": "#06060B",
|
|
"theme_color": "#06060B",
|
|
"orientation": "portrait-primary",
|
|
"categories": ["sports", "finance", "productivity"],
|
|
"shortcuts": [
|
|
{ "name": "The Slate", "short_name": "Slate", "url": "/dashboard", "description": "Tonight's games and graded props" },
|
|
{ "name": "Scan a prop", "short_name": "Scan", "url": "/scan", "description": "Grade any player prop" },
|
|
{ "name": "The Terminal", "short_name": "Terminal", "url": "/terminal", "description": "League intelligence hub" }
|
|
],
|
|
"icons": [
|
|
{ "src": "/favicon.svg", "sizes": "any", "type": "image/svg+xml" },
|
|
{ "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" },
|
|
{ "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any" },
|
|
{ "src": "/icons/icon-maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
|
|
]
|
|
}
|