# PATTERN LIBRARY - reusing this across other service pages

## Design tokens (`cwc-shell.css` `:root`)

| Token | Value | Use |
|---|---|---|
| `--cwc-green` | `#12bf6b` | brand fills, sticky bar, primary buttons |
| `--cwc-green-dark` | `#12975d` | hover/active |
| `--cwc-green-ink` | `#0b6b41` | **green text on white** (AA-safe), focus rings |
| `--cwc-ink` / `--cwc-ink-70` | `#000` / `#3d4844` | body / secondary text |
| `--cwc-grey` | `#f5f7f6` | tinted sections + footer |
| `--cwc-line` | `#e2e7e4` | borders |
| `--cwc-radius` | `15px` | buttons (matches live site) |
| `--cwc-max` | `1600px` | shell container |
| `--cwc-font-head` | gilroy-heavy | all headings, buttons |
| `--cwc-font-body` | proxima-nova | body |

Never hard-code a hex in a component - add a token.

## Component inventory

| Component | Class | Notes / variants |
|---|---|---|
| Button | `.cwc-btn` | `--primary`, `--ghost`, `--onDark`, `--block`; min-height 48 px |
| Legacy button | `.button` | header/footer only - keeps live-site parity |
| Eyebrow pill | `.cwc-eyebrow` | seasonality / category cue |
| Section | `.cwc-section` | `--tint` for grey background |
| Wrapper | `.cwc-wrap` | 1280 px content column (narrower than the 1600 px shell by design) |
| Hero | `.cwc-hero` | `__media`, `__inner`, `__ctas`, `__assure`; swap 1-col/2-col for variants |
| Quote card | `.cwc-card` + `.cwc-field` | reusable enquiry form; `.cwc-rail` makes it sticky ≥1200 px |
| Alert | `.cwc-alert--ok` / `--err` | toggled with `data-show` |
| Feature tile | `.cwc-tile` | icon + h3 + body; auto-fit grid |
| Stat / problem card | `.cwc-stat` | left green rule |
| Process step | `.cwc-step` | auto-numbered via CSS counter |
| Plan card | `.cwc-plan` | `--featured` + `.cwc-tag` |
| Client logo wall | `.cwc-logos` | ul/li/img, grayscale to colour on hover |
| Stat figure | `.cwc-figure` | b + span, used in `.cwc-figures` grid |
| Logo strip | `.cwc-logos` | grayscale, lazy |
| FAQ accordion | `.cwc-faq__item/__btn/__panel` | button + `aria-expanded` + `hidden` panel |
| Coverage block | `.cwc-coverage` | list + map |
| CTA band | `.cwc-band` | dark green closing band |
| Mobile sticky CTA | `.cwc-sticky-cta` | call + quote, ≤900 px |
| Breadcrumb | `.cwc-crumbs` | pair with BreadcrumbList JSON-LD |
| Night band | `.cwc-section--night` | dark frost-navy section; pair with `.cwc-ice-texture` and `.cwc-grain` |
| Ice texture | `.cwc-ice-texture` | decorative frost/snowflake SVG tile for dark bands |
| Grain overlay | `.cwc-grain` | very low-opacity noise so dark bands are not flat |
| Frost glass | `.cwc-frost` | `backdrop-filter` blur + translucent white border, opaque fallback |
| Gradient text | `.cwc-gradient-text` | green→ice gradient clip, used on emphasised words |
| Hand-drawn underline | `.cwc-underline` | inline SVG stroke that draws in on load; off under reduced motion |
| Season chip | `.cwc-eyebrow` + `#cwcSeasonChip` | pulsing dot; JS rewrites the text by date, static fallback in HTML |
| Cold eyebrow | `.cwc-eyebrow--cold` | ice-blue variant of the eyebrow chip for dark bands |
| Scroll cue | `.cwc-hero__scroll` | gently bobbing "see how it works" affordance |
| Reading progress | `.cwc-progress` | 3 px brand-green bar at the top of the content area |
| Trust strip | `.cwc-trustband` + `.cwc-proof` | dark accreditation band; each proof point fires `trust_element_click` |
| Logo marquee | `.cwc-marquee` | duplicated list (clone `aria-hidden`), pauses on hover/focus-within, static grid under reduced motion |
| Animated counter | `.cwc-figure` + `data-count` | counts up on first view; final value is the HTML text so it is correct with JS off |
| Cost estimator | `.cwc-calc` | paired range + number inputs, live count animation, `[hidden]` until JS enables it |
| Timeline | `.cwc-timeline` / `.cwc-tstep` | 4 steps, night→morning gradient numerals, connecting line draws in via `.is-drawn` |
| Video poster card | `.cwc-videocard` | poster image + play glyph button; loads the `<video>` only on click |
| Comparison grid | `.cwc-compare` | tick/cross feature rows under the plan cards; fires `plan_compare_view` |
| Sector chip | `.cwc-chip` | toggleable pill with `aria-pressed`; fires `sector_click` |
| Depot dots | `.cwc-depots` | decorative pulsing dots over the coverage map, `aria-hidden`, off under reduced motion |
| Input group | `.cwc-inputgroup` | joined input + button (postcode search) with a single shared focus ring |
| Smart sticky CTA | `.cwc-sticky-cta` | shows after the hero, hides while `#quote` or `#finalBand` is on screen |
| Angled divider | `.cwc-edge-top` | CSS-only frost wedge between light and dark bands |

