7.5 KiB
Phase 12 Handoff: Reusable Product and Marketing Components
Handoff status
Phase 11 source implementation is complete for tokens, theme, localization, routing, metadata, layout primitives, application shell, accessibility foundations, and global state shells.
Formal Phase 11 acceptance remains blocked by P11-001, P11-002, and P11-003: the pinned Node/pnpm quality suite, browser/accessibility suite, and reviewed visual baselines must run in an unblocked environment. Do not treat a compiled placeholder as evidence that those gates closed.
Read first
docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.mddocs/architecture/ADR-0002_PHASE_11_FOUNDATIONS.mddocs/PHASE_11_IMPLEMENTATION_REPORT_v1.0.mddocs/TOKEN_IMPLEMENTATION_v1.0.mddocs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csvdocs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.mdcontracts/phase9/components/COMPONENT_CONTRACTS_v1.0.mdcontracts/phase9/components/RTL_THEME_MATRIX_v1.0.csvcontracts/phase9/components/RESPONSIVE_BEHAVIOR_MATRIX_v1.0.csvsrc/content/locales/{en,fr,ar}
Component directories and naming
src/components/app-shell/ persistent header, drawer, footer, controls, global states
src/components/foundation/ bidi, icon, live-region, and status primitives
src/components/layout/ container, section, stack, cluster, and responsive grid
src/components/<domain>/ Phase 12 reusable product or marketing components
Use PascalCase component files and matching ComponentName.module.css files. Keep one primary component per file. Do not add barrel exports by default.
Token consumption rules
- Components consume roles from
src/styles/component-tokens.css. - Do not consume raw
--color-blue-*,--color-orange-*,--color-gray-*, or other palette variables in component CSS. - Do not add literal color functions or hexadecimal values outside token declarations.
- Do not edit
src/styles/tokens.css; it is checksum-identical to the Phase 9 authority. - New roles require a documented token migration and validator update.
- Orange remains limited to conversion and approved focus emphasis.
Theme rules
- Use semantic/component tokens only; do not branch component markup by theme.
- Never add a global transition during theme changes.
- Test light and dark explicitly. Test system mode with operating-system changes.
- Do not write a second theme provider or persistence mechanism.
- Do not weaken the nonce-based CSP bootstrap.
Translation-key conventions
- All visible production copy belongs in locale resources.
- Use semantic namespaces matching the component contract, such as
workflow.*ormodules.*. - English, French, and Arabic must retain exact key and scalar-type parity.
- Do not add hidden English fallbacks.
- Arabic is formal Modern Standard Arabic and must receive native review under P9-005/P11-004.
- Components receive typed content props or the established typed message boundary; they do not fetch unrelated translations internally.
Route generation utilities
Use functions from src/lib/localization/config.ts:
localizedPath(routeId, locale)localeSwitchUrl(currentUrl, targetLocale, routeId)routeIdFromPathname(pathname)routeIdFromSlug(locale, slug)hreflangMap(origin, routeId)
Do not concatenate locale routes manually. Do not preserve unknown query parameters or unapproved hashes.
RTL rules
- Arabic uses document-level
dir="rtl"before hydration. - Use logical CSS properties only.
- Use one DOM tree for all directions.
- Directional arrows and connectors may mirror when their meaning requires it.
- Brand marks, vehicle imagery, screenshots, checks, globes, charts, and media controls do not mirror automatically.
- Use
BidiTextfor plates, VINs, reservation IDs, phones, URLs, email addresses, model codes, and mixed-direction values.
Typography utilities
- Latin: Inter Variable stack.
- Arabic: Noto Sans Arabic stack with independent line height.
- Use component-facing type sizes and line-height tokens.
- Keep heading rank semantic; do not choose an
helement for its visual size. - Never use fixed text heights or image-based text.
Layout primitives
Use Container, Section, Stack, Cluster, and ResponsiveGrid from src/components/layout/LayoutPrimitives.tsx before inventing local layout abstractions.
Approved responsive gates remain:
- compact: 320–767 CSS px
- medium: 768–1119 CSS px
- wide: 1120 CSS px and above
Layouts remain content-driven and must pass English, long French, and Arabic independently.
Accessibility primitives and patterns
BidiTextAccessibleIconLiveRegionStatusBadge- global
.visually-hidden - global skip navigation and
#main-content - native
<dialog>pattern demonstrated byMobileNavigation - global
:focus-visible, forced-colors, and reduced-motion foundations
Icon-only controls require an accessible name. Decorative icons are hidden. Do not remove outlines or disable zoom.
Component API conventions
- Props describe meaning, not visual implementation.
- Keep server components as the default.
- Add
'use client'only for interaction, browser APIs, or client navigation state. - Content models must tolerate expansion and missing evidence.
- Unsupported evidence suppresses a component or uses an explicitly approved neutral state.
- Do not invent destinations, claims, prices, metrics, logos, legal copy, or integrations.
Story and test pattern
Phase 10 did not approve Storybook. Use the production shell and the equivalent fixture matrix in tests/fixtures/foundation-matrix.json.
For each component add:
- unit tests for pure behavior and formatting;
- browser keyboard and interaction tests;
- axe coverage on representative rendered states;
- responsive overflow checks at approved widths;
- English, French, and Arabic coverage;
- light and dark coverage;
- RTL behavior checks;
- canonical Chromium snapshots after review.
Open issues affecting Phase 12
At minimum, review P9-001 through P9-016, P10-001 through P10-004, and P11-001 through P11-004 in docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv.
Particularly relevant component gates:
- no demo form until CRM and legal consent are approved;
- no analytics adapter until vendor and consent rules are approved;
- no preview, customer evidence, security claims, public pricing, login URL, or sales contact until each owner closes its issue;
- no final public header/footer identity until RentalDriveGo logo assets are approved.
Files requiring an architecture decision before modification
contracts/phase9/**src/styles/tokens.csssrc/contracts/phase9/**src/lib/security/csp.tssrc/lib/theme/bootstrap-script.tssrc/lib/theme/config.tssrc/lib/localization/config.tssrc/lib/metadata/build-metadata.tssrc/proxy.tsnext.config.tspackage.jsondependency graphplaywright.config.tsbrowser policy
Commands before and after each component change
Before:
pnpm install --frozen-lockfile
pnpm validate
pnpm typecheck
After:
pnpm format:check
pnpm lint
pnpm typecheck
pnpm test:unit
SITE_ORIGIN=http://127.0.0.1:3000 PUBLIC_RELEASE_APPROVED=false pnpm build
pnpm test:e2e
Before packaging:
pnpm manifest:generate
pnpm validate:package
Phase 12 entry condition
Do not begin merge acceptance until the Phase 11 browser suite and visual baselines run successfully in the pinned environment. Development may proceed behind the explicit gates, but release certainty may not be manufactured from optimism and a green syntax scan.