# Design: PineAP pages — Mark VII layout Date: 2026-08-11 Status: Approved ## Problem The PineAP section of the Pager WebUI (8 tabs) uses the generic Pager WebUI card layout (`.section`, `.card`, `.tabbar`). The user wants the PineAP pages to look like the WiFi Pineapple Mark VII PineAP page: the `pineap-title-card-container` title-card anatomy (20px card titles with clickable title links, centered 24px values), a full-width Passive/Active/Advanced button group, and Mk7-style section cards. Scope is limited to the PineAP pages (all 8 tabs); the rest of the app and all behavior are unchanged. ## Reference (extracted from Mark VII firmware bundle) The Mk7 PineAP page styles (verbatim class semantics from `mk7-main.js`): ```css .pineap-title-card-container { display:flex; width:100%; flex-wrap:wrap; justify-content:space-between; } .pineap-title-card { flex:1; } .pineap-card-title { font-size:20px; display:flex; align-items:center; margin-bottom:10px; } .pineap-card-title-link { color:inherit; text-decoration:none; } :visited inherit; :hover underline .pineap-card-title-content { display:flex; justify-content:center; align-items:center; font-size:24px; } .pineap-card-button-group { width:100%; height:30px; } .pineap-card-button { width:100%; } .pineap-card-settings, .pineap-card-pool, .pineap-card-handshakes, .pineap-card-inject { flex:1; } .pineap-handshakes-none { display:flex; justify-content:center; font-style:italic; color:grey; } ``` The Recon page in this codebase already replicates this pattern as `recon-*` (`.recon-title-card-container`, `.recon-title-card`, `.recon-card-title-link`, `.recon-card-title-content`) — a proven precedent. ## Design ### 1. Layout vocabulary in `app.css` Add the Mk7 `.pineap-*` classes above, using the codebase's design tokens where the Mk7 used hardcoded colors (e.g., `.pineap-handshakes-none` uses `var(--muted)` for the italic grey text). Card background/shadow come from the existing `.card`-like surface treatment (`var(--surface)` + `var(--shadow)`), applied to a new `.pineap-title-card` surface so title cards match the app's cards. ### 2. Overview tab (full Mk7 rebuild) Three rows, each a `.pineap-title-card-container`: - **Row 1 — stat title cards:** three `.pineap-title-card` cards. Total SSIDs in Pool (link → `#/pineap/impersonation`), Clients Connected (link → `#/pineap/clients`), Handshakes Captured (link → `#/pineap/evilwpa`). Each has a 20px `.pineap-card-title-link` and a centered 24px `.pineap-card-title-content` value. Data and 5s polling unchanged from the current implementation. - **Row 2 — mode + quick settings:** a wide mode card containing the mode badge, the Passive/Active/Advanced `.pineap-card-button-group` (styled as the Mk7 30px group; reuses the existing `.seg-btn` logic) and the mode description line; beside it a `.pineap-card-settings` Quick Settings card (Capture SSIDs to Pool, Advertise AP Impersonation Pool). Preset behavior unchanged (PineAP master + Karma only; `karmaOn` tracking; `modePending` guard; karma-off wins precedence). - **Row 3 — status title cards:** Karma, Open Network, Evil WPA, Evil Enterprise as four `.pineap-title-card` cards with `.pineap-card-title` headings and Configure links (to `#/pineap/open`, `#/pineap/evilwpa`, `#/pineap/enterprise`). ### 3. Other seven tabs Same Mk7 card anatomy, existing tab bar retained as navigation: - **Clients (`#/pineap/clients`):** a `.pineap-title-card-container` with a "Clients Connected" count `.pineap-title-card` above the clients table card. - **Impersonation (`#/pineap/impersonation`):** a "Total SSIDs in Pool" count `.pineap-title-card` (link → pool section) plus the `.pineap-card-pool` pool list card (add/clear, advertise/collect toggles, SSID table). - **Open AP (`#/pineap/open`):** toggle list and info in a `.pineap-card-settings` card with a `.pineap-card-title` heading. - **Evil WPA (`#/pineap/evilwpa`):** config form in a card with `.pineap-card-title`; the handshake capture list becomes `.pineap-card-handshakes` with the `.pineap-handshakes-none` empty state. - **Enterprise (`#/pineap/enterprise`):** enabled/auth toggles in a settings card; Basic/Challenge data tables in `.pineap-card-inject`-style cards. - **Filtering (`#/pineap/filtering`):** client/SSID filter cards with `.pineap-card-title` headings (mode selector + entry tables). - **APs (`#/pineap/aps`):** the AP scan table card with a `.pineap-card-title` heading. ### 4. Behavior unchanged No API or logic changes. All toggles, tables, preset/mode logic, and actions keep their current behavior. The PineAP tab bar (8 tabs) remains the navigation. ## Files touched - `payload/user/general/pager-webui/www/css/app.css` — add `.pineap-*` classes. - `payload/user/general/pager-webui/www/js/views.js` — rebuild the markup of the 8 PineAP tab renderers to the Mk7 card anatomy. No backend changes. No test-module changes. ## Verification 1. JS delimiter balance check (Python checker; no node available). 2. All 13 backend unittest modules pass (unchanged). 3. Deploy via `scripts/deploy.ps1` (password supplied securely), restart `/etc/init.d/pagerwebui`. 4. On-device walk of all 8 PineAP tabs: title cards render with clickable links, counts populate on the 5s poll, mode toggle still applies presets, tables and forms still work.