@startuml !theme plain skinparam backgroundColor #FEFEFE skinparam shadowing false title SmartTools Landing Page Architecture package "Client Browser" { [User] as User [HTML/CSS/JS] as Frontend [Service Worker\n(future)] as SW } package "Web Server (Flask)" { [Landing Page\nController] as LandingCtrl [Template Engine\n(Jinja)] as Jinja [Static Assets\nHandler] as StaticAssets } package "Registry API" { [GET /api/v1/stats/summary] as StatsAPI [GET /api/v1/tools?sort=downloads&limit=6] as ToolsAPI [GET /api/v1/content/announcements] as AnnouncementsAPI } package "Data Layer" { database "SQLite/PostgreSQL" as DB [Cache Layer\n(ETag/Last-Modified)] as Cache } package "External Services" { [Google AdSense] as AdSense [Analytics\n(opt-in)] as Analytics } User --> Frontend : "Visit /" Frontend --> LandingCtrl : "HTTP GET /" LandingCtrl --> StatsAPI : "Fetch download count,\ntool count" LandingCtrl --> ToolsAPI : "Fetch popular tools" LandingCtrl --> AnnouncementsAPI : "Fetch latest announcements\n(optional)" StatsAPI --> DB : "Read aggregated stats" ToolsAPI --> DB : "Read tools sorted\nby downloads" AnnouncementsAPI --> DB : "Read announcements" DB --> Cache : "Set ETag/Last-Modified" Cache --> StatsAPI : "Cached response" Cache --> ToolsAPI : "Cached response" LandingCtrl --> Jinja : "Render template\nwith data" Jinja --> Frontend : "Server-rendered HTML" Frontend --> StaticAssets : "Load CSS, JS, images" StaticAssets --> Frontend : "Cached assets" Frontend --> AdSense : "Load ad script\n(after consent)" Frontend --> Analytics : "Send page view\n(after consent)" Frontend --> SW : "Cache for offline\n(future PWA)" note right of LandingCtrl **Critical Path:** 1. SSR hero section (no API calls) 2. Inline critical CSS 3. Lazy load below-fold content 4. Defer ad scripts **Performance Targets:** - FCP: <1.5s - TTI: <3s - Page weight: <500KB end note note right of Cache **Caching Strategy:** - Stats: 5 min TTL - Tools: 5 min TTL - Static assets: 24h TTL - HTML: ETag-based end note note bottom of AdSense **Ad Placement:** - Optional footer banner only - Lazy-loaded after content - Requires user consent - Fallback: hide on failure end note @enduml