---
path: /legal/cookies
surface: customer
domain: onboarding-public
auth: anon
source: apps/oshun/web/src/app/legal/cookies/page.tsx
status: walked
last_walked:
  '2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data
  (2xx), console/page-errors, expected content, screenshot verified; manual
  screen-reader and real telemetry-delivery checks pending. Evidence:
  WALKTHROUGH/results/runtime-sweep-2026-05-29.md; content re-verified
  2026-06-03 against current source; 2026-06-28 public-legal-pages Playwright
  pass covered anonymous routing, exact section inventory, legal nav
  matrix/active states, TOC/back-to-top/print shell controls, keyboard-focusable
  scrollable table regions, 390 px no-overflow, 44 px touch targets,
  offline-after-load stability, no telemetry hooks, and axe. Manual AT pass and
  real telemetry delivery remain pending.'
---

# Legal · Cookie Policy

## Purpose

OSHUN's Cookie Policy. Six sections rendered through `LegalPageShell`, including
two tabular reference tables (cookie categories with purpose/duration/required,
and a per-cookie name table).

## Entry points

- Footer link "Cookies" on `/welcome` and `/landing`
- "Learn more" link inside the cookie-consent banner shell
- Sidebar nav from other `/legal/*` pages
- Direct URL / bookmark — yes (anon)

## Layout regions

`page.tsx` defines `SECTIONS`: `what-are-cookies`, `types`, `specific-cookies`,
`managing-preferences`, `third-party`, `contact`.

- **Header (shell)**: minimal brand + back link
- **Sticky sidebar**: cross-legal nav + 6-entry TOC
- **Main article**: h1, `data-legal-date` "Last updated: May 26, 2026", six
  sections including:
  - Two `<table>` blocks wrapped in keyboard-focusable `[data-legal-table-wrap]`
    regions (`role="region"`, `tabIndex={0}`, and an `aria-label` ending in
    "table")
    - Table 1 (cookie types): columns Category / Purpose / Duration / Required,
      four rows (Essential, Functional, Analytics, Marketing)
    - Table 2 (specific cookies): columns Name / Type / Purpose, six rows
      (`oshun-session`, `__session`, `oshun-cookie-consent`, `oshun-theme`,
      `oshun-a11y`, `oshun-onboarding`) — name cells use `data-legal-mono` for
      fixed-width type
- **Floating control**: back-to-top button

## States

- [x] **Loading** — N/A; static
- [x] **Default** — all sections render with both tables
- [x] **TOC click / active section** — clicking a TOC button scrolls to that
      section and marks it `data-active="true"`; passive scroll-spy remains
      `IntersectionObserver`-driven
- [x] **Back-to-top visible** — the shared 44 px control appears after scrolling
      and returns the user near the document start
- [x] **Narrow viewport (≤ 768px)** — tables get horizontal scroll via
      `[data-legal-table-wrap] overflow-x: auto`; sidebar collapses
- [x] **Print** — shell strips sidebar/header/back-to-top; tables retain their
      dotted-rule borders
- [x] **Offline after load** — once loaded, the URL, heading, section inventory,
      and active legal nav state remain stable when the browser context goes
      offline
- [x] **Gated** — N/A; anonymous-readable

## Interactions

### Cross-legal sidebar nav

- [x] **Each `LEGAL_NAV` link** — sibling legal page navigation, active state,
      and at least 44 px mobile target

### On-this-page TOC

- [x] **Each TOC button** (6) — `scrollIntoView` to that section and immediate
      active state after click

### Back-to-top

- [x] **"↑"** — fixed bottom-right, opacity-gated by `scrollY > 300`

### Tables

- [x] **Cookie types table** — non-interactive reference data inside a labelled,
      focusable scroll region
- [x] **Specific cookies table** — non-interactive; cookie names render in mono
      via `[data-legal-mono]`; table wrapper is a labelled, focusable scroll
      region

### Managing-preferences section

References the cookie consent banner ("you can manage your cookie preferences at
any time using the cookie consent banner that appears when you first visit
OSHUN") — there is no in-page launcher for the banner on this route.

## Data & contracts

- **Reads**: none — static text
- **Writes**: none
- **Caching**: SSR static; loaded-route offline stability is asserted. Cold
  offline navigation / per-legal SW path caching is not asserted, and current
  `sw.js` does not path-cache `/legal/*`.
- **Auth**: anon (in middleware `PUBLIC_PREFIXES`)
- **Metadata**: `title: 'Cookie Policy'`,
  `description: 'How OSHUN uses cookies and similar tracking technologies.'`

## Cross-references

- Shell consent banner (referenced but not launched from this page) — see
  [`shell/01-app-shell.md`](../../shell/01-app-shell.md)
- Sibling legal pages: [`legal-privacy.md`](./legal-privacy.md),
  [`legal-terms.md`](./legal-terms.md),
  [`legal-accessibility.md`](./legal-accessibility.md),
  [`legal-ccpa.md`](./legal-ccpa.md), [`legal-dpa.md`](./legal-dpa.md)
- Component sources:
  - `apps/oshun/web/src/components/legal/LegalPageShell.tsx`

## E2E coverage

- Backed by
  [`apps/oshun/web/e2e/public-legal-pages.spec.ts`](../../../apps/oshun/web/e2e/public-legal-pages.spec.ts)
  — covers anonymous access, exact six-section inventory, both table wrappers as
  labelled keyboard-focusable scroll regions, legal nav inventory/active state,
  shared TOC/back-to-top/print shell behavior, 390 px no-overflow, 44 px touch
  targets, offline-after-load stability, no telemetry hooks, and axe.

## Open questions / known gaps

- [ ] Cold offline navigation / per-legal SW cache is not asserted and current
      `sw.js` does not path-cache `/legal/*`; PWA shell cache coverage remains
      in the offline-first / PWA walkthroughs.
- [ ] No "Manage preferences" launcher button on this page — confirm whether the
      cookie banner exposes a re-entry hook (e.g.,
      `window.dispatchEvent('oshun-open-cookie-banner')`)
- [ ] Cookie inventory is hard-coded — confirm whether the live deployment sets
      all six listed cookies or only a subset
- [ ] `LAST_UPDATED` is hard-coded; tie to release notes