## Rules for a new service page

1. Copy `gritting-service.html`, keep the header/footer includes untouched.
2. Change only: `<title>`, meta, JSON-LD (`Service.name`, FAQ entries,
   breadcrumb), hero copy/image, tiles, steps, plans, sectors.
3. Keep the section order - hero → problem → benefits → process → plans →
   trust → coverage → FAQ → CTA band. It is the tested conversion sequence.
4. Add tracking by adding `data-cwc-event` + `data-cwc-location` to new CTAs.
   No JS changes needed.
5. Keep exactly one `<h1>`, and mirror any FAQ change into the FAQPage JSON-LD.
6. Run the pixel-parity check in `INTEGRATION.md` §4 before publishing - it is
   the only way header/footer drift gets caught.


## Design tokens (`assets/cwc-page.css`)

All values are CSS custom properties on `:root`. Never hardcode a hex in markup.

| Token | Purpose |
|---|---|
| `--cwc-green`, `--cwc-green-dark`, `--cwc-mint` | brand action colours; green stays the only primary CTA colour |
| `--cwc-night-900` … `--cwc-night-700` | deep frost navy/teal darks for night bands |
| `--cwc-ice` | ice-blue accent, used sparingly for cold/frost cues only - never as a CTA |
| `--cwc-ink`, `--cwc-ink-70`, `--cwc-line` | body text, muted text, hairline borders |
| `--cwc-e1`, `--cwc-e2`, `--cwc-e3` | three elevation levels |
| `--cwc-r-sm`, `--cwc-r-lg`, `--cwc-r-xl` | radii |
| `--cwc-dur-1`, `--cwc-dur-2`, `--cwc-dur-3` | motion durations |
| `--cwc-ease-out`, `--cwc-ease-spring` | snappy ease-out and soft spring easing |
| `--cwc-frost-bg`, `--cwc-frost-border` | frosted glass surface + fallback |

## Shared behaviour (`assets/cwc-page.js`)

* **Reveal system** - add `data-reveal` (and optional `data-reveal-delay="160"`)
  to any element. An `IntersectionObserver` adds `.is-in` once. Hiding is applied
  by the `js-reveal` class on `<html>`, so with JS off everything is visible.
* **Reduced motion** - every animation above is wrapped in
  `@media (prefers-reduced-motion: reduce)` overrides, and the JS checks
  `matchMedia` so counters and the estimator jump straight to their final value.
* **Tracking** - one delegated listener on `[data-cwc-event]`. New CTAs need no
  JS, just `data-cwc-event` + `data-cwc-location`.
