# Layout & Frontend Guidelines (Windsurf) Target: **mobile‑first**, dark theme, max content width **960px** on desktop. Reference device: **Nothing Phone 2a**. --- ## 1) Design System ### 1.1 Color (Dark Theme) - `--bg-0: #0b0f14` (page background) - `--bg-1: #11161c` (cards/sections) - `--tx-0: #e6edf3` (primary text) - `--tx-1: #a7b3be` (muted) - `--pri: #ff7a1a` (accent orange) - `--ice: #b9ecff` (ice accent) - `--ok: #3ddc97` - `--warn: #ffcc00` - `--err: #ff4d4d` ### 1.2 Typography - Base font-size: **16px** (mobile), scale up at desktop. - Font stack: System UI (`-apple-system, Segoe UI, Roboto, Inter, Arial, sans-serif`). - Line-height: 1.5 body, 1.2 headings. ### 1.3 Spacing (8‑pt grid) - `--s-1: 4px`, `--s-2: 8px`, `--s-3: 12px`, `--s-4: 16px`, `--s-5: 24px`, `--s-6: 32px`, `--s-7: 48px`, `--s-8: 64px`. ### 1.4 Radius & Shadow - Radius: `--r-1: 8px`, `--r-2: 16px`. - Shadow (subtle): `0 4px 20px rgba(0,0,0,.25)`. --- ## 2) Grid & Layout ### 2.1 Container - **Mobile‑first**: full‑bleed padding. - Desktop container: **max‑width: 960px**, centered. - Side gutters: 16px (mobile), 24px (tablet), 32px (desktop). **Breakpoint summary** | Token | Min width | Container behaviour | Notes | | --- | --- | --- | --- | | `--bp-sm` | 360px | Fluid | Single-column layouts prioritise readability. | `--bp-md` | 480px | Fluid | Allow two-up cards or media/text pairings when needed. | `--bp-lg` | 768px | Max-width 90% (capped at 960px) | Stage tablet/landscape experiences before full desktop. | `--bp-xl` | 960px | Fixed 960px max width | Full desktop grid, persistent side rails allowed. Always respect `env(safe-area-inset-*)` for notch devices (use helpers like `.safe-b`). ### 2.2 Columns - 12‑column grid on screens ≥ **960px**. - Column gutter: 16px (mobile), 24px (≥960px). - Utility classes (examples): - `.row { display:grid; grid-template-columns: repeat(12, 1fr); gap: var(--gutter); }` - `.col-12, .col-6, .col-4, .col-3` for common spans on desktop. - Mobile stacks by default; use responsive helpers at breakpoints. ### 2.3 Breakpoints (Nothing Phone 2a aware) - `--bp-sm: 360px` (small phones) - `--bp-md: 480px` (Nothing 2a width in portrait ~ 412–480 CSS px) - `--bp-lg: 768px` (tablets / landscape phones) - `--bp-xl: 960px` (desktop container) **Mobile layout rules:** - Navigation collapses to icon buttons with overflow menu at `--bp-sm`. - Multi-column sections stack; keep vertical rhythm using `var(--s-6)`. - Sticky headers take 56px height; ensure content uses `.safe-b` for bottom insets. **Desktop enhancements:** - Activate `.row` grid with `.col-*` spans at `--bp-xl`. - Introduce side rail for filters or secondary nav (span 3 or 4 columns). - Increase typographic scale by 1 step (`clamp` already handles this). > **Rule:** Build for < `--bp-lg` first; enhance progressively at `--bp-lg` and `--bp-xl`. --- ## 3) Page Chrome ### 3.1 Header - Sticky top, height 56–64px. - Left: brand; Right: primary action or menu. - Translucent on scroll (backdrop‑filter), solid at top. ### 3.2 Footer - Thin bar; meta links. Uses ice accent for separators. ### 3.3 Main - Vertical rhythm: sections spaced by `var(--s-7)` (mobile) / `var(--s-8)` (desktop). - Cards: background `var(--bg-1)`, radius `var(--r-2)`, padding `var(--s-6)`. --- ## 4) CSS File Strategy (per page) **Every HTML page ships its own CSS file**, plus shared layers: - `/css/base.css` — resets, variables, typography, utility helpers. - `/css/components.css` — buttons, inputs, cards, modals, toast. - `/css/layout.css` — grid/container/header/footer. - `/css/pages/.css` — page‑specific rules (one per HTML page). **Naming** (BEM‑ish): `block__elem--mod`. Avoid nesting >2 levels. **Example includes:** ```html ``` --- ## 5) Utilities (recommended) - Spacing: `.mt-4`, `.mb-6`, `.px-4`, `.py-6` (map to spacing scale). - Flex/Grid: `.flex`, `.grid`, `.ai-c`, `.jc-b`. - Display: `.hide-sm`, `.hide-lg` using media queries. --- ## 6) Toast Messages (center bottom) **Position:** centered at bottom above safe‑area insets. **Behavior:** - Appear for 3–5s; pause on hover; dismiss on click. - Max width 90% on mobile, 420px desktop. - Elevation + subtle slide/fade. **Structure:** ```html
``` **Styles (concept):** ```css #toast-root { position: fixed; left: 50%; bottom: max(16px, env(safe-area-inset-bottom)); transform: translateX(-50%); z-index: 9999; } .toast { background: var(--bg-1); color: var(--tx-0); border: 1px solid rgba(185,236,255,.2); padding: var(--s-5) var(--s-6); border-radius: var(--r-2); box-shadow: 0 10px 30px rgba(0,0,0,.35); margin-bottom: var(--s-4); max-width: min(420px, 90vw); } .toast--ok { border-color: rgba(61,220,151,.35); } .toast--warn { border-color: rgba(255,204,0,.35); } .toast--err { border-color: rgba(255,77,77,.35); } ``` **JS API (minimal):** ```js function showToast(msg, type = "ok", ms = 3500) { const root = document.getElementById("toast-root"); const el = document.createElement("div"); el.className = `toast toast--${type}`; el.role = "status"; el.textContent = msg; root.appendChild(el); const t = setTimeout(() => el.remove(), ms); el.addEventListener("mouseenter", () => clearTimeout(t)); el.addEventListener("click", () => el.remove()); } ``` --- ## 7) Browser Notifications (system tray) **When to use:** Only for important, user‑initiated events (e.g., a new match, message, or scheduled session start). Always provide an in‑app alternative (toast/modal) for users who deny permission. **Permission flow:** ```js async function ensureNotifyPermission() { if (!("Notification" in window)) return false; if (Notification.permission === "granted") return true; if (Notification.permission === "denied") return false; const res = await Notification.requestPermission(); return res === "granted"; } ``` **Send notification:** ```js function notify(opts) { if (Notification.permission !== "granted") return; const n = new Notification(opts.title || "Update", { body: opts.body || "", icon: opts.icon || "/icons/notify.png", tag: opts.tag || "app-event", requireInteraction: !!opts.sticky }); if (opts.onclick) n.addEventListener("click", opts.onclick); } ``` **Pattern:** ```js const ok = await ensureNotifyPermission(); if (ok) notify({ title: "Match window opens soon", body: "Starts in 10 min" }); else showToast("Enable notifications in settings to get alerts", "warn"); ``` --- ## 8) Forms & Inputs - Hit target ≥ 44×44px, labels always visible. - Focus ring: `outline: 2px solid var(--ice)`. - Validation: inline text in `--warn/--err`; never only color. --- ## 9) Performance - CSS: ship **only** what a page uses (per‑page CSS). Avoid giant bundles. - Images: `loading="lazy"`, responsive sizes; WebP/AVIF first. - Fonts: use system fonts; if custom, `font-display: swap`. --- ## 10) Accessibility - Ensure color contrast ratios meet WCAG AA standards (e.g., 4.5:1 for text and 3:1 for large text). - Use semantic HTML elements (
,