--- version: alpha name: northgate-mutual-design description: "A deep navy canvas (#0f1620) with cool white ink (#eef2f6), a trust blue (#5b9be0) for the shield and primary action, and a confirm green (#52b788) for approved/paid states. Figtree carries every heading at weight 700; Inter carries the surrounding prose. The system reads as an actual mutual insurer's site, plain and specific, never a fine-print-and-fear-based national carrier's marketing page." --- ## Brand Positioning Northgate Mutual is for policyholders who want to read their own coverage without a lawyer, not a national carrier's fear-based "protect what matters" campaign. It exists because most insurance sites borrow chrome built to sell add-ons (a fear-driven hero, bundling upsells, a claims process buried three menus deep) that has nothing to do with actually understanding a policy. Northgate's bet: the one piece of drama on the page should be the coverage itself becoming whole, a shield drawing itself in four honest segments, nothing hidden behind them. Every visual decision below serves that one bet. If a component doesn't help someone understand coverage or file a claim, or doesn't come from a real insurer interaction (coverage card, claims table, claim status, claim form), it doesn't belong in this system. colors: accent: "#5b9be0" accent-alt: "#52b788" ink: "#eef2f6" ink-muted: "#93a3b8" canvas: "#0f1620" surface: "#161f2c" surface-raised: "#1e2a3a" border: "#2a3849" focus-ring: "#5b9be0" ## Logo / Wordmark System The mark is a rounded-square card containing a shield outline with a checkmark inside, literally a 1:1 miniature of the homepage's `#shield` mechanic at its finished, fully-drawn state. ```svg ``` - **Lockup**: mark, then a `0.5rem` gap, then the wordmark "Northgate Mutual" in Figtree/700, mark always left of the wordmark, never stacked or reversed. - **Minimum size**: mark not smaller than `16px` square, below that the shield outline and checkmark merge. Wordmark not smaller than `0.8rem`. - **Clearspace**: empty margin equal to the mark's own height (22px at default size) on all four sides of the lockup. - **Don't**: recolor the mark for a light background, it only ever renders on `--panel`/`--bg`. Don't show the static mark's shield incomplete or the checkmark missing, the mark represents the finished, whole-coverage state, the drawing-in motion belongs to the homepage hero only. Don't fill the shield solid, it stays an outline, matching "coverage you can see through," not a locked box. Don't rotate or stretch it. ## Color System ### Roles | Role | Token | Value | Used for | |---|---|---|---| | Canvas | `--bg` | `#0f1620` | Page background | | Surface | `--panel` | `#161f2c` | Panels, nav, coverage cards, table header | | Surface raised | `--surface-raised` | `#1e2a3a` | Row hover, input focus bg | | Border | `--border` | `#2a3849` | Panel edges, dividers, table rules | | Ink | `--ink` | `#eef2f6` | Primary text | | Ink muted | `--dim` | `#93a3b8` | Secondary text, helper text, under-review status | | Shield / primary | `--accent` | `#5b9be0` | Shield outline, primary button fill, more-info-needed copy, focus ring | | Confirm / approved | `--accent-alt` | `#52b788` | Checkmark, approved status, paid badge | There is deliberately no red anywhere. A claim needing more information is routine process, not a denial, so it's communicated in the same trust blue the shield uses, a specific sentence naming exactly what's missing. ### Contrast (computed from the hex values above via WCAG relative luminance) | Pairing | Ratio | Passes | |---|---|---| | `--ink` text on `--bg` | ~16.2:1 | AAA | | `--dim` text on `--bg` | ~7.1:1 | AAA | | `--accent` text on `--bg` (more-info copy, links) | ~6.2:1 | AA (body text) | | `--accent-alt` text on `--bg` (approved status, badge) | ~7.3:1 | AAA | | Dark label on `--accent` fill (primary button) | ~6.2:1 | AA | | `--ink` on `--panel` | ~14.7:1 | AAA | | `--ink` on `--surface-raised` | ~12.9:1 | AAA | The rule this table exists to enforce: a button or badge filled with `--accent` always labels itself in a near-black navy (`#06121f`), never `--ink`, white-on-blue at this saturation undershoots the crispness the rest of the system holds to. typography: display: fontFamily: Figtree fontWeight: 700 body: fontFamily: Inter fontWeight: 400 ## Type Scale | Token | Size | Weight | Family | Line-height | Letter-spacing | Used for | |---|---|---|---|---|---|---| | `--text-display` | `clamp(2.25rem, 5.5vw, 3.75rem)` | 700 | Figtree | 1.1 | 0 | Hero H1 only | | `--text-h2` | `1.5rem` (homepage) / `1.4rem` (second page) | 700 | Figtree | 1.2 | 0 | Section headings | | `--text-body` | `1rem` | 400 | Inter | 1.6 | 0 | Paragraph copy | | `--text-small` | `0.85rem` | 400 | Inter | 1.5 | 0.01em | Footer, nav utility links, helper text, table cells, coverage-card detail | Rule for Figtree vs. Inter: Figtree, always bold, is reserved for the hero headline, section headings, and coverage-card names, moments meant to feel confident and plain. Everything else, nav, buttons, form labels, table cells, claim numbers, is Inter, chosen for staying neutral and legible for what is ultimately paperwork. ## Spacing Scale Base unit `8px`. Tokens in use: `--space-2: 0.5rem`, `--space-3: 1rem`, `--space-4: 1.5rem`, `--space-6: 2rem`, `--space-8: 3rem`, `--space-12: 4rem`. ## Shape One radius scale: `--radius: 10px` for panels, coverage cards, inputs, and table containers. `--radius-pill: 999px` for buttons and the approved-claim badge. Nothing else rounds. ## Iconography No icon library. The only non-text glyphs are the logo mark, the shield-and-check illustration, and one Unicode glyph, `✓` (approved), set at the same weight as the text beside it. Claim status is communicated with a plain-language phrase ("Approved", "Under review") paired with color, never a status icon standing alone. If a future page needs more iconography, the fallback is Phosphor (line style, `1.5` stroke), that decision just hasn't been needed yet. ## Motion Principles Scroll draws a shield outline in four segments, top-left, top-right, right side, left side, each one revealed via `stroke-dashoffset` with a short stagger, a checkmark then drawing in once all four sides are complete. The whole sequence plays once per view (`toggleActions: play none none reverse`), reversible by scrolling back up. This is the only scripted animation on either page, everything else (buttons, table rows, form inputs) uses only `:hover`/`:active`/`:focus-visible` CSS transitions. The whole system honors `prefers-reduced-motion` by showing the shield fully drawn with the checkmark already in place, no animation. ### Never-list (written before the impeccable-pass rebuild) 1. No small decorative shield icon stacked below a centered headline, the shield is large (up to 320px, was 160px) and shares the first viewport with the copy in a two-column layout. 2. No two-button CTA row floating free of the shield, the primary action sits beside the intro copy that introduces it. ## Voice & Tone plain, transparent, no fine-print tricks, straightforward about coverage. In practice: - **Button label**: "Get a quote", not "Protect What Matters Most" - **Error message**: "More info needed. Claim #NM-4502 needs a repair estimate to move forward.", not "Action required!" - **Empty state**: "No open claims on file.", not "Nothing here, hopefully it stays that way!" - **Success status**: "#NM-4471, approved and paid", not "Great news! Your claim has been approved! 🎉" ## Accessibility Baseline - Focus ring: `2px solid var(--accent)`, `2px` offset, applied via `:focus-visible` on every interactive element (links, buttons, inputs, select, textarea), never removed without a visible replacement. - Reduced motion: the shield segment draw-in and checkmark both check `prefers-reduced-motion: reduce` and render fully resolved with no animation when it's set. - Minimum tap target: `44px` in the smallest dimension for every button and form control on touch viewports. - Color is never the only signal: claim status pairs color with a specific phrase and claim number, the more-info-needed state pairs blue with a full sentence naming exactly what's missing. ## Components ### Navigation Single-line bar, `64px` tall, `--panel` background with a `--border` bottom hairline, sticky to the top. Left: a small "back to gallery" utility link. Center-left: the mark + wordmark lockup. Right: a Claims link plus one primary button. Collapses to just the lockup and primary button under `480px`, no hamburger, there are only two destinations. ### Buttons Three variants, one radius (`--radius-pill`), one primary accent: - **Primary**: `--accent` fill, dark label, used once per view for the single real action ("Get a quote", "Open a claim"). - **Secondary**: transparent fill, `1px solid --border`, `--ink` label. "Upload estimate" and similar secondary actions. - **Ghost**: text-only, `--dim` label, `--ink` on hover, bold weight matching the rest of the button set. Tertiary actions like "see it come together." All variants define `:hover` (brightness/border shift), `:active` (`transform: scale(0.98)`), `:disabled` (`opacity: .4`, `pointer-events: none`), and `:focus-visible` (accent outline). ### Shield illustration An SVG outline shield built from four separately-revealed stroke segments plus a checkmark, all sharing `pathLength="100"` for consistent `stroke-dashoffset` timing. Purely illustrative, not interactive, exists to make "coverage assembled plainly" visually literal. ### Coverage cards A flat panel per policy type: a Figtree name and one plain sentence naming what it actually covers. No fear-based copy, no "bundle and save" upsell badge. ### Table Header row in `--panel`/`--dim` labels, body rows in `--bg`, one `--border` rule between rows, row hover to `--surface-raised`. Status cells are bold text in `--accent-alt` (approved) or `--dim` (under review), never a bare colored dot. ### Forms Label above control, `--text-small`/`--dim`. Select/input/textarea: `--panel` background, `1px solid --border`, `--radius`, `--ink` text, `--dim` placeholder. On `:focus`, border becomes `--accent` and background lifts to `--surface-raised`. On error, border stays `--accent` (the system's primary accent) and helper text explains what's missing in plain language. ### Status / feedback states - **Loading**: a skeleton shaped like the real content (bars matching text line-heights), not a spinner. - **Empty**: a plain sentence in `--dim`, no illustration. - **Error**: an inline `--accent` message naming the specific claim number and what's needed, never a silent failure. - **Success / status badge**: `--radius-pill`, `1px solid --accent-alt`, `--accent-alt` text on transparent fill, not filled, filled would compete with the primary button's exclusive use of a solid `--accent` fill. ### Footer One row: company name/tagline on the left, real page links on the right (Claims, back to gallery). No invented legal or regulatory-filing text. ## Do's and Don'ts ### Do - Let the shield draw-in be the only scroll-staggered element on the page. - Reserve `--accent` for the shield/primary-action meaning and `--accent-alt` for confirm/approved meaning, keep that split consistent everywhere. - Name specific claim numbers, dates, and what's needed, never vague "pending" language. - Use a dark label on any `--accent`-filled surface. - Keep coverage descriptions to a single plain sentence naming what's actually included. ### Don't - Don't add fear-based hero copy, bundling upsell banners, or a "you could be at risk" framing, this is a plain-language insurer, not a scare campaign. - Don't introduce red for claim states, route those to `--accent` with specific, actionable copy instead. - Don't replay the shield draw-in on every scroll pass, reveal once per view. - Don't stack more than one primary button in the same view. - Don't fill a status badge solid, badges stay outlined so the primary button remains the only solid-`--accent`-fill element on screen. ## Known Constraints - Two routes now exist (home, claims), still no real quoting engine or payment flow, no responsive breakpoint table beyond a single-column mobile collapse, no authenticated policyholder login (the "Get a quote" flow and claim form are not wired to anything real, this is a concept demo).