init project
@@ -0,0 +1,147 @@
|
||||
# Phase 9: Developer Handoff
|
||||
|
||||
## 1. Scope
|
||||
|
||||
This handoff converts the approved homePageCar design system and Phase 8 prototype into implementation contracts for a multilingual rental-car SaaS marketing website. It covers the homepage, demo-booking flow, guided product tour, responsive navigation, theme selection, locale routing, SEO language relationships, analytics boundaries, accessibility, assets, validation, and release gates.
|
||||
|
||||
It does **not** approve unverified capabilities, customer evidence, integrations, certifications, service levels, prices, legal language, CRM behavior, or usability acceptance.
|
||||
|
||||
## 2. Implementation authority
|
||||
|
||||
Use this precedence when files disagree:
|
||||
|
||||
1. `DECISION_LOG_v9.0.md`
|
||||
2. `09_DEVELOPER_HANDOFF_v1.0.md`
|
||||
3. component, localization, interaction, token, and QA contracts in this package
|
||||
4. Phase 8 prototype as behavioral reference only
|
||||
|
||||
The prototype is not production source code. Its inline rendering, simulated submission, local research logging, illustrative product UI, and placeholder contact destination must not be copied blindly.
|
||||
|
||||
## 3. Required architecture properties
|
||||
|
||||
The implementation must:
|
||||
|
||||
- render public pages server-side or statically with correct `lang`, `dir`, canonical, and reciprocal `hreflang` before hydration;
|
||||
- use strict TypeScript for application code;
|
||||
- consume semantic CSS custom properties, never component-local brand hex values;
|
||||
- use one component tree for LTR and RTL;
|
||||
- use locale-prefixed routes and stable route IDs;
|
||||
- persist explicit theme preference in a first-party cookie and mirror it in local storage;
|
||||
- run the pre-paint theme bootstrap before blocking styles;
|
||||
- keep all public strings outside component source except documented proper names and immutable technical identifiers;
|
||||
- use native semantic controls unless a documented accessibility review approves a replacement;
|
||||
- provide deterministic state URLs or test fixtures for every visual-regression state;
|
||||
- gate production analytics behind approved consent rules and exclude form values and free text.
|
||||
|
||||
## 4. Breakpoints and layout modes
|
||||
|
||||
Breakpoints are layout decisions, not device labels.
|
||||
|
||||
| Mode | CSS range | Reference frames | Required behavior |
|
||||
|---|---:|---|---|
|
||||
| Compact | 0–767 px | 320, 390 | One-column sections; mobile drawer; stacked CTAs; product preview simplified; no horizontal page scroll |
|
||||
| Medium | 768–1119 px | 768, 1024 | Two-column where specified; mobile drawer remains; 4-column workflow allowed; balanced content widths |
|
||||
| Wide | 1120 px and above | 1280, 1440 | Desktop navigation and controls; 12-column composition; hero 7/5 split; max container 1280 px |
|
||||
|
||||
Do not infer new behavior between breakpoints. Follow `components/RESPONSIVE_BEHAVIOR_MATRIX_v1.0.csv`.
|
||||
|
||||
## 5. Theme contract
|
||||
|
||||
Supported preferences are exactly `light`, `dark`, and `system`. Preference and resolved theme are separate values.
|
||||
|
||||
- Cookie: `hpc-theme`, value `light|dark|system`, `Path=/`, `SameSite=Lax`, one-year max age, `Secure` in production.
|
||||
- Local storage mirror: `hpc.theme.preference`.
|
||||
- Root attributes: `data-theme-preference` and resolved `data-theme` (`light|dark`).
|
||||
- Cookie wins if cookie and local storage disagree.
|
||||
- Default with no stored preference: `system`.
|
||||
- System updates live on `prefers-color-scheme` changes.
|
||||
- Theme application has no global transition.
|
||||
- Set `color-scheme` to the resolved theme.
|
||||
- The bootstrap must run in `<head>` before blocking CSS and use a CSP nonce or approved hash.
|
||||
|
||||
See `interaction/theme-bootstrap_v1.0.js` and `implementation/theme-config_v1.0.ts`.
|
||||
|
||||
## 6. Localization and routing contract
|
||||
|
||||
Public routes are locale-prefixed: `/en`, `/fr`, `/ar`. English is source/default/fallback, but missing translations fail CI.
|
||||
|
||||
- Root `/` may redirect using explicit cookie, then `Accept-Language`, then English.
|
||||
- Explicit locale URLs are never overridden automatically.
|
||||
- Arabic renders `<html lang="ar" dir="rtl">`; English and French render `dir="ltr"`.
|
||||
- Locale switching maps by stable route ID, preserves query parameters approved in the route manifest, and preserves valid section hashes.
|
||||
- Atomic LTR values inside Arabic use `<bdi dir="ltr">` or an equivalent isolation primitive.
|
||||
- Language does not determine currency, country, timezone, tax, or phone formatting.
|
||||
- Reciprocal `hreflang` entries include `en`, `fr`, `ar`, plus `x-default` pointing to `/en`.
|
||||
|
||||
See the localization directory for exact rules and generated resources.
|
||||
|
||||
## 7. Component implementation
|
||||
|
||||
Every public component must implement:
|
||||
|
||||
- semantic anatomy and heading rules;
|
||||
- props and state enums from `implementation/component-contracts_v1.0.ts`;
|
||||
- explicit compact/medium/wide behavior;
|
||||
- light/dark behavior via tokens;
|
||||
- LTR/RTL behavior via logical CSS and selective icon mirroring;
|
||||
- keyboard and focus behavior;
|
||||
- visible-copy keys and content bounds;
|
||||
- stable test IDs only where semantic selectors are insufficient.
|
||||
|
||||
No component may introduce a fixed height for translated text, validation messages, cards, buttons, or headings.
|
||||
|
||||
## 8. Demo form production contract
|
||||
|
||||
Required fields: full name, work email, company, fleet-size range. Optional fields: market/country, preferred language, message.
|
||||
|
||||
Submission state machine:
|
||||
|
||||
`idle → validating → submitting → success | recoverable_error | terminal_error`
|
||||
|
||||
Rules:
|
||||
|
||||
- preserve entered data on recoverable service failure;
|
||||
- focus the first invalid field after summary announcement;
|
||||
- show inline errors and a form-level summary;
|
||||
- do not use a toast as the only error record;
|
||||
- disable duplicate submission while a request is in flight;
|
||||
- attach an idempotency key to each intentional submission;
|
||||
- do not log names, emails, company names, messages, or raw server responses;
|
||||
- render final consent only after Legal approval;
|
||||
- provide an alternate contact path only after Sales approves a real destination;
|
||||
- success copy must accurately describe what the backend actually did.
|
||||
|
||||
The CRM endpoint, consent language, routing, retries, spam controls, and duplicate policy are release blockers in the issue register.
|
||||
|
||||
## 9. Motion and overlays
|
||||
|
||||
- Drawer opens from inline-start: left in LTR, right in RTL.
|
||||
- Drawer and dialogs trap focus, make background inert, support Escape, and return focus to the trigger.
|
||||
- Backdrop dismissal is allowed for non-destructive dialogs; pending form submission blocks accidental dismissal.
|
||||
- Animations are 160–220 ms and use opacity/transform only.
|
||||
- `prefers-reduced-motion: reduce` removes smooth scrolling, transforms, shimmer, and non-essential progress animation.
|
||||
- No information, success, or error state may depend on animation.
|
||||
|
||||
## 10. Assets and evidence
|
||||
|
||||
Only assets in `assets/ASSET_MANIFEST_v1.0.csv` with status `approved` may ship. The current product preview is `illustrative` and must either receive written approval or be replaced by an evidence-governed product capture before launch.
|
||||
|
||||
Product captures require metadata for locale, direction, theme, capture date, product version, approval owner, and expiry/review date. Never mirror, recolor, or invert captures.
|
||||
|
||||
## 11. Quality gates
|
||||
|
||||
A production candidate must pass:
|
||||
|
||||
- locale key parity and linguistic review;
|
||||
- all listed browser and viewport scenarios;
|
||||
- keyboard, screen-reader, zoom, reflow, forced-colors, and reduced-motion checks;
|
||||
- light/dark/system and LTR/RTL visual regression;
|
||||
- form validation, network failure, duplicate, retry, consent, and CRM integration tests;
|
||||
- performance budgets in `qa/PERFORMANCE_BUDGETS_v1.0.json`;
|
||||
- zero open Critical or High issues;
|
||||
- approved evidence and legal content only;
|
||||
- the complete definition of done.
|
||||
|
||||
## 12. Explicitly unresolved
|
||||
|
||||
The final framework, browser policy owner, analytics vendor, CRM, consent implementation, spam protection, product-tour media, market assumptions, multi-location claim, pricing, integrations, security evidence, legal documents, and participant acceptance are not approved. The package supplies a vendor-neutral implementation and a default technical profile, but each unresolved item remains visible and owned in `OPEN_ISSUE_REGISTER_v1.0.csv`.
|
||||
@@ -0,0 +1,198 @@
|
||||
# homePageCar — Decision Log
|
||||
|
||||
**Version:** 9.0
|
||||
**Phases:** 1 — Design Foundation through 9 — Developer Handoff
|
||||
|
||||
| ID | Decision | Status | Rationale | Consequence |
|
||||
|---|---|---|---|---|
|
||||
| D-001 | Use restrained operational blue as the main brand family | Approved | Supports trust, clarity, and product-led presentation | Blue carries navigation, links, selection, and routine primary actions |
|
||||
| D-002 | Reserve orange for demo conversion and tightly related emphasis | Approved | Preserves conversion salience and prevents visual noise | Orange is not a routine navigation or generic action color |
|
||||
| D-003 | Use Inter Variable for English and French | Approved | Screen-oriented, broad Latin support, strong UI and marketing utility | One Latin family across website and product-facing UI |
|
||||
| D-004 | Use Noto Sans Arabic for Arabic | Approved | Broad Arabic-script support and suitable sans-serif structure | Arabic receives separate metrics and locale loading |
|
||||
| D-005 | Use one token system with separate display and UI roles | Approved | Avoids two unrelated systems while respecting different density needs | Marketing headings and application labels do not share identical sizing |
|
||||
| D-006 | Adopt blue-600 `#1B5DD8` as brand anchor | Approved | Clear operational blue with useful lighter and darker neighbors | Accessible action background uses blue-700 |
|
||||
| D-007 | Adopt orange-600 `#EA580C` as accent anchor | Approved | Strong conversion accent without becoming the whole brand | White-text conversion CTA uses orange-700 |
|
||||
| D-008 | Ban orange-600 with white normal text | Approved restriction | 3.56:1 contrast fails normal-text AA | Use orange-700 in light theme or orange-400 with dark text in dark theme |
|
||||
| D-009 | Use a 4 px spacing base | Approved | Predictable, scalable, compatible with compact and spacious layouts | Exceptions require explicit optical rationale |
|
||||
| D-010 | Use 4/8/12 column grids for mobile/tablet/desktop | Approved | Distinct responsive composition without device-specific hacks | Reference frames: 390, 1024, 1440 px |
|
||||
| D-011 | Cap primary container at 1280 px | Approved | Protects readability while allowing strong product visuals | Wider screens gain outer breathing room, not stretched text |
|
||||
| D-012 | Use CSS logical properties | Approved | Required for real LTR/RTL parity | Physical left/right spacing tokens are rejected |
|
||||
| D-013 | Use Lucide as the base icon family | Approved | Consistent 24 px grid and 2 px outline language | Mixing icon families requires a documented exception |
|
||||
| D-014 | Prefer 44 × 44 px interactive targets | Approved | Exceeds the WCAG 2.2 minimum and improves usability | Compact exceptions must remain accessible |
|
||||
| D-015 | Require formal Modern Standard Arabic | Approved | Prevents inconsistent regional dialect and preserves professional tone | All Arabic product and marketing copy must be linguistically reviewed |
|
||||
| D-016 | Avoid automotive racing clichés | Approved | Product is operational software, not performance-car entertainment | No speedometers, racing stripes, carbon fiber, or aggressive neon styling |
|
||||
| R-001 | Use orange for every primary button | Rejected | Destroys conversion hierarchy | Routine primary actions remain blue |
|
||||
| R-002 | Force identical line-height across scripts | Rejected | Damages Arabic readability and vertical rhythm | Arabic uses script-specific line heights |
|
||||
| R-003 | Use fixed-width translated buttons | Rejected | Breaks under French expansion and Arabic content | Buttons are content-driven |
|
||||
| R-004 | Mirror all icons in RTL | Rejected | Many icons are semantically direction-neutral | Mirror only directional meaning |
|
||||
| R-005 | Create one type scale for every context | Rejected | Marketing and dense UI have different jobs | Shared foundations, separate role scales |
|
||||
| D-017 | Use English as source, default, and fallback locale | Approved | Provides one controlled authoring source while all public locales remain independently addressable | Missing translations fail CI; production fallback is logged |
|
||||
| D-018 | Use locale-prefixed public URLs for every indexable page | Approved | Makes language state shareable, crawlable, and deterministic | All navigation and SEO generation use a central route manifest |
|
||||
| D-019 | Limit automatic locale detection to root `/` | Approved | Respects explicit URLs and prevents redirect loops or crawler interference | Locale-prefixed pages are never overridden by browser language |
|
||||
| D-020 | Persist explicit language selection in a first-party cookie | Approved | Allows SSR to honor user choice without relying on client-only state | Manual choice outranks Accept-Language |
|
||||
| D-021 | Use localized public slugs backed by stable route IDs | Approved | Improves localized readability while preventing routing logic from depending on translated strings | Switchers, sitemaps, and canonicals map by route ID |
|
||||
| D-022 | Use English/French LTR and Arabic document-level RTL | Approved | Correct browser bidi and layout behavior requires root direction | Arabic pages render `html lang=ar dir=rtl` |
|
||||
| D-023 | Use formal Modern Standard Arabic only | Approved | Maintains professional, region-neutral baseline | Dialect and colloquial copy fail linguistic review |
|
||||
| D-024 | Use Latin digits and Gregorian dates in the language-only baseline | Approved | Keeps operational data and identifiers consistent before market-specific preferences exist | Revisit only after Arabic market research |
|
||||
| D-025 | Use `فحص المركبة` for vehicle inspection | Approved | Clear operational term with broad formal comprehension | `معاينة المركبة` remains a documented secondary term |
|
||||
| D-026 | Use `عقد الإيجار` for rental agreement | Approved | Concise and standard legal-operational label | Jurisdictional legal review remains required |
|
||||
| D-027 | Use `مبلغ الضمان` for security deposit | Approved | Avoids confusion between deposit and insurance | Arabic `تأمين` alone is rejected |
|
||||
| D-028 | Use `معدل استخدام الأسطول` for fleet utilization rate | Approved | Describes use rather than occupancy | Occupancy language is rejected |
|
||||
| D-029 | Keep currency, country, timezone, tax, and phone behavior independent from language | Approved | Language-only locales do not define business jurisdiction | Formatting consumes explicit data and context |
|
||||
| D-030 | Use semantic namespaced translation keys | Approved | Supports reuse, context, QA, and refactoring | Source sentences, positions, and visual styles are not keys |
|
||||
| D-031 | Fail missing translations in CI | Approved | Prevents silent partial localization | Production fallback is a logged safety net, not the workflow |
|
||||
| D-032 | Use self-canonical locale pages and reciprocal language-only hreflang | Approved | Prevents English from swallowing localized indexing | `x-default` points to `/en` until a neutral selector exists |
|
||||
| D-033 | Omit regional Open Graph locale until target markets are approved | Approved | Avoids inventing country-region assumptions | Localized OG copy still ships |
|
||||
| R-006 | Use country flags as language controls | Rejected | Languages are not equivalent to countries | Display language names in their own language |
|
||||
| R-007 | Redirect explicit locale URLs based on browser language | Rejected | Breaks shareability, intent, crawling, and testing | Detection is root-only |
|
||||
| R-008 | Use IP geolocation to choose language | Rejected | Country is not language and geolocation is unreliable | Use explicit preference and Accept-Language |
|
||||
| R-009 | Use English source sentences as translation keys | Rejected | Copy edits become code changes and context is lost | Use semantic namespaced keys |
|
||||
| R-010 | Simulate Arabic by right-aligning an LTR document | Rejected | Does not provide correct bidi or layout behavior | Set document-level RTL |
|
||||
| R-011 | Translate check-in/check-out like hotel terminology | Rejected | Misstates rental operational processes | Use pickup, handover, and return terms by perspective |
|
||||
| R-012 | Infer currency or legal jurisdiction from locale | Rejected | English, French, and Arabic span multiple markets | Use explicit business data |
|
||||
| R-013 | Publish placeholder logos, metrics, testimonials, or certifications | Rejected | Creates unsupported evidence | Hide evidence sections until approved sources exist |
|
||||
| D-034 | Organize the library into foundations, behavior primitives, and marketing composites | Approved | Prevents page-specific composition from masquerading as a reusable primitive | Component APIs and ownership follow explicit tiers |
|
||||
| D-035 | Share behavior primitives with the future product dashboard, not marketing composites by default | Approved | Marketing and operational interfaces have different density and interaction requirements | Dashboard reuse requires a later density specification |
|
||||
| D-036 | Use one Button component with primary-blue and conversion-orange intents | Approved | Preserves hierarchy and avoids duplicated behavior | Orange remains restricted to demo and related conversion |
|
||||
| D-037 | Require content-driven dimensions and prohibit truncation of important copy | Approved | French/Arabic expansion and zoom invalidate fixed text geometry | Components change structure before collision |
|
||||
| D-038 | Require visible labels for all form fields | Approved | Placeholders disappear and are unreliable accessible context | Placeholder-only fields fail review |
|
||||
| D-039 | Use native HTML semantics as the baseline for controls, tables, disclosures, and dialogs | Approved | Native behavior reduces accessibility defects | Custom widgets require separate interaction contracts |
|
||||
| D-040 | Use a native date input as the Phase 3 Gregorian baseline | Approved | Custom date pickers are complex and requirements are unresolved | Custom calendar work is deferred |
|
||||
| D-041 | Use one culturally neutral full-name field in the demo form | Approved | First/last assumptions fail across naming systems | CRM mapping preserves the complete name |
|
||||
| D-042 | Keep the demo form minimally qualified | Approved | Extra fields increase abandonment and privacy burden | Required: full name, work email, company, fleet-size range |
|
||||
| D-043 | Evidence-gate metrics, testimonials, case studies, trust marks, and pricing | Approved | A visual component must not make unsupported content publishable | Missing or expired approval suppresses rendering |
|
||||
| D-044 | Approve pricing cards and pricing comparison as separate components | Approved | Plan orientation and detailed comparison are distinct tasks | Both may coexist; neither ships without approved pricing |
|
||||
| D-045 | Open mobile navigation from inline-start | Approved | Aligns navigation origin with document direction | Drawer opens left in LTR and right in RTL |
|
||||
| D-046 | Require overlay focus containment, inert background, Escape policy, and focus return | Approved | Visual layering without focus management is inaccessible | Drawer/modal implementations need behavioral tests |
|
||||
| D-047 | Place toasts at inline-end and keep critical errors persistent in context | Approved | Locale-aware placement and durable correction prevent missed failures | Error toasts cannot be the sole error record |
|
||||
| D-048 | Use the same component tree for LTR and RTL | Approved | Direction-specific implementations drift | Direction is resolved through document state, logical CSS, and selective mirroring |
|
||||
| D-049 | Respect reduced-motion preferences and keep motion non-essential | Approved | Motion should support continuity, not gate understanding | Shimmer and transforms are removed or minimized |
|
||||
| D-050 | Use English light/LTR only for the initial specimen while requiring full locale/theme tests | Approved | Gives a concrete first specimen without pretending it proves conformance | Acceptance still requires en/fr/ar and light/dark |
|
||||
| R-014 | Create separate LTR and RTL component implementations | Rejected | Guarantees drift and mismatched behavior | Use one semantic component tree |
|
||||
| R-015 | Use fixed-height cards, buttons, labels, or validation regions | Rejected | Breaks expansion, zoom, and Arabic metrics | Use content-driven block sizes |
|
||||
| R-016 | Publish placeholder metrics, logos, testimonials, certifications, or prices | Rejected | Converts missing evidence into deception | Omit until approval exists |
|
||||
| R-017 | Open navigation or critical content on hover only | Rejected | Excludes keyboard and touch users | Use explicit triggers and focus behavior |
|
||||
| R-018 | Use placeholder text instead of visible form labels | Rejected | Loses context after input and harms accessibility | Labels remain visible |
|
||||
| R-019 | Replace native select/date controls for visual consistency alone | Rejected | Adds keyboard, screen-reader, mobile, and localization risk | Native controls are baseline |
|
||||
| R-020 | Force marketing composites into the future product dashboard | Rejected | Shared appearance is not shared information architecture | Share primitives; specify product compositions later |
|
||||
| R-021 | Combine pricing cards and comparison into one shape-shifting component | Rejected | Merges distinct tasks and creates brittle responsive behavior | Maintain separate components |
|
||||
| R-022 | Auto-dismiss critical errors without a persistent correction path | Rejected | Users can miss failure and lose context | Keep errors in the owning form/page |
|
||||
| D-051 | Expose Light, Dark, and System as explicit appearance choices | Approved | Users need deterministic control while retaining platform preference support | Theme selector and persistence support all three values |
|
||||
| D-052 | Persist System as an explicit choice | Approved | System is a user preference, not merely missing state | OS changes update resolved theme while the selector remains System |
|
||||
| D-053 | Use `hpc-theme` cookie as canonical preference and local storage as a mirror | Approved | SSR needs a readable value; client tabs need immediate synchronization | Cookie wins disagreement; both are written together |
|
||||
| D-054 | Separate theme preference from resolved theme | Approved | System can resolve to Light or Dark without losing the user choice | Root uses `data-theme-preference` and `data-theme` |
|
||||
| D-055 | Apply theme before first paint with server state and a tiny inline bootstrap | Approved | Prevents incorrect-theme flash and hydration mismatch | Bootstrap runs before blocking CSS and receives a CSP nonce/hash |
|
||||
| D-056 | Use deep-navy dark surfaces rather than pure black or mechanical inversion | Approved | Preserves operational hierarchy and reduces glare without flattening the UI | Dark surface ladder uses canvas, surface, subtle, and raised roles |
|
||||
| D-057 | Use light blue with deep-navy text for routine primary actions in dark mode | Approved | Maintains brand recognition and high contrast without a luminous button wall | Dark primary action roles differ from light while preserving intent |
|
||||
| D-058 | Use orange-400 with dark text for conversion actions in dark mode | Approved | Meets contrast and preserves controlled conversion salience | Orange remains restricted to demo conversion and related emphasis |
|
||||
| D-059 | Use neutral-black dark shadows and prohibit colored glow elevation | Approved | Glow reduces precision and makes hierarchy noisy | Elevation uses borders, surface steps, and neutral shadows |
|
||||
| D-060 | Permit semantically equivalent light/dark hero artwork variants | Approved | Dark presentation may need art direction without changing the product claim | Same content/composition; only presentation treatment changes |
|
||||
| D-061 | Do not make product screenshots automatically follow website theme | Approved | A screenshot is evidence of an actual product state | Store capture theme metadata; never invert or recolor captures |
|
||||
| D-062 | Allow paired screenshot variants only for equivalent approved product states | Approved | Theme matching is useful only when evidence remains truthful | Content model records capture theme, locale, direction, and approval |
|
||||
| D-063 | Use theme-specific chart tokens plus redundant non-color encoding | Approved | Color-only data is inaccessible and fragile across themes | Charts use labels, markers, dashes, patterns, or data tables |
|
||||
| D-064 | Keep theme changes immediate and non-essential motion reduced | Approved | Global cross-fades create flash, noise, and intermediate contrast failures | No global theme transition; reduced motion removes shimmer/rotation |
|
||||
| D-065 | Update System mode live when the platform preference changes | Approved | System should continue following its stated source | Media-query changes update resolved theme only while preference is System |
|
||||
| D-066 | Set `color-scheme` from the resolved theme | Approved | Native controls and browser UI must match the rendered appearance | Selects, dates, autofill, scrollbars, and validation UI require browser testing |
|
||||
| R-023 | Create dark mode by inverting the light palette | Rejected | Numeric inversion destroys semantic hierarchy and brand intent | Map every role explicitly |
|
||||
| R-024 | Use pure black canvas and pure white text everywhere | Rejected | Produces harsh contrast and flattens hierarchy | Use deep navy and off-white/blue-gray text roles |
|
||||
| R-025 | Add blue/orange glows to cards, charts, buttons, or dialogs | Rejected | Turns operational software into decorative noise | Use neutral elevation and restrained emphasis |
|
||||
| R-026 | Store theme only in local storage and apply after hydration | Rejected | Causes incorrect-theme flash and prevents correct SSR | Use cookie, pre-paint bootstrap, and server state |
|
||||
| R-027 | Treat System as an unpersisted default | Rejected | Loses the user’s explicit preference | Persist System exactly like Light and Dark |
|
||||
| R-028 | Recolor, invert, or mirror screenshots for dark mode | Rejected | Misrepresents the product and can corrupt direction/data meaning | Use approved captures or a neutral frame |
|
||||
| R-029 | Encode chart series or status using color alone | Rejected | Fails accessibility and weakens print/forced-colors behavior | Add labels, markers, patterns, icons, or text |
|
||||
| D-067 | Use explicit bidi isolation for atomic mixed-direction values | Approved | Arabic labels frequently contain LTR operational identifiers whose punctuation otherwise reorders | Known technical values use `dir=ltr` and `bdi`/isolation at the smallest boundary |
|
||||
| D-068 | Use `dir=auto` only for genuinely unknown user-authored text | Approved | Known value classes have deterministic direction while free text may not | Translation resources and known identifiers never delegate direction to heuristics |
|
||||
| D-069 | Mirror icons by semantic metadata rather than global RTL CSS | Approved | Global mirroring corrupts object, status, brand, and evidence assets | Icon instances declare directional, fixed, or contextual behavior |
|
||||
| D-070 | Keep DOM order aligned with Arabic visual and focus order | Approved | CSS reversal creates inaccessible mismatch and brittle responsive behavior | `row-reverse`, `column-reverse`, CSS `order`, and positive tabindex are prohibited for RTL repair |
|
||||
| D-071 | Make Arabic mobile navigation enter from inline-start | Approved | Navigation origin should follow document direction | Drawer enters from the right in Arabic and retains full focus management |
|
||||
| D-072 | Let Arabic workflow progression run from right to left while preserving authored step order | Approved | Process reading should feel native without reversing data or source arrays | Natural RTL layout places step one on the right; mobile remains top-to-bottom |
|
||||
| D-073 | Keep chronological chart axes and trend meaning independent from RTL | Approved | Data chronology and increase/decrease meaning are domain semantics, not text direction | Charts are not automatically reversed and trend arrows are fixed |
|
||||
| D-074 | Preserve authoritative license-plate value and segment direction | Approved | Plate formats vary by country and may mix scripts | Latin, Arabic, and segmented plates use explicit direction; country templates remain market configuration |
|
||||
| D-075 | Require Arabic Light desktop and Arabic Dark mobile validation sheets | Approved | The riskiest direction/theme/responsive combinations need explicit evidence | 1440 Light desktop and 390 Dark mobile become release gates |
|
||||
| D-076 | Confirm Latin digits and Gregorian dates as the Phase 5 language-only baseline | Approved | Phase 2 already separated language from market formatting | Arabic-Indic digits or alternate calendars require explicit market research and configuration |
|
||||
| D-077 | Use visual arrow-key movement for horizontal RTL tabs and similar composites | Approved | Keyboard commands should match spatial expectation while preserving authored sequence | ArrowLeft moves visually left and ArrowRight visually right; implementation maps to logical index |
|
||||
| R-030 | Mirror every SVG or image under `dir=rtl` | Rejected | Reverses logos, vehicles, screenshots, status icons, plates, and evidence | Mirror only explicitly directional icons |
|
||||
| R-031 | Reverse arrays or use CSS row-reverse to make Arabic look correct | Rejected | Breaks DOM/focus order and causes responsive drift | Preserve authored order and rely on document direction/logical layout |
|
||||
| R-032 | Insert Unicode bidi override characters into translation strings | Rejected | Hidden controls are fragile, difficult to audit, and can create spoofing risk | Use semantic markup and isolation wrappers |
|
||||
| R-033 | Reverse chronological charts because the page is RTL | Rejected | Text direction does not redefine time or data chronology | Chart order follows the chart specification |
|
||||
| R-034 | Infer license-plate format, currency, timezone, or country from Arabic language | Rejected | Arabic spans many jurisdictions | Consume explicit business and market configuration |
|
||||
| R-035 | Leave technical fields RTL and compensate with right text alignment | Rejected | Caret, punctuation, selection, and copy behavior remain broken | Use explicit LTR direction and isolation for known technical values |
|
||||
| D-078 | Use content-pressure breakpoints rather than device-name breakpoints | Approved | Translated copy, controls, and product evidence fail at different widths | Shared ranges coordinate layout, while intrinsic sizing and container queries control components |
|
||||
| D-079 | Validate 1440, 1024, and 390 px frames plus a 320 px reflow gate | Approved | Reference designs alone do not prove intermediate or zoom behavior | Automated tests include intermediate widths and 400% zoom equivalent |
|
||||
| D-080 | Collapse full navigation below 1120 px | Approved | French and Arabic header pressure makes 1024 too narrow for stable full navigation | The 1024 frame uses compact navigation and an inline-start drawer |
|
||||
| D-081 | Keep the hero stacked below 1120 px | Approved | A forced 1024 split makes either copy or product preview less informative | Tablet uses claim, CTAs, then a full-width readable preview |
|
||||
| D-082 | Keep the demo action reachable at every width | Approved | Primary conversion cannot disappear because the header becomes compact | Below 480 px the demo CTA is the first drawer action; above it may remain in the header when it fits |
|
||||
| D-083 | Use art-directed product previews instead of shrinking desktop screenshots below legibility | Approved | Tiny desktop UI ceases to provide product evidence | Mobile uses a focused crop, mobile capture, or coded responsive state |
|
||||
| D-084 | Prohibit swipe-only carousels for core modules, trust, testimonials, and case studies | Approved | Hidden slides reduce discoverability and create gesture/accessibility dependence | Core content uses grids or vertical stacks; optional carousels require a later explicit exception |
|
||||
| D-085 | Prohibit page-level horizontal scrolling | Approved | Horizontal page scroll breaks reflow, focus visibility, and mobile use | Tables and atomic technical values may own bounded, labelled overflow |
|
||||
| D-086 | Preserve semantic pricing tables at constrained widths | Approved | Plan comparison is genuinely tabular and should not become an image or inaccessible card duplicate | Use internal horizontal scroll and a sticky inline-start feature column |
|
||||
| D-087 | Use a 45rem container threshold for two-column demo-form fields | Approved | The form may sit in sections of different widths at the same viewport | Field layout responds to its own available space |
|
||||
| D-088 | Require at least 10rem per step for a horizontal workflow | Approved | Breakpoint width alone does not protect French or Arabic step labels | Workflow stays vertical whenever actual content pressure fails the minimum |
|
||||
| D-089 | Use 18rem module cards, 20rem pricing cards, and 11rem metric cards as minimum readable widths | Approved | Fixed column counts create unreadable intermediate states | Grids use auto-fit/minmax and reduce column count before compressing content |
|
||||
| D-090 | Never truncate critical headings, labels, buttons, errors, or evidence for responsive fit | Approved | Truncation hides meaning and disproportionately harms French and Arabic | Components wrap, stack, or change structure before reducing readability |
|
||||
| D-091 | Keep 44 × 44 px minimum targets across all responsive states | Approved | Compact layouts increase, rather than reduce, touch accuracy needs | Headers, drawers, accordions, pagination, and form controls preserve target size |
|
||||
| D-092 | Remove evidence sections entirely when approved content is absent | Approved | Empty responsive slots invite placeholder or fabricated evidence | No reserved logo rails, metrics, or testimonial gaps are rendered |
|
||||
| R-036 | Use one global breakpoint set as the only adaptation mechanism | Rejected | Components fail at different content widths | Use shared coordination ranges plus intrinsic and container rules |
|
||||
| R-037 | Keep desktop navigation at 1024 by shrinking gaps and labels | Rejected | Creates a fragile header that fails translation and zoom | Use compact navigation below 1120 |
|
||||
| R-038 | Hide secondary actions on mobile | Rejected | Removes valid user paths and can trap users in one conversion route | Stack or move actions without deleting them |
|
||||
| R-039 | Scale a full desktop screenshot to fit mobile | Rejected | Makes product evidence unreadable | Use art-directed captures or coded responsive previews |
|
||||
| R-040 | Convert core module sections into swipe-only carousels | Rejected | Reduces discoverability and accessibility | Use visible grids/stacks |
|
||||
| R-041 | Allow body horizontal scrolling for comparison tables | Rejected | Breaks page navigation and reflow | Contain overflow inside the table region |
|
||||
| R-042 | Ellipsize French or Arabic headings and button labels | Rejected | Hides meaning and creates unequal localization quality | Use content-driven size and structural change |
|
||||
| R-043 | Use CSS order or DOM duplication to rearrange responsive content | Rejected | Creates focus, reading-order, maintenance, and analytics drift | Keep one semantic source order |
|
||||
| R-044 | Use fixed heights to maintain card and section alignment | Rejected | Translation, zoom, validation, and dynamic data overflow | Use content-driven block sizing |
|
||||
| D-093 | Use a workflow-first homepage narrative rather than a generic feature dump | Approved | Buyers need to understand the operating model before comparing modules | Hero, problem, workflow, roles, then modules establish the product story |
|
||||
| D-094 | Use the reservation-to-return promise as the five-second hero message | Approved | It states category, scope, and operating value without unsupported superlatives | Hero copy stays concrete across en/fr/ar |
|
||||
| D-095 | Render operational-coverage proof instead of unsupported customer-logo proof | Approved | Product scope can be shown without fabricating external trust | Lifecycle cards follow the hero; logos remain blocked |
|
||||
| D-096 | Show KPI definitions and measurement methodology instead of invented outcome numbers | Approved | Evaluation rigor is more credible than fictional percentages | Results section contains no claimed improvement values |
|
||||
| D-097 | Omit the case-study section until an approved customer evidence package exists | Approved | Empty or anonymous proof violates the evidence policy | Conditional insertion point remains after Security and before Pricing |
|
||||
| D-098 | Present integration categories without naming partners until connector availability is verified | Approved | Named logos imply working production support | Discovery confirms market, connector, and data ownership |
|
||||
| D-099 | Present security as an evidence-request checklist until certifications and reliability claims are approved | Approved | Badges without scope are decoration, not assurance | No certification, uptime, RTO, or SLA claim renders |
|
||||
| D-100 | Use quote-oriented pricing preview until the commercial model is approved | Approved | Invented tiers or prices create false expectations | Page explains scope factors and routes to pricing request |
|
||||
| D-101 | Use a coded, localized, explicitly illustrative product preview | Approved | It proves layout, theme, and RTL behavior without pretending to be production evidence | Replace or approve before launch |
|
||||
| D-102 | Repeat the demo conversion in header, hero, pricing, and final CTA while reserving orange for conversion | Approved | Repetition improves reach without flattening hierarchy | Routine navigation and product emphasis remain blue |
|
||||
| D-103 | Use a native dialog for the demo form baseline | Approved | Provides a testable accessible interaction with visible labels and error state | Production integration must complete focus, submission, consent, and analytics testing |
|
||||
| D-104 | Validate six named production frames plus a 320 px reflow gate | Approved | These frames cover the highest-risk locale, direction, theme, and responsive combinations | Screenshots and automated checks are package deliverables |
|
||||
| R-045 | Fill the trust strip with fictional customer logos | Rejected | Placeholder logos quickly become accidental production claims | Omit logos until approved |
|
||||
| R-046 | Publish “up to” performance percentages without methodology | Rejected | The qualifier does not rescue unsupported evidence | Publish only after baseline and source approval |
|
||||
| R-047 | Add anonymous testimonial quotes | Rejected | Anonymous praise is not verifiable customer evidence | Use an attributable approved case study or omit |
|
||||
| R-048 | Display common integration logos as visual shorthand | Rejected | A familiar logo still implies a connector exists | Show neutral categories until verified |
|
||||
| R-049 | Add security badges with “pending” labels to the public page | Rejected | Public users should not see internal evidence placeholders | Keep status in the internal asset and copy registers |
|
||||
| R-050 | Invent three pricing tiers to make the page look complete | Rejected | Visual completeness is not worth commercial misinformation | Use a quote-oriented preview |
|
||||
| R-051 | Hide unresolved evidence behind vague superlatives | Rejected | “Trusted,” “leading,” and “proven” are still claims | Use concrete scope, workflow, and evaluation language |
|
||||
| R-052 | Make the Arabic frame by mirroring the English screenshot | Rejected | It violates true RTL and corrupts product evidence | Render localized coded UI in document-level RTL |
|
||||
|
||||
| D-105 | Treat Phase 8 as behavior validation, not aesthetic preference collection | Approved | Completion, comprehension, recovery, accessibility, and confidence are actionable; taste polling is not | Script uses task outcomes and neutral probes |
|
||||
| D-106 | Use a coded local prototype with deterministic query states | Approved | Reproducible states support moderation, accessibility checks, and automation | Demo, tour, locale, theme, navigation, failure, and research modes are addressable |
|
||||
| D-107 | Persist explicit locale and theme choices while preserving URL state and section hash | Approved | Context loss invalidates language and appearance tasks | Locale reload keeps hash; theme applies immediately and survives reload |
|
||||
| D-108 | Replace the Phase 7 product-tour anchor with a four-step guided tour | Approved | A control labeled “Watch product tour” must produce tour behavior rather than merely scroll | Final media may replace it after asset approval |
|
||||
| D-109 | Simulate demo success and service failure without sending participant data | Approved | The flow can be tested before CRM and consent integration without creating accidental leads | Prototype clearly states no request was sent |
|
||||
| D-110 | Keep prototype analytics session-local and exclude all entered values | Approved | Research needs interaction evidence without collecting names, emails, companies, or free text | Export contains event metadata only |
|
||||
| D-111 | Require 15 core participants across EN/FR/AR plus dedicated accessibility evidence | Approved | One-language five-user testing cannot establish multilingual or RTL behavior | Pilot and accessibility rounds remain separate evidence classes |
|
||||
| D-112 | Report locale cohorts separately before aggregating | Approved | An English majority can conceal Arabic or French failure | Acceptance includes per-locale floors |
|
||||
| D-113 | Treat multi-location support as a comprehension and evidence question until capability is approved | Approved | Existing copy implies location awareness but does not prove feature scope | Task measures over-inference and required clarification |
|
||||
| D-114 | Block release on unresolved Critical or High usability and accessibility issues | Approved | Conversion averages cannot excuse exclusion or a broken primary path | Fix and retest affected cohorts |
|
||||
| R-053 | Ask participants whether they like the design | Rejected | Preference is weak evidence and invites politeness bias | Ask users to perform real tasks and explain expectations |
|
||||
| R-054 | Use five English desktop participants as proof for all locales and devices | Rejected | It ignores translation expansion, RTL, mobile behavior, and cohort differences | Balance language, role, device, and accessibility coverage |
|
||||
| R-055 | Send prototype form data to a real CRM | Rejected | Creates privacy, consent, routing, and accidental-sales risk | Simulate success and failure locally |
|
||||
| R-056 | Record participant-entered form values in analytics | Rejected | Names, emails, companies, and free text are unnecessary for interaction analysis | Capture event names and non-PII context only |
|
||||
| R-057 | Aggregate results before inspecting locale cohorts | Rejected | Strong English results can hide Arabic failure | Apply cohort floors and report separately |
|
||||
| R-058 | Close a severe issue after designer inspection alone | Rejected | The affected users, device, locale, or access method must prove the repair | Retest with the cohort that exposed it |
|
||||
|
||||
| D-115 | Treat the Phase 8 prototype as behavioral reference, not production source code | Approved | Prototype shortcuts and simulations are useful for testing but unsafe to ship | Production rebuild follows typed contracts, real integrations, and release gates |
|
||||
| D-116 | Use framework-agnostic contracts with a documented default capability profile | Approved | The architecture choice is unresolved, but UI behavior cannot remain ambiguous | Any selected stack must satisfy the same SSR, localization, theme, accessibility, and test contracts |
|
||||
| D-117 | Separate theme preference from resolved theme in production | Approved | System must remain an explicit persisted choice | Root exposes both preference and resolved theme before paint |
|
||||
| D-118 | Use `hpc-theme` cookie as canonical and `hpc.theme.preference` as local mirror | Approved | SSR and cross-tab behavior require two coordinated stores | Cookie wins disagreement; values are restricted to light/dark/system |
|
||||
| D-119 | Use a 768 px medium and 1120 px wide layout boundary | Approved | Matches distinct compact, medium, and wide composition decisions from prior phases | Reference regression frames include 320, 390, 768, 1024, 1280, and 1440 px |
|
||||
| D-120 | Use typed evidence status on public claim-bearing content | Approved | Rendering copy alone must not imply approval | Pending, expired, or rejected claims are suppressed or use an approved neutral variant |
|
||||
| D-121 | Keep analytics vendor-neutral and prohibit form values or free text | Approved | Vendor selection is open and PII is unnecessary for conversion analysis | Adapter gates events behind approved consent and schema validation |
|
||||
| D-122 | Require idempotent demo submission and preserve values on recoverable failure | Approved | Double leads and lost form data damage trust and sales operations | Submit is disabled in flight; backend accepts an idempotency key |
|
||||
| D-123 | Use relative evergreen browser coverage plus named assistive-technology combinations | Approved provisional baseline | Exact versions decay immediately while coverage obligations remain testable | Product and Engineering must approve an exception/retirement owner before beta |
|
||||
| D-124 | Adopt explicit project performance budgets for mobile conversion paths | Approved provisional baseline | “Fast” is not a test criterion | Release reports against LCP, INP, CLS, TTFB, transfer, request, and font budgets |
|
||||
| D-125 | Block release until participant acceptance and native French/Arabic review pass | Approved | Automated behavior checks cannot establish comprehension or linguistic quality | Phase 8 research and locale review remain High/Critical gates |
|
||||
| D-126 | Suppress unresolved login, sales-contact, pricing, evidence, and legal destinations rather than ship placeholders | Approved | Dead or fictional destinations are worse than omission | Components render only approved links and claims |
|
||||
| R-059 | Copy the Phase 8 prototype directly into production | Rejected | It contains simulation, placeholder destinations, and research-only instrumentation | Rebuild from contracts |
|
||||
| R-060 | Let each component choose raw colors or breakpoint values | Rejected | Creates drift across themes and responsive modes | Consume centralized tokens and matrices |
|
||||
| R-061 | Put locale or direction correction in a client hydration effect | Rejected | Causes incorrect first paint, SEO ambiguity, and accessibility instability | Render document state on the server |
|
||||
| R-062 | Send form values to analytics for “better funnel insight” | Rejected | PII and free text are unnecessary and risky | Track only non-PII state and source metadata |
|
||||
| R-063 | Treat a successful HTTP response as permission to publish success copy | Rejected | Backend semantics and operational routing must match the promise | Contract defines accepted state and next-step code |
|
||||
@@ -0,0 +1,54 @@
|
||||
# Definition of Done
|
||||
|
||||
A release candidate is done only when every statement below is true.
|
||||
|
||||
## Build and architecture
|
||||
|
||||
- The selected framework, exact dependency versions, repository conventions, owners, and deployment path are recorded.
|
||||
- Strict TypeScript, linting, tests, production build, and package audit pass.
|
||||
- Public routes render correct locale, direction, theme attributes, metadata, canonical, and `hreflang` before hydration.
|
||||
- No research-only code, deterministic query backdoors, placeholder domains, or simulated submission remains.
|
||||
|
||||
## Design fidelity
|
||||
|
||||
- Components consume the token package without undeclared raw brand values.
|
||||
- Compact, medium, and wide behavior matches the responsive matrix at 320, 390, 768, 1024, 1280, and 1440 px.
|
||||
- English, French, and Arabic pass light and dark visual regression; System is behavior-tested.
|
||||
- No clipped translated text, fixed text height, unintended overflow, or theme flash exists.
|
||||
|
||||
## Localization and RTL
|
||||
|
||||
- Locale key parity, route parity, metadata, and visible-copy inventory pass CI.
|
||||
- Native French and Arabic reviewers approve all visible copy, errors, metadata, and terminology.
|
||||
- Arabic uses document-level RTL, logical CSS, selective icon mirroring, and isolation for atomic LTR values.
|
||||
- Locale switching preserves only approved query state and valid hashes.
|
||||
|
||||
## Accessibility
|
||||
|
||||
- WCAG 2.2 AA checklist is complete with evidence.
|
||||
- Keyboard-only use, focus visibility/order, skip link, drawer, dialogs, form errors, status messages, 200% zoom, 400% reflow, forced colors, text spacing, reduced motion, and target size pass.
|
||||
- NVDA, VoiceOver, and TalkBack critical-path checks pass in the supported combinations.
|
||||
- No Critical or High accessibility defect remains open.
|
||||
|
||||
## Forms, privacy, and integrations
|
||||
|
||||
- Legal approves localized consent and privacy behavior.
|
||||
- Real CRM routing, duplicate handling, idempotency, retry, spam protection, monitoring, and operational ownership pass integration tests.
|
||||
- Recoverable failures preserve entered values and provide a retry path.
|
||||
- Analytics is consent-gated, schema-validated, vendor-approved, and contains no entered form values or free text.
|
||||
- Success copy truthfully matches backend acceptance and next-step behavior.
|
||||
|
||||
## Evidence and content
|
||||
|
||||
- Every public capability, metric, logo, testimonial, partner, security statement, price, and legal destination has an approval record or is suppressed.
|
||||
- The illustrative product preview is approved as such or replaced by a governed product capture.
|
||||
- Placeholder login and sales-contact destinations are removed or replaced.
|
||||
- Multi-location wording and product-tour medium are explicitly approved.
|
||||
|
||||
## Quality and release
|
||||
|
||||
- All QA matrix release gates pass in the supported browser/AT matrix.
|
||||
- Performance budgets pass for EN, FR, and AR on the defined mobile profile.
|
||||
- Participant testing reaches the Phase 8 cohort and success thresholds; every S0/S1 finding is fixed and retested with the affected cohort.
|
||||
- Open issue register contains no Critical or High issue and no overdue unowned item.
|
||||
- Product, Design, Engineering, Content/Localization, Accessibility, Legal, Security, Analytics, and Sales Operations record release approval for their owned gates.
|
||||
@@ -0,0 +1,18 @@
|
||||
Issue_ID,Severity,Area,Problem,Owner,Due_gate,Status,Exit_criteria
|
||||
P9-001,Critical,Participant acceptance,Phase 8 usability acceptance has not been run with required cohorts.,Research,Before release,Open,"Run pilots, 15-core cohort, accessibility cohort; close/retest S0/S1 issues."
|
||||
P9-002,High,CRM integration,"Endpoint, routing, duplicate handling, retry, spam controls, and operational ownership are unapproved.",Sales Ops + Engineering,Before production integration,Open,Approve and integration-test complete request lifecycle.
|
||||
P9-003,High,Legal consent,"Consent text, privacy linkage, retention, and market-specific requirements are unresolved.",Legal,Before production form,Open,Approve localized legal content and consent model.
|
||||
P9-004,High,Analytics and consent,"Vendor, event authority, consent policy, retention, and session replay are unresolved.",Analytics + Legal,Before beta,Open,Select adapter and validate non-PII payloads and gating.
|
||||
P9-005,High,Native linguistic review,French and Arabic require native product/marketing review.,Content + Localization,Before release,Open,"Review all visible copy, metadata, errors, and mixed-direction samples."
|
||||
P9-006,High,Illustrative product preview,Current coded preview is not approved product evidence.,Product + Design,Before release,Open,Approve as illustration or replace with governed capture.
|
||||
P9-007,High,Multi-location claim,Copy can imply branch/multi-location capability without approval.,Product,Before beta,Open,Approve capability or revise/suppress affected copy.
|
||||
P9-008,High,Pricing model,Public pricing and included limits are not approved.,Commercial,Before pricing publication,Open,Keep quote-only variant until written approval.
|
||||
P9-009,High,Security evidence,"Certifications, SLA, backup/recovery, and subprocessors are not approved for public claims.",Security + Legal,Before claims publish,Open,Supply scoped evidence and expiry dates.
|
||||
P9-010,Medium,Framework selection,Final framework and repository conventions are not approved.,Architecture,Before scaffold merge,Open,Approve stack or adopt default capability profile.
|
||||
P9-011,Medium,Browser policy owner,Relative browser matrix is specified; owner and exception process need approval.,Product + Engineering,Before beta,Open,Approve matrix and telemetry-based retirement policy.
|
||||
P9-012,Medium,Product tour medium,Four-step dialog may be replaced by approved media.,Product + Marketing,Before release,Open,Approve fallback or supply accessible localized media/transcript.
|
||||
P9-013,Medium,Markets and formatting,"French/Arabic commercial markets, currency, timezone, phone, and legal jurisdiction are undefined.",Product + Legal,Before regional campaign,Open,Supply explicit market context independent of locale.
|
||||
P9-014,Medium,Login destination,Authentication URL and cross-domain behavior are unresolved.,Product + Engineering,Before release,Open,"Approve destination, security, locale return path, and analytics."
|
||||
P9-015,Medium,Alternate sales contact,Prototype uses a non-routable placeholder address.,Sales Ops,Before release,Open,Provide approved contact route or suppress secondary contact.
|
||||
P9-016,Medium,Customer evidence,"Logos, metrics, testimonials, and case studies are absent by policy.",Marketing + Legal,Optional post-launch,Open,Publish only with attributable evidence records.
|
||||
P9-017,Low,Exact dependency versions,Package intentionally avoids volatile version pins.,Engineering,At scaffold,Open,Pin and record versions; enable automated updates with review.
|
||||
|
@@ -0,0 +1,26 @@
|
||||
# Open Questions
|
||||
|
||||
The authoritative status is in `OPEN_ISSUE_REGISTER_v1.0.csv`.
|
||||
|
||||
## Architecture
|
||||
|
||||
- Which framework and repository conventions are approved?
|
||||
- Who owns browser support and dependency retirement?
|
||||
- Where will the server-readable theme and locale cookies be set?
|
||||
|
||||
## Product and commercial
|
||||
|
||||
- Is multi-location operation an approved public capability?
|
||||
- Is the guided four-step tour final, or will approved media replace it?
|
||||
- What pricing model, included limits, markets, currencies, and tax assumptions are approved?
|
||||
- What login destination and return-path behavior are required?
|
||||
|
||||
## Integration, privacy, and evidence
|
||||
|
||||
- Which CRM, routing rules, duplicate policy, retry policy, and spam control are approved?
|
||||
- Which consent model, analytics vendor, retention policy, and session replay policy are approved by market?
|
||||
- Which product captures, customer evidence, integrations, security claims, and legal documents are approved?
|
||||
|
||||
## Research
|
||||
|
||||
- When will the required participant and assistive-technology rounds run, and who owns severity arbitration and retesting?
|
||||
@@ -0,0 +1,315 @@
|
||||
{
|
||||
"package": "homePageCar_Phase9_Developer_Handoff",
|
||||
"version": "1.0",
|
||||
"created": "2026-06-25",
|
||||
"source_dependency": "homePageCar_Phase8_Interactive_Prototype_Usability_Testing_v1.0.zip",
|
||||
"status": "handoff-complete; production release blocked by open issues",
|
||||
"file_count": 61,
|
||||
"files": [
|
||||
{
|
||||
"path": "09_DEVELOPER_HANDOFF_v1.0.md",
|
||||
"bytes": 8091,
|
||||
"sha256": "e82d486f1e566d1bf0263f1baa7dd8035ae62da5c36bb6bfa417e61331ec8d51"
|
||||
},
|
||||
{
|
||||
"path": "DECISION_LOG_v9.0.md",
|
||||
"bytes": 38775,
|
||||
"sha256": "85569a7418f8cad57d094ee9ec1d83b7727b5ab91a405cbda26de0271a8d76a1"
|
||||
},
|
||||
{
|
||||
"path": "DEFINITION_OF_DONE_v1.0.md",
|
||||
"bytes": 3234,
|
||||
"sha256": "dfe53a550b7853f015901b83adb960ffb26ab08fa6d7f9f8f8a3386adc705179"
|
||||
},
|
||||
{
|
||||
"path": "OPEN_ISSUE_REGISTER_v1.0.csv",
|
||||
"bytes": 3519,
|
||||
"sha256": "b8778b3dc7d1e47446584cac046d490a9932c3dfdfa03750716f29852694a214"
|
||||
},
|
||||
{
|
||||
"path": "OPEN_QUESTIONS_v1.0.md",
|
||||
"bytes": 1085,
|
||||
"sha256": "82a2abd71830fa4023d346f3b42b138de9e1bbdff74a827d770e6b660d89bd0e"
|
||||
},
|
||||
{
|
||||
"path": "PHASE_9_HANDOFF_v1.0.md",
|
||||
"bytes": 939,
|
||||
"sha256": "90530b4e70d1fd64d5d934429c009431902639c0570e7944cf050e6d67eb73a3"
|
||||
},
|
||||
{
|
||||
"path": "README_v1.0.md",
|
||||
"bytes": 1258,
|
||||
"sha256": "ef0010b98ba641c4db453d875171a0d1dad4cb17e991ad23698acde8ac4783ae"
|
||||
},
|
||||
{
|
||||
"path": "SOURCE_TRACEABILITY_v1.0.csv",
|
||||
"bytes": 765,
|
||||
"sha256": "76dc8677ad0d50263301fd5242bc0649c23bb01d3bbd099bdc8a7e2c04fc2d46"
|
||||
},
|
||||
{
|
||||
"path": "annotated/ANNOTATION_INDEX_v1.0.md",
|
||||
"bytes": 685,
|
||||
"sha256": "a2e87dfdb138409604cac4cc5f52375cce97940da7363f7778af30490699decd"
|
||||
},
|
||||
{
|
||||
"path": "annotated/SCREEN_ANNOTATIONS_v1.0.csv",
|
||||
"bytes": 1457,
|
||||
"sha256": "d7b8120926a545f472b62a436b87d2a9d20320a4d95fcf90aa96162c50e8a6da"
|
||||
},
|
||||
{
|
||||
"path": "annotated/demo-dialog-en-light_v1.0.png",
|
||||
"bytes": 51457,
|
||||
"sha256": "d91bf102100af48feac31478770f8bfdded994ac8b47f60845e4465c50462394"
|
||||
},
|
||||
{
|
||||
"path": "annotated/desktop-en-light_v1.0.png",
|
||||
"bytes": 144908,
|
||||
"sha256": "a4151a788317aa9bf8f7262f09f645ebdb54d4a3e1254ab5703ae37e8d3cec16"
|
||||
},
|
||||
{
|
||||
"path": "annotated/mobile-ar-dark_v1.0.png",
|
||||
"bytes": 75193,
|
||||
"sha256": "6adcaf68b48bacbf105b670e71edda078a60aa26b732831bd194e1cb9da11556"
|
||||
},
|
||||
{
|
||||
"path": "annotated/mobile-drawer-ar-dark_v1.0.png",
|
||||
"bytes": 28321,
|
||||
"sha256": "bc0c14447fb6e80ce904ffcb13c237b51eaa92723702191139bee59b0f7ebdeb"
|
||||
},
|
||||
{
|
||||
"path": "annotated/tablet-fr-light_v1.0.png",
|
||||
"bytes": 102305,
|
||||
"sha256": "dd526fe6859e470ea4c67b4c1ef511cfe0e11126561f86bcff07e57378084347"
|
||||
},
|
||||
{
|
||||
"path": "annotated/tour-dialog-fr-dark_v1.0.png",
|
||||
"bytes": 94445,
|
||||
"sha256": "2dd7b24f6505f16a565ac1b5490499ccdae91d0257de608c97c54b7d5b6c2c78"
|
||||
},
|
||||
{
|
||||
"path": "assets/ASSET_MANIFEST_v1.0.csv",
|
||||
"bytes": 1049,
|
||||
"sha256": "dd77547327096b4c4084ec8b9311aaff719e378a91f16c2b3ea39832d1bc7b3a"
|
||||
},
|
||||
{
|
||||
"path": "assets/ASSET_USAGE_RULES_v1.0.md",
|
||||
"bytes": 747,
|
||||
"sha256": "46821e8e6588a62eba860e4d228b2910a05aa60124610966bdc524a86921f658"
|
||||
},
|
||||
{
|
||||
"path": "assets/brand-mark_v1.0.svg",
|
||||
"bytes": 443,
|
||||
"sha256": "bcb3a3fb8037aec69d92da06f0d60fab969547b979a0112f12e6a5c2ab8efdaa"
|
||||
},
|
||||
{
|
||||
"path": "assets/logo-horizontal_v1.0.svg",
|
||||
"bytes": 576,
|
||||
"sha256": "04be1c45e1b6e85586efc6dbd36bf3e1e9275fa138a36b93cf6532bbd7409b02"
|
||||
},
|
||||
{
|
||||
"path": "components/COMPONENT_CONTRACTS_v1.0.md",
|
||||
"bytes": 9800,
|
||||
"sha256": "84b455fe725bff11b6ab54bb13373b1aa52991b062a36fad07db47a940187a53"
|
||||
},
|
||||
{
|
||||
"path": "components/COMPONENT_STATE_MATRIX_v1.0.csv",
|
||||
"bytes": 4283,
|
||||
"sha256": "c85f96f6d5e020a27c2bd44427a2c3aed3f3cad8657d88a22fc2de9ecd3f6cda"
|
||||
},
|
||||
{
|
||||
"path": "components/CONTENT_CONSTRAINTS_v1.0.csv",
|
||||
"bytes": 1147,
|
||||
"sha256": "f4d32b7775f856ff4aac775791566427e3cc340f39cd3f9845d8a3271167228b"
|
||||
},
|
||||
{
|
||||
"path": "components/RESPONSIVE_BEHAVIOR_MATRIX_v1.0.csv",
|
||||
"bytes": 1416,
|
||||
"sha256": "0e0e262c0388c37e41f5ab7f3e80835b8edb09e00a9264e81d92953743893353"
|
||||
},
|
||||
{
|
||||
"path": "components/RTL_THEME_MATRIX_v1.0.csv",
|
||||
"bytes": 4048,
|
||||
"sha256": "b47f4b3b4e50f1fed6b1b69523a05d61952773e95a966288bfba85dd414edb15"
|
||||
},
|
||||
{
|
||||
"path": "implementation/TECHNOLOGY_PROFILE_v1.0.md",
|
||||
"bytes": 1953,
|
||||
"sha256": "a59504c81bdbb6396eb21e68518ca84862ac89c6c65744de710e9ae273e47c7b"
|
||||
},
|
||||
{
|
||||
"path": "implementation/component-contracts_v1.0.ts",
|
||||
"bytes": 2844,
|
||||
"sha256": "177dd2420b804290cf1296e43f41a7e759c8859b3253073fbdc523a81f6f94c0"
|
||||
},
|
||||
{
|
||||
"path": "implementation/hreflang-generator_v1.0.ts",
|
||||
"bytes": 751,
|
||||
"sha256": "ab919a36a5d08a28c38ae51b4ddd0d84cef5d3ec3bed13649ebd26c3fb80ac8a"
|
||||
},
|
||||
{
|
||||
"path": "implementation/localization-config_v1.0.ts",
|
||||
"bytes": 772,
|
||||
"sha256": "bd8ca09f121bfe516ece817948a81d58136e9205fbd2c05dad2ce87f2d7a1782"
|
||||
},
|
||||
{
|
||||
"path": "implementation/theme-config_v1.0.ts",
|
||||
"bytes": 725,
|
||||
"sha256": "f56d37da4129d5830ba9ebd77b18cd6084a144e8514bfd8a8152387ecf76607c"
|
||||
},
|
||||
{
|
||||
"path": "interaction/ANALYTICS_EVENT_SPEC_v1.0.csv",
|
||||
"bytes": 1713,
|
||||
"sha256": "1282ebca5b031f6267f8139033db437e30b62ac391d25823c8a4783b64151008"
|
||||
},
|
||||
{
|
||||
"path": "interaction/INTERACTION_NOTES_v1.0.md",
|
||||
"bytes": 2332,
|
||||
"sha256": "0456815622cbb072f1a7594e6b47f52e572e2570280c3a618876246e1b43d2a7"
|
||||
},
|
||||
{
|
||||
"path": "interaction/analytics-contract_v1.0.ts",
|
||||
"bytes": 832,
|
||||
"sha256": "2716eb69cc98032005e068ab7bdc265a4c896a8e1a1bed682c7fdd4f45368123"
|
||||
},
|
||||
{
|
||||
"path": "interaction/demo-form-contract_v1.0.ts",
|
||||
"bytes": 632,
|
||||
"sha256": "194db77f7cfca417dbe35e6f2c2ea94cdd02806b83b1d0f1993fe509d8c10154"
|
||||
},
|
||||
{
|
||||
"path": "interaction/theme-bootstrap_v1.0.js",
|
||||
"bytes": 753,
|
||||
"sha256": "7b89a849bdcd72e1049714ebf76f0c0decb39e44261480f0cb08bb7dfe734e4a"
|
||||
},
|
||||
{
|
||||
"path": "localization/LOCALIZATION_IMPLEMENTATION_v1.0.md",
|
||||
"bytes": 2062,
|
||||
"sha256": "87a494d7ef7ed9f5012ed1699edf90e38995aa89a0efc3800db854e1d57e1024"
|
||||
},
|
||||
{
|
||||
"path": "localization/ROUTE_MANIFEST_v1.0.json",
|
||||
"bytes": 1573,
|
||||
"sha256": "fa29b8d31da1f36f87d216a1228fd1bbe1cde337636950b40b0024a10efaf49a"
|
||||
},
|
||||
{
|
||||
"path": "localization/TRANSLATION_KEY_INVENTORY_v1.0.csv",
|
||||
"bytes": 10599,
|
||||
"sha256": "01289dc9eb94d546ae717b881b2aed4dfc63b38df38e7767054800122bbb46c2"
|
||||
},
|
||||
{
|
||||
"path": "localization/locales/ar/homepage.json",
|
||||
"bytes": 18615,
|
||||
"sha256": "fe08aabd60203dbdebc718117f5e497b52a453a8a6fb671fe0bca28651bf0d47"
|
||||
},
|
||||
{
|
||||
"path": "localization/locales/en/homepage.json",
|
||||
"bytes": 13869,
|
||||
"sha256": "a5ed956c7f07fad016ca39b40b770c25e8beeae2799ff0fece82dbf087f18e51"
|
||||
},
|
||||
{
|
||||
"path": "localization/locales/fr/homepage.json",
|
||||
"bytes": 15512,
|
||||
"sha256": "24079356bd47431ffeb66b7eb2981e108c03080205861b1bb42514b03b945a0a"
|
||||
},
|
||||
{
|
||||
"path": "qa/ACCESSIBILITY_CHECKLIST_v1.0.csv",
|
||||
"bytes": 1498,
|
||||
"sha256": "0d9c108e0c02b78aaf11badf6b5f5125cac2b03876cfddf82bd2e97230fdd28b"
|
||||
},
|
||||
{
|
||||
"path": "qa/BROWSER_SUPPORT_MATRIX_v1.0.csv",
|
||||
"bytes": 986,
|
||||
"sha256": "5ffb43732fea90530b1b088fb68172b9fc7b2c2683198448734a21cf39c234d1"
|
||||
},
|
||||
{
|
||||
"path": "qa/PERFORMANCE_BUDGETS_v1.0.json",
|
||||
"bytes": 815,
|
||||
"sha256": "e1679ce45d8a1225c46c085c7533d3230a41279c32d0812de5c5f05cb55eefa8"
|
||||
},
|
||||
{
|
||||
"path": "qa/PLAYWRIGHT_ACCEPTANCE_SPEC_v1.0.md",
|
||||
"bytes": 800,
|
||||
"sha256": "b16384a861d06eb76db5a836868d9a6e03cf72a6a896209279330e19a8d1a785"
|
||||
},
|
||||
{
|
||||
"path": "qa/QA_MATRIX_v1.0.csv",
|
||||
"bytes": 3557,
|
||||
"sha256": "6b14b92ce20a9d706de7d6d4cf9f0bb450ecceed27673ed62ae01e145d2143f8"
|
||||
},
|
||||
{
|
||||
"path": "qa/test-ids_v1.0.csv",
|
||||
"bytes": 598,
|
||||
"sha256": "6201007ae98632654a2684a0b09ce95d85d9870e0f29774687df0a9876048202"
|
||||
},
|
||||
{
|
||||
"path": "qa/validate-phase9-package_v1.0.mjs",
|
||||
"bytes": 2534,
|
||||
"sha256": "631892318cf95c0530a605e5bf08def9b06c93af79b555205f3aeb8a2bcd87ed"
|
||||
},
|
||||
{
|
||||
"path": "qa/visual-regression-scenarios_v1.0.json",
|
||||
"bytes": 1401,
|
||||
"sha256": "08a04f676cbb93e73b4c6bc112a55ebf287cb97be3dd3176ab80161e6de743c2"
|
||||
},
|
||||
{
|
||||
"path": "reference/FINDINGS_REPORT_v1.0.md",
|
||||
"bytes": 3062,
|
||||
"sha256": "ba34afd535856d0eaa8ed7e174c23a7b5f0eae87344c8fcee5daafe00c068ce4"
|
||||
},
|
||||
{
|
||||
"path": "reference/PHASE_8_HANDOFF_v1.0.md",
|
||||
"bytes": 1117,
|
||||
"sha256": "2e51ed6645fcc99f30cd4aa9da11ac59e5c2e331c384bfbd758739ad6f42c788"
|
||||
},
|
||||
{
|
||||
"path": "reference/PRIORITIZED_REVISIONS_v1.0.csv",
|
||||
"bytes": 1071,
|
||||
"sha256": "65b17813756a2d01c8a9df9faa049b170dca197f243b62a44e070d69f8959df5"
|
||||
},
|
||||
{
|
||||
"path": "reference/SUCCESS_METRICS_v1.0.csv",
|
||||
"bytes": 1552,
|
||||
"sha256": "e7b734564735ab65dcaf84ab8374ba163472cca48db1257c4c626415a779ecbe"
|
||||
},
|
||||
{
|
||||
"path": "reference/VALIDATION_RESULTS_v1.0.md",
|
||||
"bytes": 2068,
|
||||
"sha256": "3cb17f099569e5bdf4bcd731fe7f687d1636f0e82623c205e07df2cdc2b7d2f2"
|
||||
},
|
||||
{
|
||||
"path": "tokens/TOKEN_USAGE_RULES_v1.0.md",
|
||||
"bytes": 1222,
|
||||
"sha256": "b9f7d9b0a9c0595e6f6df2a53e0bcf4acfb47a56abfc6c590a6281c15b04a7b2"
|
||||
},
|
||||
{
|
||||
"path": "tokens/design-tokens_v1.0.json",
|
||||
"bytes": 3771,
|
||||
"sha256": "470d7bc9d4a466cce4e51f0fdc21fe199ec5b0d4007f5063704c523ce1b9ef0c"
|
||||
},
|
||||
{
|
||||
"path": "tokens/semantic-tokens_v1.0.css",
|
||||
"bytes": 3553,
|
||||
"sha256": "99912762e078bfc78b4878fc46b8c7d03d90c073e9c236942a58d83f6585a1b9"
|
||||
},
|
||||
{
|
||||
"path": "tokens/tokens_v1.0.ts",
|
||||
"bytes": 442,
|
||||
"sha256": "ec265270251f8dd01d9166aeca3fcec9be2b5e534d825c9058fb6ed3f51e3224"
|
||||
},
|
||||
{
|
||||
"path": "validation/CONTENT_AND_STRUCTURE_VALIDATION_v1.0.json",
|
||||
"bytes": 189,
|
||||
"sha256": "e055ef15c2de2191a3465d85ed54f4cf6bd9e1cde4d5d2bba787e14873027b73"
|
||||
},
|
||||
{
|
||||
"path": "validation/STATIC_VALIDATION_RESULTS_v1.0.json",
|
||||
"bytes": 56,
|
||||
"sha256": "b60367adf55cf4c61b705d11131b7adebc0aae6ff53732c8272ec9cf2bc95dd3"
|
||||
},
|
||||
{
|
||||
"path": "validation/VALIDATION_RESULTS_v1.0.md",
|
||||
"bytes": 1179,
|
||||
"sha256": "6f9df81e75d7149d3826ce215143c21784f39b154660fcefc5325ac114ac70b2"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# Phase 9 Handoff
|
||||
|
||||
Phase 9 is implementation-ready at the specification level.
|
||||
|
||||
Use `09_DEVELOPER_HANDOFF_v1.0.md` as the authoritative build specification and `DECISION_LOG_v9.0.md` as the cumulative decision record. The token package, component contracts, locale resources, interaction contracts, assets, QA matrix, issue register, and definition of done are all versioned and machine-readable where practical.
|
||||
|
||||
Production implementation may begin against the vendor-neutral contracts. Release may not proceed until all Critical and High issues are closed, participant acceptance is completed, native French and Arabic review passes, real submission/consent/analytics behavior is approved, and every public claim has evidence.
|
||||
|
||||
The Phase 8 prototype remains a behavioral reference. It is not a source-code base and its simulated backend, illustrative preview, research instrumentation, and placeholder contact destination must not ship.
|
||||
@@ -0,0 +1,30 @@
|
||||
# homePageCar Phase 9 — Developer Handoff
|
||||
|
||||
**Package version:** 1.0
|
||||
**Created:** 2026-06-25
|
||||
**Source:** `homePageCar_Phase8_Interactive_Prototype_Usability_Testing_v1.0.zip`
|
||||
**Status:** Build-ready specification with explicit pre-production blockers
|
||||
|
||||
## Start here
|
||||
|
||||
1. `09_DEVELOPER_HANDOFF_v1.0.md`
|
||||
2. `implementation/TECHNOLOGY_PROFILE_v1.0.md`
|
||||
3. `tokens/TOKEN_USAGE_RULES_v1.0.md`
|
||||
4. `components/COMPONENT_CONTRACTS_v1.0.md`
|
||||
5. `localization/LOCALIZATION_IMPLEMENTATION_v1.0.md`
|
||||
6. `interaction/INTERACTION_NOTES_v1.0.md`
|
||||
7. `qa/QA_MATRIX_v1.0.csv`
|
||||
8. `OPEN_ISSUE_REGISTER_v1.0.csv`
|
||||
9. `DEFINITION_OF_DONE_v1.0.md`
|
||||
|
||||
## Non-negotiable interpretation
|
||||
|
||||
Phase 8 automated checks proved prototype behavior, not production readiness or human comprehension. Participant testing, native linguistic review, CRM integration, consent, analytics approval, evidence approval, and several commercial decisions remain gates. A developer must not convert provisional copy into a public claim merely because it exists in a JSON file.
|
||||
|
||||
## Validate this package
|
||||
|
||||
```bash
|
||||
node qa/validate-phase9-package_v1.0.mjs
|
||||
```
|
||||
|
||||
The validator checks required artifacts, JSON syntax, locale key parity, route coverage, token references, issue ownership, and manifest integrity.
|
||||
@@ -0,0 +1,8 @@
|
||||
Source,Destination,Transformation
|
||||
Phase8 prototype,Component contracts,Behavior and states converted to typed production rules
|
||||
Phase8 copy JSON,Locale resources + key inventory,EN/FR/AR content preserved with parity checks
|
||||
Phase8 interaction spec,Interaction notes + QA matrix,"Drawer, dialogs, tour, form, selectors made testable"
|
||||
Phase8 analytics spec,Vendor-neutral analytics contract,Research-only logging replaced by consent-gated interface
|
||||
Phase8 findings/revisions,Issue register,"Open CRM, evidence, research, and content risks preserved"
|
||||
Phase8 decision log,Decision log v9,All prior decisions carried forward; Phase 9 decisions appended
|
||||
Phase8 prototype CSS,Token package + matrices,Visual values normalized into semantic implementation tokens
|
||||
|
@@ -0,0 +1,12 @@
|
||||
# Annotated Screen Index
|
||||
|
||||
The annotated captures are generated from the Phase 8 behavioral prototype and are references for structure and state, not launch evidence.
|
||||
|
||||
- `desktop-en-light_v1.0.png`: wide homepage top and primary hierarchy.
|
||||
- `tablet-fr-light_v1.0.png`: medium French layout and navigation mode.
|
||||
- `mobile-ar-dark_v1.0.png`: compact Arabic RTL layout and dark theme.
|
||||
- `mobile-drawer-ar-dark_v1.0.png`: inline-start drawer, focus, and control order.
|
||||
- `demo-dialog-en-light_v1.0.png`: visible labels, form grid, and modal anatomy.
|
||||
- `tour-dialog-fr-dark_v1.0.png`: guided tour progress and action anatomy.
|
||||
|
||||
Numbered callouts correspond to `SCREEN_ANNOTATIONS_v1.0.csv`.
|
||||
@@ -0,0 +1,16 @@
|
||||
Screen,Callout,Region,Rule
|
||||
desktop-en-light,1,Sticky header,Desktop nav appears only at >=1120px; orange reserved for demo.
|
||||
desktop-en-light,2,Hero copy,Single h1; primary demo before tour in reading order.
|
||||
desktop-en-light,3,Product preview,Illustrative status must remain visible internally and approved before launch.
|
||||
tablet-fr-light,1,Medium navigation,Drawer mode remains below 1120px; avoid squeezed desktop controls.
|
||||
tablet-fr-light,2,French expansion,Text blocks grow vertically; no fixed card heights or truncation.
|
||||
mobile-ar-dark,1,Document RTL,Root dir=rtl; content aligns start and order follows Arabic reading.
|
||||
mobile-ar-dark,2,Compact CTAs,Buttons remain 44px minimum and may stack/content-wrap.
|
||||
mobile-drawer-ar-dark,1,Inline-start drawer,Drawer opens from right in RTL.
|
||||
mobile-drawer-ar-dark,2,Focus boundary,Background inert; focus starts at close and loops inside.
|
||||
demo-dialog-en-light,1,Dialog heading,Programmatic name comes from visible heading.
|
||||
demo-dialog-en-light,2,Form labels,"Visible labels stay present; required state is announced, not only asterisk."
|
||||
demo-dialog-en-light,3,Submission area,Persistent errors and submit remain reachable with virtual keyboard.
|
||||
tour-dialog-fr-dark,1,Progress,Localized step count announced politely.
|
||||
tour-dialog-fr-dark,2,Step focus,Step heading/article receives focus after navigation.
|
||||
tour-dialog-fr-dark,3,Actions,Back/Next meaning stays explicit; layout follows direction.
|
||||
|
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 142 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 92 KiB |
@@ -0,0 +1,8 @@
|
||||
Asset_ID,Path,Type,Status,Usage,Constraint,Owner
|
||||
brand-mark,assets/brand-mark_v1.0.svg,svg,approved,"Header, favicon source, compact brand",Do not stretch; preserve 1:1 ratio,Design
|
||||
logo-horizontal,assets/logo-horizontal_v1.0.svg,svg,provisional,Footer or wide co-brand-safe placement,Text color must be tokenized in production rather than edited per theme,Design
|
||||
lucide-icons,external dependency,svg icon set,approved-family,Interface icons,Pin package version; 24px grid; 2px stroke; selective RTL mirroring,Engineering
|
||||
product-preview,not included as launch evidence,image or coded UI,illustrative,Hero visual,Must be approved or replaced; never mirror/recolor captures,Product + Design
|
||||
product-tour-media,not supplied,video/capture,blocked,Secondary CTA,Guided four-step dialog remains fallback until media approval,Product
|
||||
customer-logos,not supplied,svg/png,blocked,Trust proof,Do not render placeholders,Marketing
|
||||
security-badges,not supplied,svg/png,blocked,Security section,Do not render pending badges publicly,Security + Legal
|
||||
|
@@ -0,0 +1,7 @@
|
||||
# Asset Usage Rules
|
||||
|
||||
Only approved assets ship. Provisional assets require an approval record before release; blocked assets must not be rendered, even behind a feature flag visible to public users.
|
||||
|
||||
Use SVG for marks and interface illustrations when practical. Raster product captures require 1x/2x variants, responsive dimensions, width/height attributes, modern compression, and evidence metadata. Decorative images use empty alt text. Informative images use localized alt text that describes purpose, not every pixel.
|
||||
|
||||
The supplied horizontal logo contains a fixed light-theme text color for review convenience. Production must render the wordmark as live text or use theme-specific approved SVG variants. Do not use CSS filters to invert it.
|
||||
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" role="img" aria-labelledby="title">
|
||||
<title id="title">homePageCar mark</title>
|
||||
<rect width="32" height="32" rx="8" fill="#174BB5"/>
|
||||
<g fill="none" stroke="#FFFFFF" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M7 19h18M9 19l1.8-6.2a3 3 0 0 1 2.9-2.2h4.6a3 3 0 0 1 2.9 2.2L23 19M10 23h.01M22 23h.01M7 19v4a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-4"/>
|
||||
</g></svg>
|
||||
|
After Width: | Height: | Size: 443 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 220 40" role="img" aria-labelledby="title">
|
||||
<title id="title">homePageCar</title>
|
||||
<rect x="0" y="4" width="32" height="32" rx="8" fill="#174BB5"/>
|
||||
<g fill="none" stroke="#FFFFFF" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><path d="M7 23h18M9 23l1.8-6.2a3 3 0 0 1 2.9-2.2h4.6a3 3 0 0 1 2.9 2.2L23 23M10 27h.01M22 27h.01M7 23v4a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-4"/></g>
|
||||
<text x="43" y="27" font-family="Inter, Arial, sans-serif" font-size="22" font-weight="750" fill="#102035">homePageCar</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 576 B |
@@ -0,0 +1,385 @@
|
||||
# Component Contracts
|
||||
|
||||
|
||||
|
||||
Every component below is implemented once for all locales, directions, and themes. Props are semantic; components do not fetch translations internally unless the architecture establishes a single typed content boundary.
|
||||
|
||||
|
||||
## SiteHeader
|
||||
|
||||
**Purpose:** Primary navigation, brand, locale/theme controls, login, demo CTA
|
||||
|
||||
**States:** `default,scrolled`
|
||||
|
||||
**Typed data:** `HeaderModel`
|
||||
|
||||
**Copy namespace:** `header.*`
|
||||
|
||||
**Responsive:** Desktop at >=1120; drawer trigger below
|
||||
|
||||
**RTL:** Nav order reverses naturally; logo unchanged; directional icons selective
|
||||
|
||||
**Accessibility:** Sticky; 44px targets; skip-link precedes it
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## MobileDrawer
|
||||
|
||||
**Purpose:** Compact/medium navigation overlay
|
||||
|
||||
**States:** `closed,open`
|
||||
|
||||
**Typed data:** `DrawerModel`
|
||||
|
||||
**Copy namespace:** `header.*`
|
||||
|
||||
**Responsive:** Inline-start fixed drawer <=384px or 88vw
|
||||
|
||||
**RTL:** Opens right in RTL
|
||||
|
||||
**Accessibility:** Trap focus; inert background; Escape; focus return
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## LocaleSelector
|
||||
|
||||
**Purpose:** Switch locale by stable route ID
|
||||
|
||||
**States:** `closed,open,disabled`
|
||||
|
||||
**Typed data:** `LocaleSelectorProps`
|
||||
|
||||
**Copy namespace:** `language names`
|
||||
|
||||
**Responsive:** Native select baseline
|
||||
|
||||
**RTL:** Order EN/FR/AR; control follows document direction
|
||||
|
||||
**Accessibility:** Labelled; current locale selected; preserves route/hash
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## ThemeSelector
|
||||
|
||||
**Purpose:** Set Light/Dark/System preference
|
||||
|
||||
**States:** `light,dark,system`
|
||||
|
||||
**Typed data:** `ThemeSelectorProps`
|
||||
|
||||
**Copy namespace:** `header.light/dark/system`
|
||||
|
||||
**Responsive:** Native select or accessible segmented control
|
||||
|
||||
**RTL:** No mirroring needed
|
||||
|
||||
**Accessibility:** Cookie+storage; immediate; live system updates
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## HeroSection
|
||||
|
||||
**Purpose:** Communicate category, promise, primary and secondary actions
|
||||
|
||||
**States:** `default`
|
||||
|
||||
**Typed data:** `HeroModel`
|
||||
|
||||
**Copy namespace:** `hero.*`
|
||||
|
||||
**Responsive:** 1 column <1120; 7/5 split wide
|
||||
|
||||
**RTL:** Text aligns start; preview uses actual RTL rendering
|
||||
|
||||
**Accessibility:** One h1; CTA order follows document direction
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## ProductPreview
|
||||
|
||||
**Purpose:** Illustrative/evidence-governed product visual
|
||||
|
||||
**States:** `illustrative,approved-capture`
|
||||
|
||||
**Typed data:** `ProductPreviewModel`
|
||||
|
||||
**Copy namespace:** `preview.*`
|
||||
|
||||
**Responsive:** Simplify data table on compact
|
||||
|
||||
**RTL:** Do not mirror screenshots; coded preview renders RTL
|
||||
|
||||
**Accessibility:** Accessible caption; no false product claim
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## LifecycleProof
|
||||
|
||||
**Purpose:** Show operational coverage without customer logos
|
||||
|
||||
**States:** `default`
|
||||
|
||||
**Typed data:** `LifecycleItem[]`
|
||||
|
||||
**Copy namespace:** `trust.*`
|
||||
|
||||
**Responsive:** 1/2/4 columns by available width
|
||||
|
||||
**RTL:** Sequence follows reading direction
|
||||
|
||||
**Accessibility:** List semantics; icons decorative
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## ComparisonSection
|
||||
|
||||
**Purpose:** Fragmented versus connected workflow
|
||||
|
||||
**States:** `default`
|
||||
|
||||
**Typed data:** `ComparisonModel`
|
||||
|
||||
**Copy namespace:** `comparison.*`
|
||||
|
||||
**Responsive:** Stack compact; two columns medium+
|
||||
|
||||
**RTL:** Order follows locale reading direction
|
||||
|
||||
**Accessibility:** Headings identify both columns; do not rely on color
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## WorkflowSteps
|
||||
|
||||
**Purpose:** Four-step rental flow and tour source
|
||||
|
||||
**States:** `default`
|
||||
|
||||
**Typed data:** `WorkflowStep[]`
|
||||
|
||||
**Copy namespace:** `workflow.*`
|
||||
|
||||
**Responsive:** 1 column compact; 4 columns >=768
|
||||
|
||||
**RTL:** Step order follows reading direction
|
||||
|
||||
**Accessibility:** Ordered list; numerals isolated if needed
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## RoleCards
|
||||
|
||||
**Purpose:** Explain value by operating role
|
||||
|
||||
**States:** `default`
|
||||
|
||||
**Typed data:** `RoleCard[]`
|
||||
|
||||
**Copy namespace:** `roles.*`
|
||||
|
||||
**Responsive:** 1/2/4 columns content-driven
|
||||
|
||||
**RTL:** Same tree; start alignment
|
||||
|
||||
**Accessibility:** Heading hierarchy and readable card order
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## ModuleGrid
|
||||
|
||||
**Purpose:** Describe approved product modules
|
||||
|
||||
**States:** `default`
|
||||
|
||||
**Typed data:** `ModuleCard[]`
|
||||
|
||||
**Copy namespace:** `modules.*`
|
||||
|
||||
**Responsive:** 1/2/3 columns
|
||||
|
||||
**RTL:** Same tree; directional icons selective
|
||||
|
||||
**Accessibility:** No capability beyond approved copy
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## MeasurementPlan
|
||||
|
||||
**Purpose:** Show KPI definitions without invented outcomes
|
||||
|
||||
**States:** `default`
|
||||
|
||||
**Typed data:** `MetricDefinition[]`
|
||||
|
||||
**Copy namespace:** `results.*`
|
||||
|
||||
**Responsive:** Cards plus methodology block
|
||||
|
||||
**RTL:** Same tree
|
||||
|
||||
**Accessibility:** No unapproved numbers; ordered methodology
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## IntegrationCategories
|
||||
|
||||
**Purpose:** Neutral category list
|
||||
|
||||
**States:** `default`
|
||||
|
||||
**Typed data:** `IntegrationCategory[]`
|
||||
|
||||
**Copy namespace:** `integrations.*`
|
||||
|
||||
**Responsive:** Cloud/list adapts without clipping
|
||||
|
||||
**RTL:** Same tree
|
||||
|
||||
**Accessibility:** No partner logos until verified
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## SecurityChecklist
|
||||
|
||||
**Purpose:** Evidence-request checklist
|
||||
|
||||
**States:** `default`
|
||||
|
||||
**Typed data:** `SecurityCheck[]`
|
||||
|
||||
**Copy namespace:** `security.*`
|
||||
|
||||
**Responsive:** 1/2 columns
|
||||
|
||||
**RTL:** Same tree
|
||||
|
||||
**Accessibility:** No badges/certifications without approval
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## PricingPreview
|
||||
|
||||
**Purpose:** Explain pricing factors and demo route
|
||||
|
||||
**States:** `quote-only,approved-pricing`
|
||||
|
||||
**Typed data:** `PricingModel`
|
||||
|
||||
**Copy namespace:** `pricing.*`
|
||||
|
||||
**Responsive:** Stack compact; 2 columns >=768
|
||||
|
||||
**RTL:** Same tree
|
||||
|
||||
**Accessibility:** Never imply public price when absent
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## FAQAccordion
|
||||
|
||||
**Purpose:** Localized questions and answers
|
||||
|
||||
**States:** `closed,open`
|
||||
|
||||
**Typed data:** `FaqItem[]`
|
||||
|
||||
**Copy namespace:** `faq.*`
|
||||
|
||||
**Responsive:** Single column
|
||||
|
||||
**RTL:** Chevron mirrors only if it conveys expansion direction
|
||||
|
||||
**Accessibility:** Native details baseline; keyboard and SR tested
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## FinalCTA
|
||||
|
||||
**Purpose:** Final conversion block and approved secondary contact
|
||||
|
||||
**States:** `default`
|
||||
|
||||
**Typed data:** `FinalCtaModel`
|
||||
|
||||
**Copy namespace:** `finalCta.*`
|
||||
|
||||
**Responsive:** Stack compact; 2 columns >=768
|
||||
|
||||
**RTL:** CTA order follows document direction
|
||||
|
||||
**Accessibility:** Secondary link suppressed until real destination approved
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## SiteFooter
|
||||
|
||||
**Purpose:** Localized navigation, legal, evidence status internal only
|
||||
|
||||
**States:** `default`
|
||||
|
||||
**Typed data:** `FooterModel`
|
||||
|
||||
**Copy namespace:** `footer.*`
|
||||
|
||||
**Responsive:** Stack then grouped columns
|
||||
|
||||
**RTL:** Same tree
|
||||
|
||||
**Accessibility:** No public internal proof-status label
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## DemoDialog
|
||||
|
||||
**Purpose:** Qualification form and submission states
|
||||
|
||||
**States:** `idle,invalid,submitting,success,recoverable-error,terminal-error`
|
||||
|
||||
**Typed data:** `DemoFormProps`
|
||||
|
||||
**Copy namespace:** `form.*`
|
||||
|
||||
**Responsive:** Modal max width; full-screen-safe compact
|
||||
|
||||
**RTL:** Field order follows reading direction; emails isolated
|
||||
|
||||
**Accessibility:** Focus trap, summary, inline errors, return focus
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
|
||||
|
||||
## ProductTourDialog
|
||||
|
||||
**Purpose:** Four-step guided overview
|
||||
|
||||
**States:** `step-1,step-2,step-3,step-4,complete`
|
||||
|
||||
**Typed data:** `TourProps`
|
||||
|
||||
**Copy namespace:** `tour.*`
|
||||
|
||||
**Responsive:** Modal max width; compact-safe
|
||||
|
||||
**RTL:** Back/next positions follow reading direction but meaning stays explicit
|
||||
|
||||
**Accessibility:** Progress announced; focus moves to step heading
|
||||
|
||||
**Content rule:** Block size is content-driven. Unsupported evidence suppresses the component or uses the explicitly approved neutral variant.
|
||||
@@ -0,0 +1,21 @@
|
||||
Component,Purpose,States,Data_contract,Copy_namespace,Responsive_rule,RTL_rule,Accessibility_rule
|
||||
SiteHeader,"Primary navigation, brand, locale/theme controls, login, demo CTA","default,scrolled",HeaderModel,header.*,Desktop at >=1120; drawer trigger below,Nav order reverses naturally; logo unchanged; directional icons selective,Sticky; 44px targets; skip-link precedes it
|
||||
MobileDrawer,Compact/medium navigation overlay,"closed,open",DrawerModel,header.*,Inline-start fixed drawer <=384px or 88vw,Opens right in RTL,Trap focus; inert background; Escape; focus return
|
||||
LocaleSelector,Switch locale by stable route ID,"closed,open,disabled",LocaleSelectorProps,language names,Native select baseline,Order EN/FR/AR; control follows document direction,Labelled; current locale selected; preserves route/hash
|
||||
ThemeSelector,Set Light/Dark/System preference,"light,dark,system",ThemeSelectorProps,header.light/dark/system,Native select or accessible segmented control,No mirroring needed,Cookie+storage; immediate; live system updates
|
||||
HeroSection,"Communicate category, promise, primary and secondary actions",default,HeroModel,hero.*,1 column <1120; 7/5 split wide,Text aligns start; preview uses actual RTL rendering,One h1; CTA order follows document direction
|
||||
ProductPreview,Illustrative/evidence-governed product visual,"illustrative,approved-capture",ProductPreviewModel,preview.*,Simplify data table on compact,Do not mirror screenshots; coded preview renders RTL,Accessible caption; no false product claim
|
||||
LifecycleProof,Show operational coverage without customer logos,default,LifecycleItem[],trust.*,1/2/4 columns by available width,Sequence follows reading direction,List semantics; icons decorative
|
||||
ComparisonSection,Fragmented versus connected workflow,default,ComparisonModel,comparison.*,Stack compact; two columns medium+,Order follows locale reading direction,Headings identify both columns; do not rely on color
|
||||
WorkflowSteps,Four-step rental flow and tour source,default,WorkflowStep[],workflow.*,1 column compact; 4 columns >=768,Step order follows reading direction,Ordered list; numerals isolated if needed
|
||||
RoleCards,Explain value by operating role,default,RoleCard[],roles.*,1/2/4 columns content-driven,Same tree; start alignment,Heading hierarchy and readable card order
|
||||
ModuleGrid,Describe approved product modules,default,ModuleCard[],modules.*,1/2/3 columns,Same tree; directional icons selective,No capability beyond approved copy
|
||||
MeasurementPlan,Show KPI definitions without invented outcomes,default,MetricDefinition[],results.*,Cards plus methodology block,Same tree,No unapproved numbers; ordered methodology
|
||||
IntegrationCategories,Neutral category list,default,IntegrationCategory[],integrations.*,Cloud/list adapts without clipping,Same tree,No partner logos until verified
|
||||
SecurityChecklist,Evidence-request checklist,default,SecurityCheck[],security.*,1/2 columns,Same tree,No badges/certifications without approval
|
||||
PricingPreview,Explain pricing factors and demo route,"quote-only,approved-pricing",PricingModel,pricing.*,Stack compact; 2 columns >=768,Same tree,Never imply public price when absent
|
||||
FAQAccordion,Localized questions and answers,"closed,open",FaqItem[],faq.*,Single column,Chevron mirrors only if it conveys expansion direction,Native details baseline; keyboard and SR tested
|
||||
FinalCTA,Final conversion block and approved secondary contact,default,FinalCtaModel,finalCta.*,Stack compact; 2 columns >=768,CTA order follows document direction,Secondary link suppressed until real destination approved
|
||||
SiteFooter,"Localized navigation, legal, evidence status internal only",default,FooterModel,footer.*,Stack then grouped columns,Same tree,No public internal proof-status label
|
||||
DemoDialog,Qualification form and submission states,"idle,invalid,submitting,success,recoverable-error,terminal-error",DemoFormProps,form.*,Modal max width; full-screen-safe compact,Field order follows reading direction; emails isolated,"Focus trap, summary, inline errors, return focus"
|
||||
ProductTourDialog,Four-step guided overview,"step-1,step-2,step-3,step-4,complete",TourProps,tour.*,Modal max width; compact-safe,Back/next positions follow reading direction but meaning stays explicit,Progress announced; focus moves to step heading
|
||||
|
@@ -0,0 +1,13 @@
|
||||
Content_type,Key_pattern,Planning_bound,Rendering_rule
|
||||
Hero title,hero.title,90 Unicode characters target; no hard truncation,Maximum 3 lines at 320px in each locale; copy review if exceeded
|
||||
Hero body,hero.body,220 characters target,No clamp; readable measure <=65ch
|
||||
Navigation label,header.nav.*,24 characters target,No ellipsis; header switches mode before collision
|
||||
Button label,*.primary|*.secondary,40 characters target,Content-width; may wrap to 2 lines on compact only
|
||||
Card title,*.items.*.title,70 characters target,No fixed height
|
||||
Card body,*.items.*.body,220 characters target,No line clamp
|
||||
FAQ question,faq.items.*.question,160 characters target,Whole trigger remains visible
|
||||
FAQ answer,faq.items.*.answer,900 characters target,Paragraph/list semantics allowed
|
||||
Form error,form.*Error,180 characters target,Inline and summary can wrap
|
||||
Meta title,meta.title,50-60 Latin-character planning range,Localized SEO review; never truncate in source
|
||||
Meta description,meta.description,140-160 Latin-character planning range,Localized SEO review
|
||||
Atomic identifier,runtime value,Data-defined,Wrap with bdi/isolation; never translate
|
||||
|
@@ -0,0 +1,20 @@
|
||||
Component,Range_px,Layout,Constraint
|
||||
Global,0-767,16px minimum gutter; 1 column; 320px reflow gate,No horizontal overflow at 320 CSS px and 400% zoom
|
||||
Global,768-1119,24-32px gutter; 4/8-column compositions,Drawer navigation remains
|
||||
Global,1120+,40px max gutter; 12-column composition; 1280px container,Desktop header visible
|
||||
Header,0-1119,Brand + demo CTA where space permits + menu button,Language/theme/login live in drawer
|
||||
Header,1120+,"Brand, center nav, locale/theme, login, demo CTA",Header min block 76px
|
||||
Hero,0-1119,Copy then product visual; CTA wraps/stacks as needed,"Title <=14ch target, never forced"
|
||||
Hero,1120+,7/5 grid; vertically centered,Visual may not reduce copy below readable measure
|
||||
Lifecycle,0-479,1 column,Cards auto height
|
||||
Lifecycle,480-767,2 columns,Odd last card spans only if approved
|
||||
Lifecycle,768+,4 columns,"Equal visual rhythm, not fixed height"
|
||||
Workflow,0-767,1 column ordered list,Connectors omitted
|
||||
Workflow,768+,4 columns,Connectors direction-aware
|
||||
Cards,0-767,1 column,No carousel substitution
|
||||
Cards,768-1119,2 columns,Content-driven
|
||||
Cards,1120+,2-3 columns by component contract,No text truncation
|
||||
Dialogs,0-479,Viewport-safe margin 8-16px; internal scroll; no hidden submit,Virtual keyboard tested
|
||||
Dialogs,480+,Max inline size 720px,Centered native dialog
|
||||
Footer,0-767,Stacked groups,Logical order
|
||||
Footer,768+,Brand column + grouped links,No fixed widths
|
||||
|
@@ -0,0 +1,21 @@
|
||||
Component,RTL_layout,Mirroring,Theme_behavior,Required_variants
|
||||
SiteHeader,Use logical CSS; start alignment; one DOM tree.,None by default.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
MobileDrawer,Use logical CSS; start alignment; one DOM tree.,Drawer origin and slide transform mirror.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
LocaleSelector,Use logical CSS; start alignment; one DOM tree.,None by default.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
ThemeSelector,Use logical CSS; start alignment; one DOM tree.,None by default.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
HeroSection,Use logical CSS; start alignment; one DOM tree.,None by default.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
ProductPreview,Use logical CSS; start alignment; one DOM tree.,Coded preview may reflow in RTL. Captured screenshots never mirror.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
LifecycleProof,Use logical CSS; start alignment; one DOM tree.,None by default.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
ComparisonSection,Use logical CSS; start alignment; one DOM tree.,None by default.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
WorkflowSteps,Use logical CSS; start alignment; one DOM tree.,"Mirror directional arrows/connectors only; do not mirror check, vehicle, globe, or media icons.",Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
RoleCards,Use logical CSS; start alignment; one DOM tree.,None by default.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
ModuleGrid,Use logical CSS; start alignment; one DOM tree.,None by default.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
MeasurementPlan,Use logical CSS; start alignment; one DOM tree.,None by default.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
IntegrationCategories,Use logical CSS; start alignment; one DOM tree.,None by default.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
SecurityChecklist,Use logical CSS; start alignment; one DOM tree.,None by default.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
PricingPreview,Use logical CSS; start alignment; one DOM tree.,None by default.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
FAQAccordion,Use logical CSS; start alignment; one DOM tree.,"Mirror directional arrows/connectors only; do not mirror check, vehicle, globe, or media icons.",Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
FinalCTA,Use logical CSS; start alignment; one DOM tree.,None by default.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
SiteFooter,Use logical CSS; start alignment; one DOM tree.,None by default.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
DemoDialog,Use logical CSS; start alignment; one DOM tree.,None by default.,Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
ProductTourDialog,Use logical CSS; start alignment; one DOM tree.,"Mirror directional arrows/connectors only; do not mirror check, vehicle, globe, or media icons.",Consume semantic tokens; no component-owned theme palette.,"Test en-light, fr-dark, ar-light, ar-dark"
|
||||
|
@@ -0,0 +1,43 @@
|
||||
# Technology Profile
|
||||
|
||||
## Required capabilities
|
||||
|
||||
The production stack must support SSR or SSG, strict TypeScript, locale-aware route generation, server-readable cookies, CSP nonces or hashes, accessible native dialogs or an equivalent proven overlay primitive, CSS logical properties, automated component tests, Playwright-style browser tests, and deterministic visual-regression fixtures.
|
||||
|
||||
## Default profile when architecture has not selected a stack
|
||||
|
||||
This profile is a default, not a retroactive approval:
|
||||
|
||||
- React-compatible SSR framework with file-based routing
|
||||
- TypeScript in strict mode
|
||||
- CSS Modules plus global semantic custom properties
|
||||
- no runtime CSS-in-JS dependency for static marketing layout
|
||||
- server components or server rendering for page shell, metadata, locale, and theme attributes
|
||||
- client code limited to navigation drawer, theme selector, locale selector, tour, demo form, and analytics adapter
|
||||
- schema validation at network boundaries
|
||||
- first-party API endpoint or server action for demo submission
|
||||
- Playwright-compatible browser testing
|
||||
|
||||
Exact framework and dependency versions are pinned at repository creation and recorded in the decision log. Do not let the package manager quietly select floating major versions, because apparently version drift enjoys surprise appearances during deadlines.
|
||||
|
||||
## Styling constraints
|
||||
|
||||
CSS variables contain all visual tokens. Components may use CSS Modules, scoped styles, or an equivalent build-time strategy, but may not embed raw brand colors, physical left/right spacing, or duplicated light/dark values. Utility classes are permitted only if generated from the same semantic token source and if class ordering does not become the design system.
|
||||
|
||||
## Repository baseline
|
||||
|
||||
```text
|
||||
src/
|
||||
app-or-pages/
|
||||
components/
|
||||
content/locales/
|
||||
lib/analytics/
|
||||
lib/localization/
|
||||
lib/theme/
|
||||
styles/tokens.css
|
||||
styles/globals.css
|
||||
public/assets/
|
||||
tests/a11y/
|
||||
tests/browser/
|
||||
tests/visual/
|
||||
```
|
||||
@@ -0,0 +1,26 @@
|
||||
export type Locale = "en" | "fr" | "ar";
|
||||
export type Direction = "ltr" | "rtl";
|
||||
export type EvidenceStatus = "approved" | "illustrative" | "pending" | "expired" | "rejected";
|
||||
export type ThemePreference = "light" | "dark" | "system";
|
||||
|
||||
export interface LinkModel { id: string; label: string; href: string; external?: boolean; }
|
||||
export interface SiteHeaderProps { locale: Locale; direction: Direction; links: LinkModel[]; login?: LinkModel; onDemo(): void; }
|
||||
export interface DrawerProps extends SiteHeaderProps { open: boolean; onOpenChange(open: boolean): void; returnFocusRef?: HTMLElement | null; }
|
||||
export interface LocaleSelectorProps { locale: Locale; routeId: string; hash?: string; onLocaleChange(locale: Locale): void; }
|
||||
export interface ThemeSelectorProps { preference: ThemePreference; onPreferenceChange(value: ThemePreference): void; }
|
||||
export interface HeroModel { eyebrow: string; title: string; body: string; primaryLabel: string; secondaryLabel: string; }
|
||||
export interface ProductPreviewModel { status: EvidenceStatus; caption: string; locale: Locale; direction: Direction; theme: "light"|"dark"; assetId?: string; }
|
||||
export interface LifecycleItem { id: string; title: string; description: string; icon: string; }
|
||||
export interface ComparisonModel { title: string; body: string; before: { title: string; items: string[] }; after: { title: string; items: string[] }; }
|
||||
export interface WorkflowStep { id: string; ordinal: string; title: string; description: string; }
|
||||
export interface RoleCard { id: string; title: string; description: string; }
|
||||
export interface ModuleCard { id: string; title: string; description: string; evidenceStatus: EvidenceStatus; }
|
||||
export interface MetricDefinition { id: string; title: string; definition: string; publishedValue?: never; }
|
||||
export interface IntegrationCategory { id: string; label: string; verifiedPartners?: never; }
|
||||
export interface SecurityCheck { id: string; title: string; description: string; certificationBadge?: never; }
|
||||
export interface PricingModel { mode: "quote-only" | "approved-pricing"; title: string; body: string; factors: string[]; note: string; }
|
||||
export interface FaqItem { id: string; question: string; answer: string; }
|
||||
export interface DemoFormValues { fullName: string; workEmail: string; company: string; fleetSize: string; market?: string; preferredLanguage?: Locale; message?: string; }
|
||||
export type DemoFormState = "idle"|"validating"|"submitting"|"success"|"recoverable_error"|"terminal_error";
|
||||
export interface DemoFormProps { state: DemoFormState; values: DemoFormValues; fieldErrors: Partial<Record<keyof DemoFormValues,string>>; formError?: string; onSubmit(values: DemoFormValues): Promise<void>; }
|
||||
export interface TourProps { steps: WorkflowStep[]; activeIndex: number; open: boolean; onOpenChange(open:boolean): void; onStepChange(index:number): void; }
|
||||
@@ -0,0 +1,13 @@
|
||||
import manifest from "../localization/ROUTE_MANIFEST_v1.0.json";
|
||||
type Locale = "en"|"fr"|"ar";
|
||||
export function localizedPath(routeId:string, locale:Locale):string {
|
||||
const route = manifest.routes.find((item) => item.id === routeId);
|
||||
if (!route) throw new Error(`Unknown route: ${routeId}`);
|
||||
const slug = route.slugs[locale];
|
||||
return slug ? `/${locale}/${slug}` : `/${locale}`;
|
||||
}
|
||||
export function hreflangLinks(origin:string, routeId:string) {
|
||||
const alternates = manifest.locales.map((locale) => ({ rel:"alternate", hreflang:locale, href:new URL(localizedPath(routeId, locale as Locale),origin).href }));
|
||||
alternates.push({ rel:"alternate", hreflang:"x-default", href:new URL(localizedPath(routeId,"en"),origin).href });
|
||||
return alternates;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export const locales = ["en", "fr", "ar"] as const;
|
||||
export type Locale = typeof locales[number];
|
||||
export const defaultLocale: Locale = "en";
|
||||
export const directionByLocale: Record<Locale,"ltr"|"rtl"> = { en:"ltr", fr:"ltr", ar:"rtl" };
|
||||
export const localeCookie = "hpc-locale";
|
||||
export const localeStorageKey = "hpc.locale";
|
||||
export const campaignQueryAllowlist = ["utm_source","utm_medium","utm_campaign","utm_content","gclid"] as const;
|
||||
export const rootDetectionOrder = ["cookie","accept-language","default-en"] as const;
|
||||
export function isLocale(value: unknown): value is Locale { return typeof value === "string" && (locales as readonly string[]).includes(value); }
|
||||
export function isolateLtr(value: string): { dir:"ltr"; value:string } { return { dir:"ltr", value }; }
|
||||
@@ -0,0 +1,8 @@
|
||||
export const themeCookie = "hpc-theme";
|
||||
export const themeStorageKey = "hpc.theme.preference";
|
||||
export const themePreferences = ["light","dark","system"] as const;
|
||||
export type ThemePreference = typeof themePreferences[number];
|
||||
export type ResolvedTheme = "light"|"dark";
|
||||
export function isThemePreference(v:unknown): v is ThemePreference { return typeof v === "string" && (themePreferences as readonly string[]).includes(v); }
|
||||
export function resolveTheme(preference:ThemePreference, systemDark:boolean):ResolvedTheme { return preference === "system" ? (systemDark ? "dark" : "light") : preference; }
|
||||
export const themeCookieAttributes = { path:"/", sameSite:"lax" as const, maxAgeSeconds:31536000, secureInProduction:true };
|
||||
@@ -0,0 +1,19 @@
|
||||
Event,Trigger,Properties,PII_Allowed,Purpose
|
||||
page_view,Prototype loaded,"locale,theme,path,hash,session_id,test_mode,referrer_origin",No,Session start and denominator
|
||||
section_view,Section reaches 35% visibility,"section,locale,theme,hash,session_id",No,Discovery sequence
|
||||
navigation_click,Primary/mobile nav link used,"target,locale,theme,hash,session_id",No,Navigation path
|
||||
product_tour_open,Tour opened,"locale,theme,hash,session_id",No,Tour discovery
|
||||
product_tour_step,Tour step rendered,"step,locale,theme,session_id",No,Progress/drop-off
|
||||
product_tour_complete,Final tour step completed,"locale,theme,session_id",No,Completion
|
||||
product_tour_close,Tour closed,"reason,last_step,locale,theme,session_id",No,Abandonment point
|
||||
locale_change,Language selected,"from,to,context,session_id",No,Locale use/context preservation
|
||||
theme_change,Theme selected,"from,to,locale,session_id",No,Theme use
|
||||
mobile_nav_open,Drawer opened,"locale,theme,session_id",No,Mobile discovery
|
||||
mobile_nav_close,Drawer closed,"locale,theme,session_id",No,Drawer completion
|
||||
demo_open,Demo opened,"source,locale,theme,session_id",No,CTA source
|
||||
demo_validation_error,Validation blocked submit,"source,error_count,locale,theme,session_id",No,Error rate; never field values
|
||||
demo_submit_attempt,Submit activated,"source,locale,theme,session_id",No,Funnel attempt
|
||||
demo_submit_failure,Simulated service failure,"source,scenario,locale,theme,session_id",No,Failure recovery
|
||||
demo_submit_success,Prototype confirmation reached,"source,locale,theme,session_id",No,Completion
|
||||
demo_close,Demo closed,"reason,locale,theme,session_id",No,Abandonment
|
||||
faq_open,FAQ disclosure opened,"index,locale,theme,session_id",No,Question discovery
|
||||
|
@@ -0,0 +1,33 @@
|
||||
# Interaction Notes
|
||||
|
||||
## Navigation
|
||||
|
||||
Anchor navigation updates the URL hash and lands the target below the sticky header using `scroll-margin-block-start`. Locale switching preserves only hashes listed for the route. Mobile navigation closes after an internal destination activates. Focus is returned only when the close action does not immediately navigate.
|
||||
|
||||
## Drawer
|
||||
|
||||
`closed → opening → open → closing → closed`. Opening stores the active element, sets `aria-expanded=true`, reveals backdrop, makes page landmarks inert, locks body scroll without layout shift, and focuses the close control. Tab and Shift+Tab remain inside. Escape and backdrop close unless a nested blocking dialog is active.
|
||||
|
||||
## Dialogs
|
||||
|
||||
Use native `<dialog>` when browser support and QA pass; otherwise use a proven accessible primitive. The trigger regains focus on close. Backdrop click is permitted when the form is idle. During submission, closing requires an explicit cancel decision so an in-flight request is not silently duplicated.
|
||||
|
||||
## Demo validation
|
||||
|
||||
Validation occurs on submit, then on change/blur for fields that are already invalid. A form summary uses `role=alert` or an announced live region. First invalid field receives focus after the summary is updated. Native input semantics remain. Email syntax validation is deliberately modest; the server remains authoritative.
|
||||
|
||||
## Theme
|
||||
|
||||
Apply preference immediately. Persist cookie and storage in one transaction. Broadcast changes through the `storage` event. In System mode, respond to `prefers-color-scheme` changes. Never animate the entire page between themes.
|
||||
|
||||
## Product tour
|
||||
|
||||
Opening starts at step one. Back is disabled on the first step. Next becomes Finish on the last. Step heading receives programmatic focus after each change. Progress text is localized and announced politely. Completion does not imply a video was watched.
|
||||
|
||||
## FAQ
|
||||
|
||||
Native `details/summary` is the baseline. Multiple items may remain open. Do not introduce accordion exclusivity without a content reason and a new decision.
|
||||
|
||||
## Analytics
|
||||
|
||||
Events are emitted through a vendor-neutral adapter after consent. Event payloads contain route, locale, resolved theme, direction, component/source ID, and non-PII state. Form field values and free text are forbidden. Development logs must be disabled in production.
|
||||
@@ -0,0 +1,9 @@
|
||||
export type AnalyticsEventName =
|
||||
| "page_view" | "section_view" | "navigation_click"
|
||||
| "locale_change" | "theme_change" | "mobile_nav_open" | "mobile_nav_close"
|
||||
| "product_tour_open" | "product_tour_step" | "product_tour_complete" | "product_tour_close"
|
||||
| "demo_open" | "demo_submit_attempt" | "demo_validation_error" | "demo_submit_success" | "demo_submit_failure" | "demo_close"
|
||||
| "faq_open";
|
||||
export interface AnalyticsContext { routeId:string; locale:"en"|"fr"|"ar"; direction:"ltr"|"rtl"; resolvedTheme:"light"|"dark"; source?:string; step?:number; errorCode?:string; }
|
||||
export interface AnalyticsAdapter { consentGranted():boolean; track(name:AnalyticsEventName, context:AnalyticsContext):void; }
|
||||
export const forbiddenPayloadKeys = ["name","email","company","message","phone","fieldValue","serverResponse"] as const;
|
||||
@@ -0,0 +1,5 @@
|
||||
export const fleetSizeValues = ["1-9","10-24","25-49","50-99","100-249","250+"] as const;
|
||||
export type FleetSize = typeof fleetSizeValues[number];
|
||||
export interface DemoRequest { fullName:string; workEmail:string; company:string; fleetSize:FleetSize; market?:string; preferredLanguage?:"en"|"fr"|"ar"; message?:string; idempotencyKey:string; source:string; }
|
||||
export interface DemoSuccess { requestId:string; acceptedAt:string; nextStepCode:"sales_followup"|"manual_review"; }
|
||||
export interface DemoFailure { code:"validation"|"rate_limited"|"duplicate"|"unavailable"|"unknown"; retryable:boolean; fieldErrors?:Record<string,string>; }
|
||||
@@ -0,0 +1,14 @@
|
||||
(function () {
|
||||
var allowed = { light: true, dark: true, system: true };
|
||||
var cookieMatch = document.cookie.match(/(?:^|; )hpc-theme=([^;]+)/);
|
||||
var cookieValue = cookieMatch ? decodeURIComponent(cookieMatch[1]) : null;
|
||||
var stored = null;
|
||||
try { stored = localStorage.getItem("hpc.theme.preference"); } catch (_) {}
|
||||
var preference = allowed[cookieValue] ? cookieValue : (allowed[stored] ? stored : "system");
|
||||
var dark = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
var resolved = preference === "system" ? (dark ? "dark" : "light") : preference;
|
||||
var root = document.documentElement;
|
||||
root.dataset.themePreference = preference;
|
||||
root.dataset.theme = resolved;
|
||||
root.style.colorScheme = resolved;
|
||||
})();
|
||||
@@ -0,0 +1,39 @@
|
||||
# Localization Implementation
|
||||
|
||||
## Source and parity
|
||||
|
||||
English is the authoring source. French and Arabic are independent production resources, not machine-generated runtime fallbacks. CI compares complete key shape, scalar types, required arrays, empty values, and route coverage. A missing translation blocks merge.
|
||||
|
||||
## Document state
|
||||
|
||||
Set document attributes on the server:
|
||||
|
||||
```html
|
||||
<html lang="ar" dir="rtl" data-theme-preference="system" data-theme="dark">
|
||||
```
|
||||
|
||||
Do not wait for hydration to set language, direction, or resolved theme.
|
||||
|
||||
## Route behavior
|
||||
|
||||
- Public indexable pages use locale prefixes.
|
||||
- Root `/` is the only route eligible for browser-language detection.
|
||||
- Explicit locale URLs remain explicit.
|
||||
- Switch by route ID, not string substitution.
|
||||
- Preserve only allowlisted campaign parameters and valid section hashes.
|
||||
- Canonicals are self-referential locale URLs.
|
||||
- Every indexable locale page outputs reciprocal `en`, `fr`, `ar`, and `x-default` alternatives.
|
||||
|
||||
## Arabic and mixed direction
|
||||
|
||||
Use formal Modern Standard Arabic. Apply document-level RTL and CSS logical properties. Wrap plates, VINs, emails, phone numbers, URLs, currency codes, dates with Latin digits, model numbers, and analytics identifiers in `bdi dir="ltr"` or a typed isolation component. Do not add directional Unicode marks manually inside translation strings unless linguistic review documents the exception.
|
||||
|
||||
Icons mirror only when their meaning is directional. Product screenshots never mirror.
|
||||
|
||||
## Formatting
|
||||
|
||||
Language does not imply market. Formatters receive locale plus explicit currency, timezone, country, and numbering policy. The baseline uses Gregorian dates and Latin digits for all three language-only locales until market research approves another rule.
|
||||
|
||||
## Copy governance
|
||||
|
||||
Every visible string has a semantic key. Exceptions are the `homePageCar` proper name, immutable technical identifiers, and data supplied at runtime. Public evidence-bearing blocks include evidence status in their content model; pending or expired evidence suppresses the claim.
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"defaultLocale": "en",
|
||||
"locales": [
|
||||
"en",
|
||||
"fr",
|
||||
"ar"
|
||||
],
|
||||
"rootDetection": true,
|
||||
"routes": [
|
||||
{
|
||||
"id": "home",
|
||||
"slugs": {
|
||||
"en": "",
|
||||
"fr": "",
|
||||
"ar": ""
|
||||
},
|
||||
"indexable": true,
|
||||
"hashes": [
|
||||
"top",
|
||||
"product",
|
||||
"workflow",
|
||||
"modules",
|
||||
"pricing",
|
||||
"faq",
|
||||
"contact"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "login",
|
||||
"slugs": {
|
||||
"en": "login",
|
||||
"fr": "connexion",
|
||||
"ar": "تسجيل-الدخول"
|
||||
},
|
||||
"indexable": false,
|
||||
"hashes": []
|
||||
},
|
||||
{
|
||||
"id": "privacy",
|
||||
"slugs": {
|
||||
"en": "privacy",
|
||||
"fr": "confidentialite",
|
||||
"ar": "الخصوصية"
|
||||
},
|
||||
"indexable": true,
|
||||
"hashes": []
|
||||
},
|
||||
{
|
||||
"id": "terms",
|
||||
"slugs": {
|
||||
"en": "terms",
|
||||
"fr": "conditions",
|
||||
"ar": "الشروط"
|
||||
},
|
||||
"indexable": true,
|
||||
"hashes": []
|
||||
},
|
||||
{
|
||||
"id": "accessibility",
|
||||
"slugs": {
|
||||
"en": "accessibility",
|
||||
"fr": "accessibilite",
|
||||
"ar": "إمكانية-الوصول"
|
||||
},
|
||||
"indexable": true,
|
||||
"hashes": []
|
||||
}
|
||||
],
|
||||
"switching": {
|
||||
"preserveQueryAllowlist": [
|
||||
"utm_source",
|
||||
"utm_medium",
|
||||
"utm_campaign",
|
||||
"utm_content",
|
||||
"gclid"
|
||||
],
|
||||
"preserveValidHash": true,
|
||||
"dropUnknownQuery": true
|
||||
},
|
||||
"hreflang": {
|
||||
"values": [
|
||||
"en",
|
||||
"fr",
|
||||
"ar"
|
||||
],
|
||||
"xDefaultLocale": "en",
|
||||
"selfCanonical": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
Key,EN,FR,AR,Value_type,Usage
|
||||
comparison.afterItems[0],yes,yes,yes,str,visible
|
||||
comparison.afterItems[1],yes,yes,yes,str,visible
|
||||
comparison.afterItems[2],yes,yes,yes,str,visible
|
||||
comparison.afterItems[3],yes,yes,yes,str,visible
|
||||
comparison.afterTitle,yes,yes,yes,str,visible
|
||||
comparison.beforeItems[0],yes,yes,yes,str,visible
|
||||
comparison.beforeItems[1],yes,yes,yes,str,visible
|
||||
comparison.beforeItems[2],yes,yes,yes,str,visible
|
||||
comparison.beforeItems[3],yes,yes,yes,str,visible
|
||||
comparison.beforeTitle,yes,yes,yes,str,visible
|
||||
comparison.body,yes,yes,yes,str,visible
|
||||
comparison.eyebrow,yes,yes,yes,str,visible
|
||||
comparison.title,yes,yes,yes,str,visible
|
||||
faq.eyebrow,yes,yes,yes,str,visible
|
||||
faq.items[0][0],yes,yes,yes,str,visible
|
||||
faq.items[0][1],yes,yes,yes,str,visible
|
||||
faq.items[1][0],yes,yes,yes,str,visible
|
||||
faq.items[1][1],yes,yes,yes,str,visible
|
||||
faq.items[2][0],yes,yes,yes,str,visible
|
||||
faq.items[2][1],yes,yes,yes,str,visible
|
||||
faq.items[3][0],yes,yes,yes,str,visible
|
||||
faq.items[3][1],yes,yes,yes,str,visible
|
||||
faq.items[4][0],yes,yes,yes,str,visible
|
||||
faq.items[4][1],yes,yes,yes,str,visible
|
||||
faq.items[5][0],yes,yes,yes,str,visible
|
||||
faq.items[5][1],yes,yes,yes,str,visible
|
||||
faq.title,yes,yes,yes,str,visible
|
||||
final.body,yes,yes,yes,str,visible
|
||||
final.eyebrow,yes,yes,yes,str,visible
|
||||
final.primary,yes,yes,yes,str,visible
|
||||
final.secondary,yes,yes,yes,str,visible
|
||||
final.title,yes,yes,yes,str,visible
|
||||
footer.copyright,yes,yes,yes,str,visible
|
||||
footer.groups[0][0],yes,yes,yes,str,visible
|
||||
footer.groups[0][1][0][0],yes,yes,yes,str,visible
|
||||
footer.groups[0][1][0][1],yes,yes,yes,str,visible
|
||||
footer.groups[0][1][1][0],yes,yes,yes,str,visible
|
||||
footer.groups[0][1][1][1],yes,yes,yes,str,visible
|
||||
footer.groups[0][1][2][0],yes,yes,yes,str,visible
|
||||
footer.groups[0][1][2][1],yes,yes,yes,str,visible
|
||||
footer.groups[1][0],yes,yes,yes,str,visible
|
||||
footer.groups[1][1][0][0],yes,yes,yes,str,visible
|
||||
footer.groups[1][1][0][1],yes,yes,yes,str,visible
|
||||
footer.groups[1][1][1][0],yes,yes,yes,str,visible
|
||||
footer.groups[1][1][1][1],yes,yes,yes,str,visible
|
||||
footer.groups[2][0],yes,yes,yes,str,visible
|
||||
footer.groups[2][1][0][0],yes,yes,yes,str,visible
|
||||
footer.groups[2][1][0][1],yes,yes,yes,str,visible
|
||||
footer.groups[2][1][1][0],yes,yes,yes,str,visible
|
||||
footer.groups[2][1][1][1],yes,yes,yes,str,visible
|
||||
footer.groups[2][1][2][0],yes,yes,yes,str,visible
|
||||
footer.groups[2][1][2][1],yes,yes,yes,str,visible
|
||||
footer.groups[3][0],yes,yes,yes,str,visible
|
||||
footer.groups[3][1][0][0],yes,yes,yes,str,visible
|
||||
footer.groups[3][1][0][1],yes,yes,yes,str,visible
|
||||
footer.groups[3][1][1][0],yes,yes,yes,str,visible
|
||||
footer.groups[3][1][1][1],yes,yes,yes,str,visible
|
||||
footer.groups[3][1][2][0],yes,yes,yes,str,visible
|
||||
footer.groups[3][1][2][1],yes,yes,yes,str,visible
|
||||
footer.tagline,yes,yes,yes,str,visible
|
||||
form.body,yes,yes,yes,str,visible
|
||||
form.close,yes,yes,yes,str,visible
|
||||
form.company,yes,yes,yes,str,visible
|
||||
form.email,yes,yes,yes,str,visible
|
||||
form.emailError,yes,yes,yes,str,visible
|
||||
form.errorSummary,yes,yes,yes,str,visible
|
||||
form.fleet,yes,yes,yes,str,visible
|
||||
form.fleetOptions[0],yes,yes,yes,str,visible
|
||||
form.fleetOptions[1],yes,yes,yes,str,visible
|
||||
form.fleetOptions[2],yes,yes,yes,str,visible
|
||||
form.fleetOptions[3],yes,yes,yes,str,visible
|
||||
form.fleetOptions[4],yes,yes,yes,str,visible
|
||||
form.fleetOptions[5],yes,yes,yes,str,visible
|
||||
form.langOptions[0],yes,yes,yes,str,visible
|
||||
form.langOptions[1],yes,yes,yes,str,visible
|
||||
form.langOptions[2],yes,yes,yes,str,visible
|
||||
form.language,yes,yes,yes,str,visible
|
||||
form.market,yes,yes,yes,str,visible
|
||||
form.message,yes,yes,yes,str,visible
|
||||
form.name,yes,yes,yes,str,visible
|
||||
form.privacy,yes,yes,yes,str,visible
|
||||
form.required,yes,yes,yes,str,visible
|
||||
form.requiredError,yes,yes,yes,str,visible
|
||||
form.submissionError,yes,yes,yes,str,visible
|
||||
form.submit,yes,yes,yes,str,visible
|
||||
form.submitAnother,yes,yes,yes,str,visible
|
||||
form.successBody,yes,yes,yes,str,visible
|
||||
form.successTitle,yes,yes,yes,str,visible
|
||||
form.title,yes,yes,yes,str,visible
|
||||
header.dark,yes,yes,yes,str,visible
|
||||
header.demo,yes,yes,yes,str,visible
|
||||
header.language,yes,yes,yes,str,visible
|
||||
header.light,yes,yes,yes,str,visible
|
||||
header.login,yes,yes,yes,str,visible
|
||||
header.menu,yes,yes,yes,str,visible
|
||||
header.nav[0][0],yes,yes,yes,str,visible
|
||||
header.nav[0][1],yes,yes,yes,str,visible
|
||||
header.nav[1][0],yes,yes,yes,str,visible
|
||||
header.nav[1][1],yes,yes,yes,str,visible
|
||||
header.nav[2][0],yes,yes,yes,str,visible
|
||||
header.nav[2][1],yes,yes,yes,str,visible
|
||||
header.nav[3][0],yes,yes,yes,str,visible
|
||||
header.nav[3][1],yes,yes,yes,str,visible
|
||||
header.nav[4][0],yes,yes,yes,str,visible
|
||||
header.nav[4][1],yes,yes,yes,str,visible
|
||||
header.system,yes,yes,yes,str,visible
|
||||
header.theme,yes,yes,yes,str,visible
|
||||
hero.body,yes,yes,yes,str,visible
|
||||
hero.caption,yes,yes,yes,str,visible
|
||||
hero.eyebrow,yes,yes,yes,str,visible
|
||||
hero.primary,yes,yes,yes,str,visible
|
||||
hero.secondary,yes,yes,yes,str,visible
|
||||
hero.title,yes,yes,yes,str,visible
|
||||
integrations.body,yes,yes,yes,str,visible
|
||||
integrations.eyebrow,yes,yes,yes,str,visible
|
||||
integrations.items[0],yes,yes,yes,str,visible
|
||||
integrations.items[1],yes,yes,yes,str,visible
|
||||
integrations.items[2],yes,yes,yes,str,visible
|
||||
integrations.items[3],yes,yes,yes,str,visible
|
||||
integrations.items[4],yes,yes,yes,str,visible
|
||||
integrations.items[5],yes,yes,yes,str,visible
|
||||
integrations.title,yes,yes,yes,str,visible
|
||||
meta.description,yes,yes,yes,str,metadata
|
||||
meta.dir,yes,yes,yes,str,metadata
|
||||
meta.langName,yes,yes,yes,str,metadata
|
||||
meta.title,yes,yes,yes,str,metadata
|
||||
modules.body,yes,yes,yes,str,visible
|
||||
modules.eyebrow,yes,yes,yes,str,visible
|
||||
modules.items[0][0],yes,yes,yes,str,visible
|
||||
modules.items[0][1],yes,yes,yes,str,visible
|
||||
modules.items[1][0],yes,yes,yes,str,visible
|
||||
modules.items[1][1],yes,yes,yes,str,visible
|
||||
modules.items[2][0],yes,yes,yes,str,visible
|
||||
modules.items[2][1],yes,yes,yes,str,visible
|
||||
modules.items[3][0],yes,yes,yes,str,visible
|
||||
modules.items[3][1],yes,yes,yes,str,visible
|
||||
modules.items[4][0],yes,yes,yes,str,visible
|
||||
modules.items[4][1],yes,yes,yes,str,visible
|
||||
modules.items[5][0],yes,yes,yes,str,visible
|
||||
modules.items[5][1],yes,yes,yes,str,visible
|
||||
modules.title,yes,yes,yes,str,visible
|
||||
preview.active,yes,yes,yes,str,visible
|
||||
preview.attention,yes,yes,yes,str,visible
|
||||
preview.branch,yes,yes,yes,str,visible
|
||||
preview.customer,yes,yes,yes,str,visible
|
||||
preview.plate1,yes,yes,yes,str,visible
|
||||
preview.plate2,yes,yes,yes,str,visible
|
||||
preview.r1,yes,yes,yes,str,visible
|
||||
preview.r2,yes,yes,yes,str,visible
|
||||
preview.r3,yes,yes,yes,str,visible
|
||||
preview.ready,yes,yes,yes,str,visible
|
||||
preview.reservations,yes,yes,yes,str,visible
|
||||
preview.status,yes,yes,yes,str,visible
|
||||
preview.statusDue,yes,yes,yes,str,visible
|
||||
preview.statusReady,yes,yes,yes,str,visible
|
||||
preview.task,yes,yes,yes,str,visible
|
||||
preview.taskAssign,yes,yes,yes,str,visible
|
||||
preview.taskInspect,yes,yes,yes,str,visible
|
||||
preview.title,yes,yes,yes,str,visible
|
||||
preview.today,yes,yes,yes,str,visible
|
||||
preview.vehicle,yes,yes,yes,str,visible
|
||||
pricing.body,yes,yes,yes,str,visible
|
||||
pricing.eyebrow,yes,yes,yes,str,visible
|
||||
pricing.factors[0],yes,yes,yes,str,visible
|
||||
pricing.factors[1],yes,yes,yes,str,visible
|
||||
pricing.factors[2],yes,yes,yes,str,visible
|
||||
pricing.factors[3],yes,yes,yes,str,visible
|
||||
pricing.note,yes,yes,yes,str,visible
|
||||
pricing.primary,yes,yes,yes,str,visible
|
||||
pricing.title,yes,yes,yes,str,visible
|
||||
research.clear,yes,yes,yes,str,visible
|
||||
research.close,yes,yes,yes,str,visible
|
||||
research.events,yes,yes,yes,str,visible
|
||||
research.export,yes,yes,yes,str,visible
|
||||
research.title,yes,yes,yes,str,visible
|
||||
results.body,yes,yes,yes,str,visible
|
||||
results.eyebrow,yes,yes,yes,str,visible
|
||||
results.methodTitle,yes,yes,yes,str,visible
|
||||
results.method[0],yes,yes,yes,str,visible
|
||||
results.method[1],yes,yes,yes,str,visible
|
||||
results.method[2],yes,yes,yes,str,visible
|
||||
results.method[3],yes,yes,yes,str,visible
|
||||
results.metrics[0][0],yes,yes,yes,str,visible
|
||||
results.metrics[0][1],yes,yes,yes,str,visible
|
||||
results.metrics[1][0],yes,yes,yes,str,visible
|
||||
results.metrics[1][1],yes,yes,yes,str,visible
|
||||
results.metrics[2][0],yes,yes,yes,str,visible
|
||||
results.metrics[2][1],yes,yes,yes,str,visible
|
||||
results.metrics[3][0],yes,yes,yes,str,visible
|
||||
results.metrics[3][1],yes,yes,yes,str,visible
|
||||
results.title,yes,yes,yes,str,visible
|
||||
roles.eyebrow,yes,yes,yes,str,visible
|
||||
roles.roles[0][0],yes,yes,yes,str,visible
|
||||
roles.roles[0][1],yes,yes,yes,str,visible
|
||||
roles.roles[1][0],yes,yes,yes,str,visible
|
||||
roles.roles[1][1],yes,yes,yes,str,visible
|
||||
roles.roles[2][0],yes,yes,yes,str,visible
|
||||
roles.roles[2][1],yes,yes,yes,str,visible
|
||||
roles.roles[3][0],yes,yes,yes,str,visible
|
||||
roles.roles[3][1],yes,yes,yes,str,visible
|
||||
roles.title,yes,yes,yes,str,visible
|
||||
security.body,yes,yes,yes,str,visible
|
||||
security.checks[0][0],yes,yes,yes,str,visible
|
||||
security.checks[0][1],yes,yes,yes,str,visible
|
||||
security.checks[1][0],yes,yes,yes,str,visible
|
||||
security.checks[1][1],yes,yes,yes,str,visible
|
||||
security.checks[2][0],yes,yes,yes,str,visible
|
||||
security.checks[2][1],yes,yes,yes,str,visible
|
||||
security.checks[3][0],yes,yes,yes,str,visible
|
||||
security.checks[3][1],yes,yes,yes,str,visible
|
||||
security.eyebrow,yes,yes,yes,str,visible
|
||||
security.title,yes,yes,yes,str,visible
|
||||
tour.back,yes,yes,yes,str,visible
|
||||
tour.close,yes,yes,yes,str,visible
|
||||
tour.finish,yes,yes,yes,str,visible
|
||||
tour.intro,yes,yes,yes,str,visible
|
||||
tour.next,yes,yes,yes,str,visible
|
||||
tour.of,yes,yes,yes,str,visible
|
||||
tour.step,yes,yes,yes,str,visible
|
||||
tour.title,yes,yes,yes,str,visible
|
||||
trust.body,yes,yes,yes,str,visible
|
||||
trust.eyebrow,yes,yes,yes,str,visible
|
||||
trust.items[0][0],yes,yes,yes,str,visible
|
||||
trust.items[0][1],yes,yes,yes,str,visible
|
||||
trust.items[1][0],yes,yes,yes,str,visible
|
||||
trust.items[1][1],yes,yes,yes,str,visible
|
||||
trust.items[2][0],yes,yes,yes,str,visible
|
||||
trust.items[2][1],yes,yes,yes,str,visible
|
||||
trust.items[3][0],yes,yes,yes,str,visible
|
||||
trust.items[3][1],yes,yes,yes,str,visible
|
||||
trust.title,yes,yes,yes,str,visible
|
||||
workflow.body,yes,yes,yes,str,visible
|
||||
workflow.eyebrow,yes,yes,yes,str,visible
|
||||
workflow.steps[0][0],yes,yes,yes,str,visible
|
||||
workflow.steps[0][1],yes,yes,yes,str,visible
|
||||
workflow.steps[0][2],yes,yes,yes,str,visible
|
||||
workflow.steps[1][0],yes,yes,yes,str,visible
|
||||
workflow.steps[1][1],yes,yes,yes,str,visible
|
||||
workflow.steps[1][2],yes,yes,yes,str,visible
|
||||
workflow.steps[2][0],yes,yes,yes,str,visible
|
||||
workflow.steps[2][1],yes,yes,yes,str,visible
|
||||
workflow.steps[2][2],yes,yes,yes,str,visible
|
||||
workflow.steps[3][0],yes,yes,yes,str,visible
|
||||
workflow.steps[3][1],yes,yes,yes,str,visible
|
||||
workflow.steps[3][2],yes,yes,yes,str,visible
|
||||
workflow.title,yes,yes,yes,str,visible
|
||||
|
@@ -0,0 +1,430 @@
|
||||
{
|
||||
"meta": {
|
||||
"langName": "العربية",
|
||||
"dir": "rtl",
|
||||
"title": "homePageCar | تشغيل مترابط لتأجير السيارات",
|
||||
"description": "أدِر الحجوزات والمركبات والعقود والتسليم والإرجاع ضمن منصة تشغيل مترابطة."
|
||||
},
|
||||
"header": {
|
||||
"nav": [
|
||||
[
|
||||
"product",
|
||||
"المنتج"
|
||||
],
|
||||
[
|
||||
"workflow",
|
||||
"سير العمل"
|
||||
],
|
||||
[
|
||||
"modules",
|
||||
"الوحدات"
|
||||
],
|
||||
[
|
||||
"pricing",
|
||||
"التسعير"
|
||||
],
|
||||
[
|
||||
"faq",
|
||||
"الأسئلة الشائعة"
|
||||
]
|
||||
],
|
||||
"login": "تسجيل الدخول",
|
||||
"demo": "احجز عرضًا توضيحيًا",
|
||||
"menu": "فتح القائمة",
|
||||
"language": "اللغة",
|
||||
"theme": "المظهر",
|
||||
"light": "فاتح",
|
||||
"dark": "داكن",
|
||||
"system": "النظام"
|
||||
},
|
||||
"hero": {
|
||||
"eyebrow": "تشغيل تأجير السيارات ضمن نظام مترابط",
|
||||
"title": "أدِر كل عملية تأجير من الحجز حتى إعادة المركبة في نظام واحد.",
|
||||
"body": "اجمع الحجوزات والمركبات والعقود والتسليم والإرجاع في سجل تشغيلي واحد، كي يرى كل فريق ما يتطلب المتابعة بعد ذلك.",
|
||||
"primary": "احجز عرضًا توضيحيًا للمنتج",
|
||||
"secondary": "شاهد جولة المنتج",
|
||||
"caption": "واجهة توضيحية للمنتج. يجب أن تستخدم الشاشات النهائية بيانات ولقطات معتمدة."
|
||||
},
|
||||
"trust": {
|
||||
"eyebrow": "تغطية تشغيلية",
|
||||
"title": "سير عمل واحد يغطي دورة التأجير كاملة.",
|
||||
"body": "حافظ على ترابط سياق العميل والمركبة والعقد والمهام مع تقدم عملية التأجير.",
|
||||
"items": [
|
||||
[
|
||||
"الحجز",
|
||||
"سجّل الطلب والبيانات المطلوبة."
|
||||
],
|
||||
[
|
||||
"المركبة",
|
||||
"تابع التوافر والجاهزية."
|
||||
],
|
||||
[
|
||||
"العقد",
|
||||
"اجمع مهام التسليم والسجلات في موضع واحد."
|
||||
],
|
||||
[
|
||||
"الإرجاع",
|
||||
"سجّل الحالة وأغلق أعمال المتابعة."
|
||||
]
|
||||
]
|
||||
},
|
||||
"comparison": {
|
||||
"eyebrow": "لماذا التغيير",
|
||||
"title": "استبدل عمليات التسليم المجزأة بسير تشغيلي مشترك.",
|
||||
"body": "تكلفة الأدوات المنفصلة لا تظهر دائمًا في عطل كبير، بل تتراكم يوميًا عبر تكرار الإدخال وضياع السياق وتأخر المتابعة.",
|
||||
"beforeTitle": "تشغيل مجزأ",
|
||||
"beforeItems": [
|
||||
"نسخ بيانات الحجز بين أدوات متعددة",
|
||||
"تأكيد حالة المركبة عبر الرسائل",
|
||||
"متابعة مهام العقد بالاعتماد على الذاكرة",
|
||||
"اكتشاف مشكلات الإرجاع بعد مغادرة العميل"
|
||||
],
|
||||
"afterTitle": "تشغيل مترابط",
|
||||
"afterItems": [
|
||||
"حالة حجز واحدة يراها الفريق",
|
||||
"ربط جاهزية المركبة بعملية التأجير",
|
||||
"إظهار متطلبات التسليم قبل تسليم المركبة",
|
||||
"إنشاء متابعة الإرجاع بينما لا يزال السياق واضحًا"
|
||||
]
|
||||
},
|
||||
"workflow": {
|
||||
"eyebrow": "سير عمل متكامل",
|
||||
"title": "حرّك عملية التأجير إلى الأمام من دون فقدان السياق.",
|
||||
"body": "توضح كل خطوة القرار والمسؤول والإجراء التالي بدل دفن التشغيل داخل قائمة عامة من الميزات.",
|
||||
"steps": [
|
||||
[
|
||||
"01",
|
||||
"تسجيل الحجز",
|
||||
"سجّل التواريخ وبيانات السائق والمتطلبات والمصدر."
|
||||
],
|
||||
[
|
||||
"02",
|
||||
"تخصيص مركبة جاهزة",
|
||||
"طابق التوافر مع الفئة والموقع وحالة الجاهزية."
|
||||
],
|
||||
[
|
||||
"03",
|
||||
"إكمال التسليم",
|
||||
"تحقق من المستندات والفحص والعقد ومهام تسليم المركبة."
|
||||
],
|
||||
[
|
||||
"04",
|
||||
"معالجة الإرجاع",
|
||||
"سجّل الحالة وأغلق الأعمال المفتوحة وأعد المركبة إلى التوافر."
|
||||
]
|
||||
]
|
||||
},
|
||||
"roles": {
|
||||
"eyebrow": "مصمم لفريق التشغيل",
|
||||
"title": "امنح كل دور السياق الذي يحتاجه من دون إنشاء نسخ متعددة من الحقيقة.",
|
||||
"roles": [
|
||||
[
|
||||
"المالك أو المدير",
|
||||
"اطّلع على عبء العمل والاستثناءات والمؤشرات التشغيلية عبر النشاط."
|
||||
],
|
||||
[
|
||||
"فريق الحجوزات",
|
||||
"حوّل الطلبات إلى حجوزات مؤكدة مع عدد أقل من عمليات التسليم."
|
||||
],
|
||||
[
|
||||
"الأسطول والتشغيل",
|
||||
"اعرف المركبات المتاحة أو المحجوبة أو المستحقة أو التي تنتظر إجراءً."
|
||||
],
|
||||
[
|
||||
"مكتب الاستقبال",
|
||||
"حضّر مهام التسليم والإرجاع قبل انتظار العميل."
|
||||
]
|
||||
]
|
||||
},
|
||||
"modules": {
|
||||
"eyebrow": "وحدات المنتج",
|
||||
"title": "نواة مترابطة منظّمة حول أعمال التأجير الفعلية.",
|
||||
"body": "توضح حدود الوحدات المسؤوليات، بينما تمنع السجلات المشتركة فوضى النسخ واللصق المعتادة.",
|
||||
"items": [
|
||||
[
|
||||
"الحجوزات",
|
||||
"التوافر والتواريخ ومتطلبات العميل والحالة ضمن سير واحد."
|
||||
],
|
||||
[
|
||||
"جاهزية الأسطول",
|
||||
"توافر المركبات والحجوزات التشغيلية وحالة الخدمة وسياق الموقع."
|
||||
],
|
||||
[
|
||||
"عقود الإيجار",
|
||||
"متطلبات التسليم وحالة العقد والسجلات التشغيلية."
|
||||
],
|
||||
[
|
||||
"فحص المركبة",
|
||||
"فحوص منظمة عند التسليم والإرجاع مع مهام متابعة."
|
||||
],
|
||||
[
|
||||
"سجلات العملاء",
|
||||
"سجل التأجير وبيانات الاتصال المرتبطة بالعمل الجاري."
|
||||
],
|
||||
[
|
||||
"التقارير التشغيلية",
|
||||
"تعريفات وعروض تشغيلية يمكن التحقق منها مقابل النشاط المصدر."
|
||||
]
|
||||
]
|
||||
},
|
||||
"results": {
|
||||
"eyebrow": "نتائج قابلة للقياس",
|
||||
"title": "قِس التغيير، لا الخطاب التسويقي.",
|
||||
"body": "لا ينبغي نشر أي نتيجة قبل اعتماد خط أساس حقيقي لعميل وفترة مقارنة وتعريف واضح للبيانات. لذلك تعرض هذه النسخة منهجية القياس بدل نسب مئوية مختلقة.",
|
||||
"metrics": [
|
||||
[
|
||||
"زمن معالجة الحجز",
|
||||
"من استلام طلب صالح للعمل حتى تأكيد الحجز."
|
||||
],
|
||||
[
|
||||
"زمن إعادة المركبة إلى الجاهزية",
|
||||
"من تسجيل الإرجاع حتى حالة جاهز للتأجير."
|
||||
],
|
||||
[
|
||||
"معدل استخدام الأسطول",
|
||||
"مقارنة أيام التوافر بأيام التأجير وفق تعريف واحد معتمد."
|
||||
],
|
||||
[
|
||||
"متابعة حالات التأخير",
|
||||
"عمليات التأجير المتأخرة المفتوحة مع مسؤول وإجراء تالٍ."
|
||||
]
|
||||
],
|
||||
"methodTitle": "المنهجية المطلوبة قبل نشر أي نتيجة",
|
||||
"method": [
|
||||
"سجّل خط أساس قبل الإطلاق باستخدام تعريفات المؤشرات نفسها.",
|
||||
"قارن مواقع وفئات أسطول وفترات تشغيل متكافئة.",
|
||||
"انشر حجم العينة والاستثناءات وفترة القياس.",
|
||||
"اربط كل نتيجة منشورة بسجل دليل معتمد."
|
||||
]
|
||||
},
|
||||
"integrations": {
|
||||
"eyebrow": "التكاملات",
|
||||
"title": "اربط الأنظمة التي يعتمد عليها تشغيلك حاليًا.",
|
||||
"body": "يُعتمد نطاق التكامل خلال مرحلة الاستكشاف ليتوافق مع سوقك وبنيتك الحالية وملكية البيانات. لا تُعرض أسماء شركاء قبل التحقق من توافر الموصل.",
|
||||
"items": [
|
||||
"المحاسبة والمالية",
|
||||
"المدفوعات ومبالغ الضمان",
|
||||
"الاتصال بالمركبات وبياناتها",
|
||||
"خدمات الهوية والمستندات",
|
||||
"البريد الإلكتروني والرسائل والإشعارات",
|
||||
"الموقع الإلكتروني وقنوات الحجز"
|
||||
]
|
||||
},
|
||||
"security": {
|
||||
"eyebrow": "الأمن والموثوقية",
|
||||
"title": "قيّم المنصة بالأدلة، لا بالشعارات.",
|
||||
"body": "لا تُنشر شهادات أو وعود بمستوى الخدمة قبل وجود وثائق معتمدة. أثناء التقييم، اطلب إجابات محددة حول الضوابط المهمة لنشاطك.",
|
||||
"checks": [
|
||||
[
|
||||
"التحكم في الوصول",
|
||||
"الأدوار والصلاحيات وإجراءات المسؤول وإنهاء وصول المستخدم."
|
||||
],
|
||||
[
|
||||
"قابلية التدقيق",
|
||||
"التغييرات المسجلة والقابلة للبحث والتصدير."
|
||||
],
|
||||
[
|
||||
"معالجة البيانات",
|
||||
"الملكية والاحتفاظ والتصدير والحذف والجهات الفرعية."
|
||||
],
|
||||
[
|
||||
"استمرارية العمل",
|
||||
"النسخ الاحتياطي والاستعادة والتواصل عند الحوادث والدعم."
|
||||
]
|
||||
]
|
||||
},
|
||||
"pricing": {
|
||||
"eyebrow": "معاينة التسعير",
|
||||
"title": "يجب أن يعكس التسعير طبيعة التشغيل الفعلية.",
|
||||
"body": "لا يُعرض سعر عام قبل اعتماد النموذج التجاري والحدود المشمولة. يبدأ التقييم بالعوامل التي تؤثر فعلًا في النطاق.",
|
||||
"factors": [
|
||||
"حجم الأسطول وعدد المواقع النشطة",
|
||||
"الوحدات المطلوبة وأدوار المستخدمين",
|
||||
"نطاق ترحيل البيانات والتهيئة",
|
||||
"متطلبات التكامل والدعم"
|
||||
],
|
||||
"primary": "اطلب عرض سعر",
|
||||
"note": "لا تنشر هذه النسخة أسعار بطاقات أو خصومات أو حدود باقات."
|
||||
},
|
||||
"faq": {
|
||||
"eyebrow": "الأسئلة الشائعة",
|
||||
"title": "أسئلة ينبغي للمشتري طرحها قبل حجز العرض التوضيحي.",
|
||||
"items": [
|
||||
[
|
||||
"هل homePageCar مخصص فقط لشركات التأجير الكبيرة؟",
|
||||
"لا يزال السوق المستهدف وهيكل الباقات قيد الاعتماد. يجب أن يحدد العرض حجم الأسطول والمواقع وسير العمل والوحدات المطلوبة بدل افتراض أن إعدادًا واحدًا يناسب الجميع."
|
||||
],
|
||||
[
|
||||
"هل يمكننا الاحتفاظ بأنظمتنا الحالية؟",
|
||||
"تُراجع التكاملات المحتملة خلال الاستكشاف. يجب تأكيد توافر الموصل وملكية البيانات وجهد الترحيل والمزامنة المستمرة قبل تقديم أي وعد."
|
||||
],
|
||||
[
|
||||
"هل تدعم المنصة لغات متعددة؟",
|
||||
"يدعم الموقع ونظام التصميم المعتمد الإنجليزية والفرنسية والعربية. تستخدم العربية اتجاهًا حقيقيًا للمستند من اليمين إلى اليسار، لا مجرد محاذاة شكلية."
|
||||
],
|
||||
[
|
||||
"كيف يُحسب السعر؟",
|
||||
"النموذج التجاري قيد الاعتماد. حتى ذلك الحين، يجب أن يوضح كل عرض النطاق والوحدات والحدود والتهيئة والتكاملات والدعم."
|
||||
],
|
||||
[
|
||||
"ما الشهادات الأمنية المتوفرة؟",
|
||||
"لا تدّعي هذه النسخة وجود أي شهادة. يجب تقديم الأدلة الأمنية عبر وثائق معتمدة أثناء التقييم وعدم نشرها إلا بعد التحقق."
|
||||
],
|
||||
[
|
||||
"ماذا يحدث أثناء العرض التوضيحي؟",
|
||||
"ينبغي أن ترسم الجلسة سير عملك من الحجز حتى الإرجاع، وتعرض المسار المناسب في المنتج، وتحدد احتياجات التكامل، وتوثق أسئلة الملاءمة غير المحسومة."
|
||||
]
|
||||
]
|
||||
},
|
||||
"final": {
|
||||
"eyebrow": "شاهد سير العمل كاملًا",
|
||||
"title": "أحضر عملية تأجير حقيقية إلى العرض التوضيحي.",
|
||||
"body": "سنتتبع عمليات التسليم والاستثناءات والمعلومات التي يحتاجها فريقك من الحجز حتى إعادة المركبة.",
|
||||
"primary": "احجز عرضًا توضيحيًا للمنتج",
|
||||
"secondary": "تواصل مع المبيعات"
|
||||
},
|
||||
"footer": {
|
||||
"tagline": "تشغيل مترابط لتأجير السيارات من الحجز حتى الإرجاع.",
|
||||
"groups": [
|
||||
[
|
||||
"المنتج",
|
||||
[
|
||||
[
|
||||
"سير العمل",
|
||||
"#workflow"
|
||||
],
|
||||
[
|
||||
"الوحدات",
|
||||
"#modules"
|
||||
],
|
||||
[
|
||||
"التسعير",
|
||||
"#pricing"
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
"الشركة",
|
||||
[
|
||||
[
|
||||
"تواصل مع المبيعات",
|
||||
"#contact"
|
||||
],
|
||||
[
|
||||
"احجز عرضًا توضيحيًا",
|
||||
"#demo"
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
"الحساب",
|
||||
[
|
||||
[
|
||||
"تسجيل الدخول",
|
||||
"#login"
|
||||
],
|
||||
[
|
||||
"اللغة",
|
||||
"#language"
|
||||
],
|
||||
[
|
||||
"المظهر",
|
||||
"#theme"
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
"قانوني",
|
||||
[
|
||||
[
|
||||
"الخصوصية",
|
||||
"#!"
|
||||
],
|
||||
[
|
||||
"الشروط",
|
||||
"#!"
|
||||
],
|
||||
[
|
||||
"إمكانية الوصول",
|
||||
"#!"
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
"copyright": "© 2026 homePageCar. تظل الأدلة والادعاءات التجارية خاضعة للاعتماد."
|
||||
},
|
||||
"form": {
|
||||
"title": "احجز عرضًا توضيحيًا للمنتج",
|
||||
"body": "أخبرنا كيف يعمل نشاط تأجير السيارات لديك. الحقول المطلوبة مميزة.",
|
||||
"name": "الاسم الكامل",
|
||||
"email": "البريد الإلكتروني للعمل",
|
||||
"company": "الشركة",
|
||||
"fleet": "الحجم التقريبي للأسطول",
|
||||
"market": "الدولة أو سوق التشغيل",
|
||||
"language": "لغة العرض المفضلة",
|
||||
"message": "ما الموضوع الذي ينبغي أن يركز عليه العرض؟",
|
||||
"submit": "إرسال طلب العرض",
|
||||
"privacy": "بإرسال النموذج، فإنك توافق على التواصل معك بخصوص هذا الطلب. يحتاج نص إشعار الخصوصية إلى اعتماد قانوني.",
|
||||
"close": "إغلاق",
|
||||
"required": "مطلوب",
|
||||
"emailError": "أدخل عنوان بريد إلكتروني صالحًا للعمل.",
|
||||
"requiredError": "هذا الحقل مطلوب.",
|
||||
"fleetOptions": [
|
||||
"اختر خيارًا",
|
||||
"من 1 إلى 25 مركبة",
|
||||
"من 26 إلى 100 مركبة",
|
||||
"من 101 إلى 500 مركبة",
|
||||
"أكثر من 500 مركبة",
|
||||
"غير متأكد بعد"
|
||||
],
|
||||
"langOptions": [
|
||||
"English",
|
||||
"Français",
|
||||
"العربية"
|
||||
],
|
||||
"successTitle": "تم تسجيل طلب العرض",
|
||||
"successBody": "اكتمل مسار الحجز في هذا النموذج الأولي. لم يُرسل أي طلب إلى نظام مبيعات فعلي.",
|
||||
"submitAnother": "إرسال طلب آخر",
|
||||
"submissionError": "تعذر على النموذج الأولي إكمال الطلب. ما زالت بياناتك متاحة. حاول مرة أخرى.",
|
||||
"errorSummary": "راجع الحقول المميزة ثم حاول مرة أخرى."
|
||||
},
|
||||
"preview": {
|
||||
"today": "اليوم",
|
||||
"branch": "الفرع المركزي",
|
||||
"title": "نظرة عامة على التشغيل",
|
||||
"reservations": "الحجوزات",
|
||||
"ready": "مركبات جاهزة",
|
||||
"attention": "تحتاج متابعة",
|
||||
"active": "عمليات تأجير نشطة",
|
||||
"r1": "تسليم الساعة 10:30",
|
||||
"r2": "إرجاع مستحق الساعة 14:00",
|
||||
"r3": "الفحص مطلوب",
|
||||
"vehicle": "المركبة",
|
||||
"customer": "العميل",
|
||||
"status": "الحالة",
|
||||
"task": "الإجراء التالي",
|
||||
"plate1": "ABC-2048",
|
||||
"plate2": "RNT-7712",
|
||||
"statusReady": "جاهزة",
|
||||
"statusDue": "مستحقة اليوم",
|
||||
"taskAssign": "تأكيد مستندات السائق",
|
||||
"taskInspect": "إكمال فحص الإرجاع"
|
||||
},
|
||||
"tour": {
|
||||
"title": "جولة في المنتج",
|
||||
"intro": "تابع عملية تأجير واحدة من الحجز حتى الإرجاع.",
|
||||
"back": "السابق",
|
||||
"next": "التالي",
|
||||
"finish": "إنهاء الجولة",
|
||||
"close": "إغلاق جولة المنتج",
|
||||
"step": "الخطوة",
|
||||
"of": "من"
|
||||
},
|
||||
"research": {
|
||||
"title": "وضع البحث",
|
||||
"events": "أحداث",
|
||||
"export": "تصدير الأحداث",
|
||||
"clear": "مسح",
|
||||
"close": "إغلاق"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,430 @@
|
||||
{
|
||||
"meta": {
|
||||
"langName": "English",
|
||||
"dir": "ltr",
|
||||
"title": "homePageCar | Connected rental-car operations",
|
||||
"description": "Run reservations, vehicles, agreements, handovers, and returns in one connected rental operations platform."
|
||||
},
|
||||
"header": {
|
||||
"nav": [
|
||||
[
|
||||
"product",
|
||||
"Product"
|
||||
],
|
||||
[
|
||||
"workflow",
|
||||
"Workflow"
|
||||
],
|
||||
[
|
||||
"modules",
|
||||
"Modules"
|
||||
],
|
||||
[
|
||||
"pricing",
|
||||
"Pricing"
|
||||
],
|
||||
[
|
||||
"faq",
|
||||
"FAQ"
|
||||
]
|
||||
],
|
||||
"login": "Log in",
|
||||
"demo": "Book a demo",
|
||||
"menu": "Open menu",
|
||||
"language": "Language",
|
||||
"theme": "Theme",
|
||||
"light": "Light",
|
||||
"dark": "Dark",
|
||||
"system": "System"
|
||||
},
|
||||
"hero": {
|
||||
"eyebrow": "Rental operations, connected",
|
||||
"title": "Run every rental from reservation to return in one system.",
|
||||
"body": "Give reservations, fleet, agreements, handovers, and returns one operational record, so each team sees what needs attention next.",
|
||||
"primary": "Book a product demo",
|
||||
"secondary": "Watch product tour",
|
||||
"caption": "Illustrative product interface. Final screens must use approved product data and captures."
|
||||
},
|
||||
"trust": {
|
||||
"eyebrow": "Operational coverage",
|
||||
"title": "One workflow across the rental lifecycle.",
|
||||
"body": "Keep the customer, vehicle, agreement, and task context connected as the rental moves forward.",
|
||||
"items": [
|
||||
[
|
||||
"Reservation",
|
||||
"Capture the request and required details."
|
||||
],
|
||||
[
|
||||
"Vehicle",
|
||||
"Track availability and readiness."
|
||||
],
|
||||
[
|
||||
"Agreement",
|
||||
"Keep pickup tasks and records together."
|
||||
],
|
||||
[
|
||||
"Return",
|
||||
"Record condition and close follow-up work."
|
||||
]
|
||||
]
|
||||
},
|
||||
"comparison": {
|
||||
"eyebrow": "Why change",
|
||||
"title": "Replace fragmented handoffs with a shared operating flow.",
|
||||
"body": "The cost of disconnected tools is rarely one dramatic failure. It is the daily accumulation of duplicate entry, missing context, and delayed follow-up.",
|
||||
"beforeTitle": "Fragmented operation",
|
||||
"beforeItems": [
|
||||
"Reservation details copied between tools",
|
||||
"Vehicle status confirmed through messages",
|
||||
"Agreement tasks tracked from memory",
|
||||
"Return issues discovered after the customer leaves"
|
||||
],
|
||||
"afterTitle": "Connected operation",
|
||||
"afterItems": [
|
||||
"One reservation status visible to the team",
|
||||
"Vehicle readiness attached to the rental",
|
||||
"Pickup requirements shown before handover",
|
||||
"Return follow-up created while context is fresh"
|
||||
]
|
||||
},
|
||||
"workflow": {
|
||||
"eyebrow": "End-to-end workflow",
|
||||
"title": "Move the rental forward without losing the thread.",
|
||||
"body": "Each step exposes the decision, owner, and next action instead of burying operations inside a generic feature list.",
|
||||
"steps": [
|
||||
[
|
||||
"01",
|
||||
"Capture the reservation",
|
||||
"Record dates, driver details, requirements, and source."
|
||||
],
|
||||
[
|
||||
"02",
|
||||
"Assign a ready vehicle",
|
||||
"Match availability with class, location, and readiness."
|
||||
],
|
||||
[
|
||||
"03",
|
||||
"Complete pickup",
|
||||
"Confirm documents, inspection, agreement, and handover tasks."
|
||||
],
|
||||
[
|
||||
"04",
|
||||
"Process the return",
|
||||
"Record condition, close open work, and release the vehicle."
|
||||
]
|
||||
]
|
||||
},
|
||||
"roles": {
|
||||
"eyebrow": "Built for the operating team",
|
||||
"title": "Give each role the context it needs, without creating separate versions of the truth.",
|
||||
"roles": [
|
||||
[
|
||||
"Owner or manager",
|
||||
"See workload, exceptions, and operating signals across the business."
|
||||
],
|
||||
[
|
||||
"Reservations team",
|
||||
"Move requests from inquiry to confirmed rental with fewer handoffs."
|
||||
],
|
||||
[
|
||||
"Fleet and operations",
|
||||
"Know which vehicles are available, blocked, due, or awaiting action."
|
||||
],
|
||||
[
|
||||
"Front desk",
|
||||
"Prepare pickup and return tasks before the customer is waiting."
|
||||
]
|
||||
]
|
||||
},
|
||||
"modules": {
|
||||
"eyebrow": "Product modules",
|
||||
"title": "A connected core, organized around real rental work.",
|
||||
"body": "Module boundaries clarify responsibility while shared records prevent the usual copy-and-paste archaeology.",
|
||||
"items": [
|
||||
[
|
||||
"Reservations",
|
||||
"Availability, dates, customer requirements, and status in one flow."
|
||||
],
|
||||
[
|
||||
"Fleet readiness",
|
||||
"Vehicle availability, blocks, service state, and location context."
|
||||
],
|
||||
[
|
||||
"Rental agreements",
|
||||
"Pickup requirements, agreement status, and operational records."
|
||||
],
|
||||
[
|
||||
"Vehicle inspections",
|
||||
"Structured pickup and return condition checks with follow-up tasks."
|
||||
],
|
||||
[
|
||||
"Customer records",
|
||||
"Rental history and contact context attached to active work."
|
||||
],
|
||||
[
|
||||
"Operations reporting",
|
||||
"Definitions and operational views that can be validated against source activity."
|
||||
]
|
||||
]
|
||||
},
|
||||
"results": {
|
||||
"eyebrow": "Measured results",
|
||||
"title": "Measure the change, not the marketing.",
|
||||
"body": "No outcome claim should appear until a real customer baseline, comparison period, and data definition are approved. The production page therefore shows the measurement plan instead of fictional percentages.",
|
||||
"metrics": [
|
||||
[
|
||||
"Reservation handling time",
|
||||
"From usable request to confirmed reservation."
|
||||
],
|
||||
[
|
||||
"Vehicle turnaround time",
|
||||
"From return recorded to ready-for-rental status."
|
||||
],
|
||||
[
|
||||
"Fleet utilization",
|
||||
"Available rental days compared with rented days, using one approved definition."
|
||||
],
|
||||
[
|
||||
"Overdue follow-up",
|
||||
"Open overdue rentals with an assigned owner and next action."
|
||||
]
|
||||
],
|
||||
"methodTitle": "Methodology required before publishing results",
|
||||
"method": [
|
||||
"Capture a pre-launch baseline using the same KPI definitions.",
|
||||
"Compare equivalent locations, fleet classes, and operating periods.",
|
||||
"Report sample size, exclusions, and measurement window.",
|
||||
"Link every public result to an approved evidence record."
|
||||
]
|
||||
},
|
||||
"integrations": {
|
||||
"eyebrow": "Integrations",
|
||||
"title": "Connect the systems your operation already depends on.",
|
||||
"body": "Integration scope is confirmed during discovery so the proposal reflects your market, current stack, and data ownership. Named partners are not shown until connector availability is verified.",
|
||||
"items": [
|
||||
"Accounting and finance",
|
||||
"Payments and deposits",
|
||||
"Telematics and vehicle data",
|
||||
"Identity and document services",
|
||||
"Email, SMS, and notifications",
|
||||
"Website and booking channels"
|
||||
]
|
||||
},
|
||||
"security": {
|
||||
"eyebrow": "Security and reliability",
|
||||
"title": "Evaluate the platform with evidence, not badges.",
|
||||
"body": "Certifications and service-level claims remain unpublished until approved documentation exists. During evaluation, request concrete answers for the controls that matter to your operation.",
|
||||
"checks": [
|
||||
[
|
||||
"Access control",
|
||||
"Roles, permissions, administrator actions, and offboarding."
|
||||
],
|
||||
[
|
||||
"Auditability",
|
||||
"Which changes are recorded, searchable, and exportable."
|
||||
],
|
||||
[
|
||||
"Data handling",
|
||||
"Ownership, retention, export, deletion, and subprocessors."
|
||||
],
|
||||
[
|
||||
"Continuity",
|
||||
"Backup, recovery, incident communication, and support process."
|
||||
]
|
||||
]
|
||||
},
|
||||
"pricing": {
|
||||
"eyebrow": "Pricing preview",
|
||||
"title": "Pricing should match the operation you actually run.",
|
||||
"body": "A public price is not shown until the commercial model and included limits are approved. The evaluation starts with the factors that materially affect scope.",
|
||||
"factors": [
|
||||
"Fleet size and active locations",
|
||||
"Required modules and user roles",
|
||||
"Migration and onboarding scope",
|
||||
"Integration and support requirements"
|
||||
],
|
||||
"primary": "Request pricing",
|
||||
"note": "No card prices, discounts, or package limits are published in this baseline."
|
||||
},
|
||||
"faq": {
|
||||
"eyebrow": "FAQ",
|
||||
"title": "Questions buyers should ask before booking a demo.",
|
||||
"items": [
|
||||
[
|
||||
"Is homePageCar only for large rental companies?",
|
||||
"The final market and packaging are still being defined. The demo should qualify fleet size, locations, workflows, and required modules rather than pretend one setup fits everyone."
|
||||
],
|
||||
[
|
||||
"Can we keep our existing systems?",
|
||||
"Potential integrations are reviewed during discovery. Connector availability, data ownership, migration effort, and ongoing synchronization must be confirmed before they are promised."
|
||||
],
|
||||
[
|
||||
"Does the platform support multiple languages?",
|
||||
"The website and approved design system support English, French, and Arabic. Arabic uses true document-level right-to-left behavior rather than a mirrored-looking patch."
|
||||
],
|
||||
[
|
||||
"How is pricing calculated?",
|
||||
"The commercial model is pending approval. Until then, proposals should state the scope, included modules, limits, onboarding, integrations, and support explicitly."
|
||||
],
|
||||
[
|
||||
"What security certifications do you have?",
|
||||
"No certification is claimed in this baseline. Security evidence should be supplied through approved documentation during evaluation and published only after verification."
|
||||
],
|
||||
[
|
||||
"What happens during the demo?",
|
||||
"The session should map your current reservation-to-return flow, show the relevant product path, identify integration needs, and document unresolved fit questions."
|
||||
]
|
||||
]
|
||||
},
|
||||
"final": {
|
||||
"eyebrow": "See the full workflow",
|
||||
"title": "Bring one real rental process to the demo.",
|
||||
"body": "We will trace the handoffs, exceptions, and information your team needs from reservation through vehicle return.",
|
||||
"primary": "Book a product demo",
|
||||
"secondary": "Contact sales"
|
||||
},
|
||||
"footer": {
|
||||
"tagline": "Connected rental-car operations from reservation to return.",
|
||||
"groups": [
|
||||
[
|
||||
"Product",
|
||||
[
|
||||
[
|
||||
"Workflow",
|
||||
"#workflow"
|
||||
],
|
||||
[
|
||||
"Modules",
|
||||
"#modules"
|
||||
],
|
||||
[
|
||||
"Pricing",
|
||||
"#pricing"
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
"Company",
|
||||
[
|
||||
[
|
||||
"Contact sales",
|
||||
"#contact"
|
||||
],
|
||||
[
|
||||
"Book a demo",
|
||||
"#demo"
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
"Account",
|
||||
[
|
||||
[
|
||||
"Log in",
|
||||
"#login"
|
||||
],
|
||||
[
|
||||
"Language",
|
||||
"#language"
|
||||
],
|
||||
[
|
||||
"Theme",
|
||||
"#theme"
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
"Legal",
|
||||
[
|
||||
[
|
||||
"Privacy",
|
||||
"#!"
|
||||
],
|
||||
[
|
||||
"Terms",
|
||||
"#!"
|
||||
],
|
||||
[
|
||||
"Accessibility",
|
||||
"#!"
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
"copyright": "© 2026 homePageCar. Evidence and commercial claims remain subject to approval."
|
||||
},
|
||||
"form": {
|
||||
"title": "Book a product demo",
|
||||
"body": "Tell us how your rental operation works. Required fields are marked.",
|
||||
"name": "Full name",
|
||||
"email": "Work email",
|
||||
"company": "Company",
|
||||
"fleet": "Approximate fleet size",
|
||||
"market": "Country or operating market",
|
||||
"language": "Preferred demo language",
|
||||
"message": "What should the demo focus on?",
|
||||
"submit": "Request my demo",
|
||||
"privacy": "By submitting, you agree to be contacted about this request. Privacy notice text requires legal approval.",
|
||||
"close": "Close",
|
||||
"required": "Required",
|
||||
"emailError": "Enter a valid work email address.",
|
||||
"requiredError": "This field is required.",
|
||||
"fleetOptions": [
|
||||
"Select an option",
|
||||
"1–25 vehicles",
|
||||
"26–100 vehicles",
|
||||
"101–500 vehicles",
|
||||
"More than 500 vehicles",
|
||||
"Not sure yet"
|
||||
],
|
||||
"langOptions": [
|
||||
"English",
|
||||
"Français",
|
||||
"العربية"
|
||||
],
|
||||
"successTitle": "Demo request recorded",
|
||||
"successBody": "This prototype has completed the booking flow. No request was sent to a real sales system.",
|
||||
"submitAnother": "Submit another request",
|
||||
"submissionError": "The prototype could not complete the request. Your entries are still available. Try again.",
|
||||
"errorSummary": "Review the highlighted fields and try again."
|
||||
},
|
||||
"preview": {
|
||||
"today": "Today",
|
||||
"branch": "Central branch",
|
||||
"title": "Operations overview",
|
||||
"reservations": "Reservations",
|
||||
"ready": "Vehicles ready",
|
||||
"attention": "Needs attention",
|
||||
"active": "Active rentals",
|
||||
"r1": "Pickup at 10:30",
|
||||
"r2": "Return due at 14:00",
|
||||
"r3": "Inspection required",
|
||||
"vehicle": "Vehicle",
|
||||
"customer": "Customer",
|
||||
"status": "Status",
|
||||
"task": "Next action",
|
||||
"plate1": "ABC-2048",
|
||||
"plate2": "RNT-7712",
|
||||
"statusReady": "Ready",
|
||||
"statusDue": "Due today",
|
||||
"taskAssign": "Confirm driver documents",
|
||||
"taskInspect": "Complete return inspection"
|
||||
},
|
||||
"tour": {
|
||||
"title": "Product tour",
|
||||
"intro": "Follow one rental from reservation through return.",
|
||||
"back": "Previous",
|
||||
"next": "Next",
|
||||
"finish": "Finish tour",
|
||||
"close": "Close product tour",
|
||||
"step": "Step",
|
||||
"of": "of"
|
||||
},
|
||||
"research": {
|
||||
"title": "Research mode",
|
||||
"events": "events",
|
||||
"export": "Export events",
|
||||
"clear": "Clear",
|
||||
"close": "Close"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,430 @@
|
||||
{
|
||||
"meta": {
|
||||
"langName": "Français",
|
||||
"dir": "ltr",
|
||||
"title": "homePageCar | Opérations de location connectées",
|
||||
"description": "Pilotez les réservations, véhicules, contrats, remises et retours dans une plateforme connectée."
|
||||
},
|
||||
"header": {
|
||||
"nav": [
|
||||
[
|
||||
"product",
|
||||
"Produit"
|
||||
],
|
||||
[
|
||||
"workflow",
|
||||
"Parcours"
|
||||
],
|
||||
[
|
||||
"modules",
|
||||
"Modules"
|
||||
],
|
||||
[
|
||||
"pricing",
|
||||
"Tarifs"
|
||||
],
|
||||
[
|
||||
"faq",
|
||||
"FAQ"
|
||||
]
|
||||
],
|
||||
"login": "Se connecter",
|
||||
"demo": "Réserver une démo",
|
||||
"menu": "Ouvrir le menu",
|
||||
"language": "Langue",
|
||||
"theme": "Thème",
|
||||
"light": "Clair",
|
||||
"dark": "Sombre",
|
||||
"system": "Système"
|
||||
},
|
||||
"hero": {
|
||||
"eyebrow": "Opérations de location connectées",
|
||||
"title": "Pilotez chaque location, de la réservation au retour du véhicule, dans un seul système.",
|
||||
"body": "Reliez les réservations, le parc, les contrats, les remises et les retours dans un même dossier opérationnel, afin que chaque équipe sache quelle action vient ensuite.",
|
||||
"primary": "Réserver une démonstration",
|
||||
"secondary": "Voir la visite du produit",
|
||||
"caption": "Interface produit illustrative. Les écrans définitifs doivent utiliser des données et captures approuvées."
|
||||
},
|
||||
"trust": {
|
||||
"eyebrow": "Couverture opérationnelle",
|
||||
"title": "Un même parcours pour tout le cycle de location.",
|
||||
"body": "Conservez le contexte du client, du véhicule, du contrat et des tâches au fil de la location.",
|
||||
"items": [
|
||||
[
|
||||
"Réservation",
|
||||
"Saisir la demande et les informations nécessaires."
|
||||
],
|
||||
[
|
||||
"Véhicule",
|
||||
"Suivre la disponibilité et l’état de préparation."
|
||||
],
|
||||
[
|
||||
"Contrat",
|
||||
"Regrouper les tâches de départ et les documents."
|
||||
],
|
||||
[
|
||||
"Retour",
|
||||
"Enregistrer l’état et clôturer les actions de suivi."
|
||||
]
|
||||
]
|
||||
},
|
||||
"comparison": {
|
||||
"eyebrow": "Pourquoi changer",
|
||||
"title": "Remplacez les transmissions fragmentées par un flux opérationnel partagé.",
|
||||
"body": "Le coût des outils déconnectés n’est pas toujours une panne spectaculaire. Il s’accumule dans les doubles saisies, le contexte perdu et les suivis tardifs.",
|
||||
"beforeTitle": "Fonctionnement fragmenté",
|
||||
"beforeItems": [
|
||||
"Informations de réservation recopiées entre plusieurs outils",
|
||||
"État du véhicule confirmé par messages",
|
||||
"Tâches contractuelles suivies de mémoire",
|
||||
"Problèmes de retour découverts après le départ du client"
|
||||
],
|
||||
"afterTitle": "Fonctionnement connecté",
|
||||
"afterItems": [
|
||||
"Un statut de réservation visible par l’équipe",
|
||||
"Préparation du véhicule rattachée à la location",
|
||||
"Exigences de départ affichées avant la remise",
|
||||
"Suivi du retour créé pendant que le contexte est encore précis"
|
||||
]
|
||||
},
|
||||
"workflow": {
|
||||
"eyebrow": "Parcours de bout en bout",
|
||||
"title": "Faites avancer la location sans perdre le fil.",
|
||||
"body": "Chaque étape met en évidence la décision, le responsable et l’action suivante, au lieu d’enfouir le travail dans une liste générique de fonctionnalités.",
|
||||
"steps": [
|
||||
[
|
||||
"01",
|
||||
"Saisir la réservation",
|
||||
"Enregistrer les dates, le conducteur, les exigences et la source."
|
||||
],
|
||||
[
|
||||
"02",
|
||||
"Affecter un véhicule prêt",
|
||||
"Faire correspondre disponibilité, catégorie, agence et état de préparation."
|
||||
],
|
||||
[
|
||||
"03",
|
||||
"Finaliser le départ",
|
||||
"Confirmer documents, inspection, contrat et tâches de remise."
|
||||
],
|
||||
[
|
||||
"04",
|
||||
"Traiter le retour",
|
||||
"Enregistrer l’état, clôturer les actions et libérer le véhicule."
|
||||
]
|
||||
]
|
||||
},
|
||||
"roles": {
|
||||
"eyebrow": "Conçu pour l’équipe opérationnelle",
|
||||
"title": "Donnez à chaque rôle le contexte utile, sans multiplier les versions de la vérité.",
|
||||
"roles": [
|
||||
[
|
||||
"Direction ou responsable",
|
||||
"Voir la charge, les exceptions et les signaux d’exploitation."
|
||||
],
|
||||
[
|
||||
"Équipe réservations",
|
||||
"Faire passer les demandes vers une location confirmée avec moins de transmissions."
|
||||
],
|
||||
[
|
||||
"Parc et opérations",
|
||||
"Savoir quels véhicules sont disponibles, bloqués, attendus ou en attente d’action."
|
||||
],
|
||||
[
|
||||
"Comptoir",
|
||||
"Préparer les tâches de départ et de retour avant que le client n’attende."
|
||||
]
|
||||
]
|
||||
},
|
||||
"modules": {
|
||||
"eyebrow": "Modules produit",
|
||||
"title": "Un socle connecté, organisé autour du travail réel de location.",
|
||||
"body": "Les modules clarifient les responsabilités, tandis que les dossiers partagés évitent l’archéologie du copier-coller.",
|
||||
"items": [
|
||||
[
|
||||
"Réservations",
|
||||
"Disponibilités, dates, besoins du client et statut dans un même flux."
|
||||
],
|
||||
[
|
||||
"Préparation du parc",
|
||||
"Disponibilité, blocages, état de service et contexte d’agence."
|
||||
],
|
||||
[
|
||||
"Contrats de location",
|
||||
"Exigences de départ, état du contrat et dossiers opérationnels."
|
||||
],
|
||||
[
|
||||
"Inspections des véhicules",
|
||||
"Contrôles structurés au départ et au retour avec actions de suivi."
|
||||
],
|
||||
[
|
||||
"Dossiers clients",
|
||||
"Historique de location et coordonnées rattachés au travail en cours."
|
||||
],
|
||||
[
|
||||
"Rapports opérationnels",
|
||||
"Définitions et vues vérifiables par rapport à l’activité source."
|
||||
]
|
||||
]
|
||||
},
|
||||
"results": {
|
||||
"eyebrow": "Résultats mesurés",
|
||||
"title": "Mesurez le changement, pas le discours commercial.",
|
||||
"body": "Aucun résultat ne doit être publié sans référence client, période de comparaison et définition de données approuvées. Cette version présente donc la méthode plutôt que des pourcentages fictifs.",
|
||||
"metrics": [
|
||||
[
|
||||
"Temps de traitement des réservations",
|
||||
"De la demande exploitable à la réservation confirmée."
|
||||
],
|
||||
[
|
||||
"Temps de remise en service",
|
||||
"Du retour enregistré au statut prêt à louer."
|
||||
],
|
||||
[
|
||||
"Taux d’utilisation du parc",
|
||||
"Jours louables comparés aux jours loués, selon une définition approuvée."
|
||||
],
|
||||
[
|
||||
"Suivi des retards",
|
||||
"Locations en retard avec responsable et prochaine action."
|
||||
]
|
||||
],
|
||||
"methodTitle": "Méthode requise avant toute publication",
|
||||
"method": [
|
||||
"Établir une référence avant lancement avec les mêmes définitions de KPI.",
|
||||
"Comparer des agences, catégories de parc et périodes équivalentes.",
|
||||
"Publier la taille de l’échantillon, les exclusions et la fenêtre de mesure.",
|
||||
"Relier chaque résultat public à une preuve approuvée."
|
||||
]
|
||||
},
|
||||
"integrations": {
|
||||
"eyebrow": "Intégrations",
|
||||
"title": "Reliez les systèmes dont votre exploitation dépend déjà.",
|
||||
"body": "Le périmètre d’intégration est confirmé pendant la découverte afin de refléter votre marché, votre environnement actuel et la propriété des données. Aucun partenaire n’est nommé avant vérification du connecteur.",
|
||||
"items": [
|
||||
"Comptabilité et finance",
|
||||
"Paiements et dépôts",
|
||||
"Télématique et données véhicules",
|
||||
"Identité et documents",
|
||||
"E-mail, SMS et notifications",
|
||||
"Site web et canaux de réservation"
|
||||
]
|
||||
},
|
||||
"security": {
|
||||
"eyebrow": "Sécurité et fiabilité",
|
||||
"title": "Évaluez la plateforme avec des preuves, pas avec des badges.",
|
||||
"body": "Aucune certification ni promesse de niveau de service n’est publiée sans documentation approuvée. Pendant l’évaluation, demandez des réponses concrètes sur les contrôles utiles à votre activité.",
|
||||
"checks": [
|
||||
[
|
||||
"Contrôle des accès",
|
||||
"Rôles, autorisations, actions administrateur et départs."
|
||||
],
|
||||
[
|
||||
"Traçabilité",
|
||||
"Modifications enregistrées, recherchables et exportables."
|
||||
],
|
||||
[
|
||||
"Gestion des données",
|
||||
"Propriété, conservation, export, suppression et sous-traitants."
|
||||
],
|
||||
[
|
||||
"Continuité",
|
||||
"Sauvegarde, reprise, communication d’incident et support."
|
||||
]
|
||||
]
|
||||
},
|
||||
"pricing": {
|
||||
"eyebrow": "Aperçu des tarifs",
|
||||
"title": "Le tarif doit correspondre à l’exploitation que vous gérez réellement.",
|
||||
"body": "Aucun prix public n’est affiché tant que le modèle commercial et les limites incluses ne sont pas approuvés. L’évaluation commence par les facteurs qui influencent réellement le périmètre.",
|
||||
"factors": [
|
||||
"Taille du parc et agences actives",
|
||||
"Modules requis et rôles utilisateurs",
|
||||
"Migration et accompagnement au démarrage",
|
||||
"Intégrations et niveau de support"
|
||||
],
|
||||
"primary": "Demander un tarif",
|
||||
"note": "Aucun prix, remise ou plafond de forfait n’est publié dans cette version."
|
||||
},
|
||||
"faq": {
|
||||
"eyebrow": "FAQ",
|
||||
"title": "Les questions à poser avant de réserver une démonstration.",
|
||||
"items": [
|
||||
[
|
||||
"homePageCar est-il réservé aux grands loueurs ?",
|
||||
"Le marché cible et les offres finales restent à définir. La démonstration doit qualifier la taille du parc, les agences, les flux et les modules nécessaires au lieu de prétendre qu’une configuration convient à tous."
|
||||
],
|
||||
[
|
||||
"Pouvons-nous conserver nos systèmes actuels ?",
|
||||
"Les intégrations possibles sont examinées pendant la découverte. La disponibilité du connecteur, la propriété des données, l’effort de migration et la synchronisation doivent être confirmés avant toute promesse."
|
||||
],
|
||||
[
|
||||
"La plateforme prend-elle en charge plusieurs langues ?",
|
||||
"Le site et le système de design approuvé prennent en charge l’anglais, le français et l’arabe. L’arabe utilise une vraie direction de document de droite à gauche."
|
||||
],
|
||||
[
|
||||
"Comment les tarifs sont-ils calculés ?",
|
||||
"Le modèle commercial est en attente d’approbation. En attendant, toute proposition doit préciser le périmètre, les modules, les limites, l’accompagnement, les intégrations et le support."
|
||||
],
|
||||
[
|
||||
"Quelles certifications de sécurité possédez-vous ?",
|
||||
"Aucune certification n’est revendiquée dans cette version. Les preuves de sécurité doivent être fournies pendant l’évaluation puis publiées uniquement après vérification."
|
||||
],
|
||||
[
|
||||
"Que se passe-t-il pendant la démonstration ?",
|
||||
"La session doit cartographier votre flux de la réservation au retour, montrer le parcours produit pertinent, identifier les intégrations et consigner les questions de compatibilité non résolues."
|
||||
]
|
||||
]
|
||||
},
|
||||
"final": {
|
||||
"eyebrow": "Voir le parcours complet",
|
||||
"title": "Apportez un processus de location réel à la démonstration.",
|
||||
"body": "Nous suivrons les transmissions, les exceptions et les informations dont votre équipe a besoin de la réservation au retour du véhicule.",
|
||||
"primary": "Réserver une démonstration",
|
||||
"secondary": "Contacter le service commercial"
|
||||
},
|
||||
"footer": {
|
||||
"tagline": "Des opérations de location connectées, de la réservation au retour.",
|
||||
"groups": [
|
||||
[
|
||||
"Produit",
|
||||
[
|
||||
[
|
||||
"Parcours",
|
||||
"#workflow"
|
||||
],
|
||||
[
|
||||
"Modules",
|
||||
"#modules"
|
||||
],
|
||||
[
|
||||
"Tarifs",
|
||||
"#pricing"
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
"Entreprise",
|
||||
[
|
||||
[
|
||||
"Contacter le service commercial",
|
||||
"#contact"
|
||||
],
|
||||
[
|
||||
"Réserver une démo",
|
||||
"#demo"
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
"Compte",
|
||||
[
|
||||
[
|
||||
"Se connecter",
|
||||
"#login"
|
||||
],
|
||||
[
|
||||
"Langue",
|
||||
"#language"
|
||||
],
|
||||
[
|
||||
"Thème",
|
||||
"#theme"
|
||||
]
|
||||
]
|
||||
],
|
||||
[
|
||||
"Mentions légales",
|
||||
[
|
||||
[
|
||||
"Confidentialité",
|
||||
"#!"
|
||||
],
|
||||
[
|
||||
"Conditions",
|
||||
"#!"
|
||||
],
|
||||
[
|
||||
"Accessibilité",
|
||||
"#!"
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
"copyright": "© 2026 homePageCar. Les preuves et conditions commerciales restent soumises à approbation."
|
||||
},
|
||||
"form": {
|
||||
"title": "Réserver une démonstration du produit",
|
||||
"body": "Décrivez-nous le fonctionnement de votre activité de location. Les champs obligatoires sont signalés.",
|
||||
"name": "Nom complet",
|
||||
"email": "Adresse e-mail professionnelle",
|
||||
"company": "Entreprise",
|
||||
"fleet": "Taille approximative du parc",
|
||||
"market": "Pays ou marché d’exploitation",
|
||||
"language": "Langue souhaitée pour la démonstration",
|
||||
"message": "Sur quoi la démonstration doit-elle se concentrer ?",
|
||||
"submit": "Demander ma démonstration",
|
||||
"privacy": "En envoyant ce formulaire, vous acceptez d’être contacté au sujet de cette demande. Le texte de confidentialité nécessite une validation juridique.",
|
||||
"close": "Fermer",
|
||||
"required": "Obligatoire",
|
||||
"emailError": "Saisissez une adresse e-mail professionnelle valide.",
|
||||
"requiredError": "Ce champ est obligatoire.",
|
||||
"fleetOptions": [
|
||||
"Sélectionnez une option",
|
||||
"1 à 25 véhicules",
|
||||
"26 à 100 véhicules",
|
||||
"101 à 500 véhicules",
|
||||
"Plus de 500 véhicules",
|
||||
"Je ne sais pas encore"
|
||||
],
|
||||
"langOptions": [
|
||||
"English",
|
||||
"Français",
|
||||
"العربية"
|
||||
],
|
||||
"successTitle": "Demande de démonstration enregistrée",
|
||||
"successBody": "Ce prototype a terminé le parcours de réservation. Aucune demande n’a été envoyée à un véritable système commercial.",
|
||||
"submitAnother": "Envoyer une autre demande",
|
||||
"submissionError": "Le prototype n’a pas pu terminer la demande. Vos informations sont conservées. Réessayez.",
|
||||
"errorSummary": "Vérifiez les champs signalés, puis réessayez."
|
||||
},
|
||||
"preview": {
|
||||
"today": "Aujourd’hui",
|
||||
"branch": "Agence centrale",
|
||||
"title": "Vue des opérations",
|
||||
"reservations": "Réservations",
|
||||
"ready": "Véhicules prêts",
|
||||
"attention": "À traiter",
|
||||
"active": "Locations actives",
|
||||
"r1": "Départ à 10 h 30",
|
||||
"r2": "Retour prévu à 14 h 00",
|
||||
"r3": "Inspection requise",
|
||||
"vehicle": "Véhicule",
|
||||
"customer": "Client",
|
||||
"status": "Statut",
|
||||
"task": "Prochaine action",
|
||||
"plate1": "ABC-2048",
|
||||
"plate2": "RNT-7712",
|
||||
"statusReady": "Prêt",
|
||||
"statusDue": "Prévu aujourd’hui",
|
||||
"taskAssign": "Confirmer les documents du conducteur",
|
||||
"taskInspect": "Finaliser l’inspection de retour"
|
||||
},
|
||||
"tour": {
|
||||
"title": "Visite du produit",
|
||||
"intro": "Suivez une location de la réservation au retour.",
|
||||
"back": "Précédent",
|
||||
"next": "Suivant",
|
||||
"finish": "Terminer la visite",
|
||||
"close": "Fermer la visite du produit",
|
||||
"step": "Étape",
|
||||
"of": "sur"
|
||||
},
|
||||
"research": {
|
||||
"title": "Mode recherche",
|
||||
"events": "événements",
|
||||
"export": "Exporter les événements",
|
||||
"clear": "Effacer",
|
||||
"close": "Fermer"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
ID,Area,Check,Method,Criterion,Status
|
||||
A11Y-001,Page,One h1 and logical heading order,Automated + manual,WCAG 1.3.1,Required
|
||||
A11Y-002,Keyboard,All interactive controls reachable and operable,Manual,WCAG 2.1.1,Required
|
||||
A11Y-003,Focus,Visible focus and logical order,Manual,"WCAG 2.4.7, 2.4.11",Required
|
||||
A11Y-004,Skip link,Moves focus/viewport to main content,Manual,WCAG 2.4.1,Required
|
||||
A11Y-005,Drawer/dialog,"Containment, inert background, Escape, return focus",Manual + browser,"WCAG 2.4.3, 3.2.1",Required
|
||||
A11Y-006,Forms,"Visible labels, programmatic names, instructions",Automated + SR,"WCAG 1.3.1, 3.3.2",Required
|
||||
A11Y-007,Errors,"Summary, inline association, first invalid focus",SR + manual,"WCAG 3.3.1, 3.3.3",Required
|
||||
A11Y-008,Status,Success/failure announced without focus theft,SR,WCAG 4.1.3,Required
|
||||
A11Y-009,Contrast,"Text, UI, focus in both themes",Automated + manual,"WCAG 1.4.3, 1.4.11",Required
|
||||
A11Y-010,Reflow,320px and 400% zoom,Manual,WCAG 1.4.10,Required
|
||||
A11Y-011,Text spacing,User overrides do not clip,Bookmarklet/manual,WCAG 1.4.12,Required
|
||||
A11Y-012,Motion,Reduced-motion honored,Manual,WCAG 2.3.3,Required
|
||||
A11Y-013,Language,Page and language changes identified,DOM + SR,"WCAG 3.1.1, 3.1.2",Required
|
||||
A11Y-014,Bidi,Mixed-direction values remain intelligible,Visual + SR,WCAG 1.3.2,Required
|
||||
A11Y-015,Targets,Target spacing and size tested,Automated + manual,WCAG 2.5.8,Required
|
||||
A11Y-016,Autofill,Correct autocomplete tokens,DOM + browser,WCAG 1.3.5,Required
|
||||
|
@@ -0,0 +1,10 @@
|
||||
Browser_or_AT,Version_policy,Platform,Coverage
|
||||
Chrome desktop,Latest stable and previous major,"Windows 11, macOS","All functional, visual, performance smoke"
|
||||
Edge desktop,Latest stable and previous major,Windows 11,All functional and visual smoke
|
||||
Firefox desktop,Latest stable and previous major,"Windows 11, macOS","Functional, keyboard, layout, forced-colors where supported"
|
||||
Safari desktop,Latest stable and previous major,macOS,"Functional, dialog, storage, typography, visual"
|
||||
Safari iOS,Latest stable and previous major,Representative iPhone compact and large,"Navigation, dialogs, virtual keyboard, form, viewport"
|
||||
Chrome Android,Latest stable and previous major,Representative Android phone,"Navigation, dialogs, virtual keyboard, form, viewport"
|
||||
Assistive technology,NVDA + Firefox/Chrome current,Windows,Critical paths
|
||||
Assistive technology,VoiceOver + Safari current,macOS/iOS,Critical paths
|
||||
Assistive technology,TalkBack + Chrome current,Android,Critical paths
|
||||
|
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"measurement": "75th percentile real-user data where available; otherwise repeatable lab median on defined mobile profile",
|
||||
"core": {
|
||||
"LCP_ms_max": 2500,
|
||||
"INP_ms_max": 200,
|
||||
"CLS_max": 0.1,
|
||||
"TTFB_ms_max": 800
|
||||
},
|
||||
"transfer_gzip": {
|
||||
"initial_javascript_kb_max": 180,
|
||||
"initial_css_kb_max": 60,
|
||||
"initial_html_kb_max": 100,
|
||||
"hero_media_kb_max": 250,
|
||||
"font_total_kb_max": 220
|
||||
},
|
||||
"requests": {
|
||||
"initial_third_party_max": 2,
|
||||
"initial_font_files_max": 2
|
||||
},
|
||||
"rules": [
|
||||
"No marketing tag may block first paint.",
|
||||
"Load analytics after consent and idle where possible.",
|
||||
"Reserve media dimensions to prevent layout shift.",
|
||||
"No autoplay video on initial load.",
|
||||
"Test EN, FR, and AR because font and copy costs differ."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# Browser Acceptance Specification
|
||||
|
||||
Automated browser tests must cover the scenarios in `visual-regression-scenarios_v1.0.json` plus behavioral assertions from `QA_MATRIX_v1.0.csv`.
|
||||
|
||||
Use semantic locators first: role, accessible name, label, heading, and visible text. Add `data-testid` only where locale-independent state cannot be selected reliably. Never use generated class names as test contracts.
|
||||
|
||||
At minimum, assert server HTML attributes, locale switching with preserved hash, root-only detection, theme no-flash state before app hydration, cookie precedence, system live update, drawer focus loop and inert state, dialog focus return, invalid form focus, recoverable failure value retention, idempotent submit, tour progress, reduced motion, and prohibited PII absence from analytics calls.
|
||||
@@ -0,0 +1,27 @@
|
||||
ID,Area,Scenario,Variants,Method,Expected,Gate
|
||||
QA-001,Routing,Each locale route renders server-correct lang/dir/canonical/hreflang,en/fr/ar,Automated HTML assertion,No hydration correction required,Release
|
||||
QA-002,Localization,Key parity and scalar/array type parity,en/fr/ar,CI validator,"Zero missing, empty, or extra production keys",Release
|
||||
QA-003,Localization,Translation overflow,320/390/768/1024/1440; all locales,Visual + manual,"No clipping, ellipsis, fixed-height collision, or horizontal page scroll",Release
|
||||
QA-004,RTL,Full homepage direction,ar light/dark,Visual + DOM,"Logical order, correct start alignment, selective mirroring",Release
|
||||
QA-005,Mixed direction,"Plate, email, URL, phone, date, currency",ar,Screen reader + visual,Atomic value order remains correct,Release
|
||||
QA-006,Theme,Preference persistence and cookie/storage disagreement,light/dark/system,Browser automation,Cookie wins; no flash; system stays system,Release
|
||||
QA-007,Theme,OS theme changes while System selected,system,Browser automation,Resolved theme updates without changing preference,Release
|
||||
QA-008,Navigation,Desktop header collision and keyboard use,1120/1280/1440; all locales,Visual + keyboard,No overlap; visible focus; logical order,Release
|
||||
QA-009,Navigation,Drawer open/close containment,390/1024; ltr/rtl,Keyboard + SR,"Focus trapped, background inert, Escape and focus return work",Release
|
||||
QA-010,Hero,Primary demo and tour actions,all locales/themes,Browser,Correct dialogs open; analytics source accurate,Release
|
||||
QA-011,Demo form,Empty/invalid submission,all locales,Browser + SR,Summary announced; first invalid focused; inline errors associated,Release
|
||||
QA-012,Demo form,Recoverable server failure,all locales,Integration,Values preserved; retry possible; persistent error,Release
|
||||
QA-013,Demo form,Duplicate click/network retry,all locales,Integration,Single lead due to disabled submit and idempotency,Release
|
||||
QA-014,Demo form,Success,all locales,Integration,Accurate localized confirmation; no PII in analytics,Release
|
||||
QA-015,Tour,Four-step keyboard flow,all locales,Browser + SR,Progress announced; back/next/finish correct; focus moves,Release
|
||||
QA-016,FAQ,Toggle by keyboard and screen reader,all locales,Manual + browser,Summary semantics and state announced,Release
|
||||
QA-017,Accessibility,200% zoom and 400% reflow,320-equivalent; all locales,Manual,No two-dimensional scrolling except data regions,Release
|
||||
QA-018,Accessibility,Forced colors,Windows,Manual,"Controls, focus, boundaries, status remain perceivable",Release
|
||||
QA-019,Accessibility,Reduced motion,all,Browser + manual,No smooth scrolling or essential animation,Release
|
||||
QA-020,Accessibility,Touch target size,compact,Automated + manual,44x44 preferred; WCAG minimum not violated,Release
|
||||
QA-021,Evidence,Claims and assets,production content,Content audit,Every claim has approval or is suppressed,Release
|
||||
QA-022,SEO,Metadata and language alternates,indexable routes,Automated,Unique localized metadata; reciprocal alternates; self-canonical,Release
|
||||
QA-023,Performance,Budgets,mobile + desktop; each locale,Lighthouse/WebPageTest/RUM,All budgets met or approved exception,Release
|
||||
QA-024,Security,CSP and bootstrap,production,Header inspection,Nonce/hash accepted; no unsafe inline expansion,Release
|
||||
QA-025,Privacy,Consent and analytics gating,regions in scope,Integration/manual,No non-essential analytics before required consent,Release
|
||||
QA-026,Visual regression,Named screen states,scenario manifest,Automated screenshots,No unapproved diffs above threshold,Release
|
||||
|
@@ -0,0 +1,14 @@
|
||||
Test_ID,Element,Justification
|
||||
site-header,Header root,Only for visual anchor
|
||||
mobile-drawer,Drawer root,State assertion
|
||||
locale-selector,Locale control,State assertion
|
||||
theme-selector,Theme control,State assertion
|
||||
hero-demo,Hero demo CTA,Source attribution
|
||||
hero-tour,Hero tour CTA,Source attribution
|
||||
demo-dialog,Demo dialog,Overlay state
|
||||
demo-form,Demo form,Submission state
|
||||
demo-alert,Form summary,Error assertion
|
||||
tour-dialog,Tour dialog,Overlay state
|
||||
tour-step,Current tour step,Progress assertion
|
||||
pricing-demo,Pricing CTA,Source attribution
|
||||
final-demo,Final CTA,Source attribution
|
||||
|
@@ -0,0 +1,24 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import crypto from 'node:crypto';
|
||||
const root = path.resolve(path.dirname(new URL(import.meta.url).pathname), '..');
|
||||
const required = [
|
||||
'09_DEVELOPER_HANDOFF_v1.0.md','DECISION_LOG_v9.0.md','DEFINITION_OF_DONE_v1.0.md','OPEN_ISSUE_REGISTER_v1.0.csv',
|
||||
'tokens/design-tokens_v1.0.json','tokens/semantic-tokens_v1.0.css','components/COMPONENT_CONTRACTS_v1.0.md',
|
||||
'localization/ROUTE_MANIFEST_v1.0.json','localization/locales/en/homepage.json','localization/locales/fr/homepage.json','localization/locales/ar/homepage.json',
|
||||
'interaction/theme-bootstrap_v1.0.js','qa/QA_MATRIX_v1.0.csv','qa/ACCESSIBILITY_CHECKLIST_v1.0.csv','qa/PERFORMANCE_BUDGETS_v1.0.json'
|
||||
];
|
||||
const errors=[]; let checks=0;
|
||||
for (const file of required){ checks++; if(!fs.existsSync(path.join(root,file))) errors.push(`Missing ${file}`); }
|
||||
const readJson=(f)=>JSON.parse(fs.readFileSync(path.join(root,f),'utf8'));
|
||||
for (const file of ['tokens/design-tokens_v1.0.json','localization/ROUTE_MANIFEST_v1.0.json','qa/PERFORMANCE_BUDGETS_v1.0.json','qa/visual-regression-scenarios_v1.0.json']) { try{readJson(file);checks++;}catch(e){errors.push(`${file}: ${e.message}`);} }
|
||||
function shape(value){ if(Array.isArray(value)) return value.map(shape); if(value && typeof value==='object') return Object.fromEntries(Object.keys(value).sort().map(k=>[k,shape(value[k])])); return typeof value; }
|
||||
const locales=['en','fr','ar'].map(l=>readJson(`localization/locales/${l}/homepage.json`));
|
||||
const base=JSON.stringify(shape(locales[0]));
|
||||
for (let i=1;i<locales.length;i++){ checks++; if(JSON.stringify(shape(locales[i]))!==base) errors.push(`Locale shape mismatch: ${['en','fr','ar'][i]}`); }
|
||||
const routes=readJson('localization/ROUTE_MANIFEST_v1.0.json');
|
||||
for (const route of routes.routes){ for (const locale of routes.locales){ checks++; if(!(locale in route.slugs)) errors.push(`Route ${route.id} missing ${locale}`); } }
|
||||
const issueCsv=fs.readFileSync(path.join(root,'OPEN_ISSUE_REGISTER_v1.0.csv'),'utf8'); checks++; if(/,(Critical|High),[^\n]*,,/.test(issueCsv)) errors.push('Critical/High issue missing ownership data');
|
||||
const css=fs.readFileSync(path.join(root,'tokens/semantic-tokens_v1.0.css'),'utf8'); checks++; if(!css.includes('--color-action-conversion')) errors.push('Conversion semantic token missing');
|
||||
if(errors.length){ console.error(JSON.stringify({status:'FAILED',checks,errors},null,2)); process.exit(1); }
|
||||
console.log(JSON.stringify({status:'PASSED',checks,files:fs.readdirSync(root).length},null,2));
|
||||
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"version": "1.0",
|
||||
"pixelDiffThreshold": 0.01,
|
||||
"scenarios": [
|
||||
{
|
||||
"id": "VR-001",
|
||||
"route": "/en",
|
||||
"viewport": [
|
||||
1440,
|
||||
1000
|
||||
],
|
||||
"theme": "light",
|
||||
"state": "homepage-top"
|
||||
},
|
||||
{
|
||||
"id": "VR-002",
|
||||
"route": "/fr",
|
||||
"viewport": [
|
||||
1024,
|
||||
900
|
||||
],
|
||||
"theme": "dark",
|
||||
"state": "homepage-top"
|
||||
},
|
||||
{
|
||||
"id": "VR-003",
|
||||
"route": "/ar",
|
||||
"viewport": [
|
||||
390,
|
||||
844
|
||||
],
|
||||
"theme": "light",
|
||||
"state": "homepage-top"
|
||||
},
|
||||
{
|
||||
"id": "VR-004",
|
||||
"route": "/ar",
|
||||
"viewport": [
|
||||
390,
|
||||
844
|
||||
],
|
||||
"theme": "dark",
|
||||
"state": "drawer-open"
|
||||
},
|
||||
{
|
||||
"id": "VR-005",
|
||||
"route": "/en",
|
||||
"viewport": [
|
||||
390,
|
||||
844
|
||||
],
|
||||
"theme": "light",
|
||||
"state": "demo-invalid"
|
||||
},
|
||||
{
|
||||
"id": "VR-006",
|
||||
"route": "/fr",
|
||||
"viewport": [
|
||||
768,
|
||||
1024
|
||||
],
|
||||
"theme": "dark",
|
||||
"state": "tour-step-3"
|
||||
},
|
||||
{
|
||||
"id": "VR-007",
|
||||
"route": "/ar",
|
||||
"viewport": [
|
||||
320,
|
||||
800
|
||||
],
|
||||
"theme": "dark",
|
||||
"state": "reflow-gate"
|
||||
},
|
||||
{
|
||||
"id": "VR-008",
|
||||
"route": "/en",
|
||||
"viewport": [
|
||||
1440,
|
||||
1000
|
||||
],
|
||||
"theme": "dark",
|
||||
"state": "pricing-and-final-cta"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
# Findings Report
|
||||
|
||||
**Version:** 1.0
|
||||
**Evidence status:** Pre-test expert review and automated validation only
|
||||
**Participant sessions completed:** 0
|
||||
|
||||
## Executive assessment
|
||||
|
||||
The Phase 8 prototype is ready for pilot testing. The Phase 7 baseline exposed several behavioral gaps that would have invalidated primary-flow testing: inert form submission, no product-tour interaction behind a “Watch product tour” promise, incomplete mobile drawer focus containment, and no durable theme preference. These were corrected in the Phase 8 prototype.
|
||||
|
||||
No claim is made that users understand the product, find the CTA, or complete the form. Those are hypotheses until representative participants attempt the tasks.
|
||||
|
||||
## Pre-test findings
|
||||
|
||||
| ID | Evidence | Finding | Severity | Status |
|
||||
|---|---|---|---|---|
|
||||
| P8-001 | Expert + code review | Demo submission in Phase 7 prevented default and produced no success, failure, or recovery state. | S0/C | Fixed in prototype |
|
||||
| P8-002 | Expert + code review | “Watch product tour” navigated to a workflow section rather than opening a tour, creating an expectation mismatch. | S1/C | Fixed with four-step tour |
|
||||
| P8-003 | Expert + code review | Mobile drawer moved focus initially but did not contain focus or make background content inert. | S0/C | Fixed in prototype |
|
||||
| P8-004 | Expert + code review | Theme existed in URL state but did not persist reliably when revisiting without the query parameter. | S1/C | Fixed with local persistence |
|
||||
| P8-005 | Expert review | Multi-location support is implied by branch/location copy but is not an approved capability claim. Users may over-infer. | S2/C | Test explicitly; content approval pending |
|
||||
| P8-006 | Expert review | Final legal consent, alternate failure contact, CRM routing, and spam controls are unresolved. | S1/C for production | Prototype limitation; open |
|
||||
| P8-007 | Automated browser test | EN/FR/AR direction, tour completion, form validation/success, locale hash preservation, theme persistence, and mobile focus return pass the scripted browser checks. | S4/A | Passed |
|
||||
|
||||
## Hypotheses requiring participant evidence
|
||||
|
||||
1. The first viewport communicates rental operations and reservation-to-return scope within five seconds.
|
||||
2. Orange CTA hierarchy yields unprompted demo discovery.
|
||||
3. The four-step tour improves workflow comprehension without being mistaken for a full product demo.
|
||||
4. Arabic users understand menu origin, control order, and mixed LTR identifiers.
|
||||
5. Users distinguish “pricing factors” from public pricing.
|
||||
6. Users do not mistake neutral integration and security evaluation content for confirmed capability or certification.
|
||||
7. Form error recovery preserves confidence and entered data.
|
||||
|
||||
## Participant-results section
|
||||
|
||||
After sessions, add cohort counts, task-level completion, median time, error and rescue rates, abandonment, confidence, accessibility outcomes, repeated behavior patterns, anonymized quotes where consented, issue table, and recommended revisions. Report locale results separately before any aggregate.
|
||||
@@ -0,0 +1,19 @@
|
||||
# Phase 8 Handoff — Interactive Prototype and Usability Testing
|
||||
|
||||
Phase 8 is test-ready.
|
||||
|
||||
Use `08_INTERACTIVE_PROTOTYPE_USABILITY_TESTING_v1.0.md` as the authoritative research specification, `prototype/` as the clickable test build, and `DECISION_LOG_v8.0.md` as the cumulative decision record.
|
||||
|
||||
The prototype provides:
|
||||
|
||||
- EN/FR/AR content with true Arabic RTL;
|
||||
- Light/Dark/System selection with persistence;
|
||||
- context-preserving locale changes;
|
||||
- demo form validation, simulated service failure, confirmation, and reset;
|
||||
- four-step product tour;
|
||||
- mobile navigation with focus containment, inert background, Escape handling, and focus return;
|
||||
- session-local, non-PII research events and export in `?test=1` mode.
|
||||
|
||||
Research must begin with three pilot sessions, then the balanced core and accessibility cohorts defined in `PARTICIPANT_PROFILE_v1.0.md`. Do not mark Phase 8 accepted until the thresholds in `SUCCESS_METRICS_v1.0.csv` pass and every Critical/High issue is fixed and retested.
|
||||
|
||||
Unresolved product, recruitment, market, analytics, CRM, legal, and content matters remain in `OPEN_QUESTIONS_v1.0.md`.
|
||||
@@ -0,0 +1,8 @@
|
||||
Revision_ID,Finding_ID,Revision,Severity,Status,Owner,Target,Retest
|
||||
REV-001,P8-001,"Implement validation, failure, success, and reset states",S0,Done,Prototype,Phase 8 v1.0,Automated + participant retest
|
||||
REV-002,P8-002,Replace misleading tour anchor with four-step tour dialog,S1,Done,Prototype,Phase 8 v1.0,Tour task
|
||||
REV-003,P8-003,"Add drawer focus containment, inert background, and focus return",S0,Done,Prototype,Phase 8 v1.0,Keyboard + screen reader
|
||||
REV-004,P8-004,Persist theme and restore it after reload,S1,Done,Prototype,Phase 8 v1.0,Theme task
|
||||
REV-005,P8-005,Test and then clarify multi-location capability language using approved product evidence,S2,Pending evidence,Product + Content,Before beta,Affected cohort retest
|
||||
REV-006,P8-006,"Approve consent, CRM routing, spam protection, alternate contact, retry and duplicate handling",S1,Open,Legal + Sales Ops + Engineering,Before production,Integration test
|
||||
REV-007,Analytics open question,Map provisional events to approved analytics/consent platform,S2,Open,Analytics + Legal,Before beta,Event QA
|
||||
|
@@ -0,0 +1,13 @@
|
||||
ID,Metric,Definition,Threshold,Collection,Segmentation
|
||||
M-01,Five-second comprehension,Correct category + audience + reservation-to-return scope,>=80% overall; no locale <70%,Exact unprompted response,Per locale
|
||||
M-02,Primary CTA discovery,Book demo activated without prompt,>=90% within 10 seconds,Time and first action,Per locale/device
|
||||
M-03,Product tour completion,All four steps completed and sequence paraphrased,>=85%,"Completion, time, errors",Per locale
|
||||
M-04,Module discovery,Vehicle inspections located and explained,>=85% without rescue,"Completion, path, time",Per role
|
||||
M-05,Multi-location interpretation,Finds evidence and separates confirmed from unresolved,>=80%; overclaim <=10%,Response and cited evidence,Multi-location vs single
|
||||
M-06,Pricing discovery,Finds quote model and >=2 factors,>=85%,Completion and time,Per locale
|
||||
M-07,Locale context,Switch preserves current section and task,100% technical; >=90% participant continuation,"Hash, section, errors",EN↔FR; EN↔AR
|
||||
M-08,Theme persistence,Selection survives reload,100%,State before/after reload,Browser/OS
|
||||
M-09,Demo completion,Reaches confirmation,>=90%,Completion and abandonment,Per locale/device
|
||||
M-10,Validation recovery,Corrects error without losing other data,>=85%,"Errors, recovery time, rescue",Per locale/access method
|
||||
M-11,Keyboard critical path,Completes navigation/theme/demo with keyboard,100%; zero traps,Focus order and completion,Desktop/mobile keyboard
|
||||
M-12,Confidence,Post-task rating,Median >=4/5; no locale <3.5,Rating plus reason,Per locale
|
||||
|
@@ -0,0 +1,35 @@
|
||||
# homePageCar — Phase 8 Validation Results
|
||||
|
||||
**Version:** 1.0
|
||||
**Package status:** PASSED for prototype readiness
|
||||
**Usability acceptance status:** NOT YET TESTED WITH PARTICIPANTS
|
||||
|
||||
## Automated package validation
|
||||
|
||||
- 63 static package and behavior-contract checks passed.
|
||||
- Required deliverables, locale copy parity, form state copy, tour state copy, interaction hooks, privacy constraints, and decision continuity are present.
|
||||
- JavaScript syntax and browser execution completed successfully in Chromium.
|
||||
|
||||
## Scripted browser validation
|
||||
|
||||
Six checks passed:
|
||||
|
||||
1. English homepage and four-step product-tour completion.
|
||||
2. French demo-form validation recovery and confirmation.
|
||||
3. Locale switch preserves the pricing-section context.
|
||||
4. Explicit theme selection persists after reload/revisit.
|
||||
5. Arabic dark mobile drawer opens in RTL, moves focus, closes with Escape, and returns focus.
|
||||
6. Simulated service failure retains entered values and presents a persistent error.
|
||||
|
||||
The execution environment blocks browser navigation to local HTTP and file URLs by administrator policy. The browser harness therefore injects the exact packaged HTML, CSS, copy, and JavaScript into Chromium and supplies deterministic query state in memory. This validates behavior but does not replace manual testing from a normal local server, real browser storage, assistive technology, zoom, virtual keyboards, or network conditions.
|
||||
|
||||
## Manual gates still required
|
||||
|
||||
- Moderated pilot and core participant sessions.
|
||||
- Native Arabic and French linguistic review.
|
||||
- NVDA, VoiceOver, TalkBack, and real keyboard/switch-user testing.
|
||||
- 200% zoom, 400% reflow, forced colors, reduced motion, and mobile virtual keyboard.
|
||||
- Real CRM submission, consent, duplicate handling, retry, spam protection, and analytics consent.
|
||||
- Final multi-location, pricing, integrations, security, legal, and evidence approvals.
|
||||
|
||||
Automated checks establish that the prototype behaves as specified. They do not establish that people understand it, trust it, or refrain from inventing capabilities between the lines.
|
||||
@@ -0,0 +1,12 @@
|
||||
# Token Usage Rules
|
||||
|
||||
1. Components consume semantic tokens such as `--color-text`, `--color-surface`, and `--color-action-conversion`. Raw palette values are allowed only in token declaration files, approved asset files, and documented data visualizations.
|
||||
2. Orange is reserved for demo conversion and tightly related emphasis. Routine primary actions use the primary-action token.
|
||||
3. White normal text may not use orange-600. Light conversion uses orange-700 with white; dark conversion uses orange-400 with dark text.
|
||||
4. Spacing uses the 4 px scale. Optical exceptions require a comment and design approval.
|
||||
5. Interactive targets are 44 × 44 px minimum unless the target is an inline text link with sufficient surrounding line height.
|
||||
6. Use logical properties: `margin-inline`, `padding-block`, `inset-inline-start`, `border-inline-end`. Physical left/right properties fail review unless they describe an intrinsically physical asset.
|
||||
7. Shadows are neutral. Colored glow is prohibited.
|
||||
8. No global transition is applied during theme changes.
|
||||
9. Text and surfaces must meet WCAG 2.2 AA in both themes. Focus indicators must remain visible in forced-colors mode.
|
||||
10. Product screenshots are not recolored by tokens.
|
||||
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"$schema": "https://design-tokens.github.io/community-group/format/",
|
||||
"version": "1.0",
|
||||
"raw": {
|
||||
"color": {
|
||||
"blue": {
|
||||
"50": "#eff6ff",
|
||||
"100": "#dbeafe",
|
||||
"200": "#bfdbfe",
|
||||
"500": "#2874e8",
|
||||
"600": "#1b5dd8",
|
||||
"700": "#174bb5",
|
||||
"800": "#183d88"
|
||||
},
|
||||
"orange": {
|
||||
"100": "#ffedd5",
|
||||
"400": "#fb923c",
|
||||
"600": "#ea580c",
|
||||
"700": "#c2410c"
|
||||
},
|
||||
"navy": {
|
||||
"950": "#081426",
|
||||
"900": "#0d1b2e",
|
||||
"850": "#11233b",
|
||||
"800": "#162b46"
|
||||
},
|
||||
"gray": {
|
||||
"25": "#fbfdff",
|
||||
"50": "#f7f9fc",
|
||||
"100": "#eef2f7",
|
||||
"200": "#dbe3ed",
|
||||
"300": "#c6d0dc",
|
||||
"500": "#64748b",
|
||||
"600": "#475569",
|
||||
"700": "#334155",
|
||||
"800": "#1e293b",
|
||||
"900": "#0f172a"
|
||||
},
|
||||
"green": {
|
||||
"100": "#dcfce7",
|
||||
"700": "#15803d"
|
||||
},
|
||||
"amber": {
|
||||
"100": "#fef3c7",
|
||||
"800": "#92400e"
|
||||
},
|
||||
"red": {
|
||||
"100": "#fee2e2",
|
||||
"700": "#b91c1c"
|
||||
}
|
||||
},
|
||||
"space": {
|
||||
"0": "0px",
|
||||
"1": "4px",
|
||||
"2": "8px",
|
||||
"3": "12px",
|
||||
"4": "16px",
|
||||
"5": "20px",
|
||||
"6": "24px",
|
||||
"7": "28px",
|
||||
"8": "32px",
|
||||
"9": "36px",
|
||||
"10": "40px",
|
||||
"11": "44px",
|
||||
"12": "48px",
|
||||
"13": "52px",
|
||||
"14": "56px",
|
||||
"15": "60px",
|
||||
"16": "64px",
|
||||
"17": "68px",
|
||||
"18": "72px",
|
||||
"19": "76px",
|
||||
"20": "80px",
|
||||
"21": "84px",
|
||||
"22": "88px",
|
||||
"23": "92px",
|
||||
"24": "96px"
|
||||
},
|
||||
"radius": {
|
||||
"sm": "10px",
|
||||
"md": "16px",
|
||||
"lg": "24px",
|
||||
"xl": "32px",
|
||||
"pill": "999px"
|
||||
},
|
||||
"size": {
|
||||
"touch-min": "44px",
|
||||
"container-max": "1280px"
|
||||
},
|
||||
"duration": {
|
||||
"fast": "120ms",
|
||||
"standard": "160ms",
|
||||
"overlay": "220ms"
|
||||
},
|
||||
"easing": {
|
||||
"standard": "ease",
|
||||
"productive": "cubic-bezier(.2,0,0,1)"
|
||||
},
|
||||
"font": {
|
||||
"latin": "Inter Variable, Inter, Arial, sans-serif",
|
||||
"arabic": "Noto Sans Arabic, Arial, sans-serif"
|
||||
},
|
||||
"breakpoint": {
|
||||
"medium": "768px",
|
||||
"wide": "1120px"
|
||||
}
|
||||
},
|
||||
"semantic": {
|
||||
"light": {
|
||||
"color.canvas": "{color.gray.25}",
|
||||
"color.surface": "#ffffff",
|
||||
"color.surface.raised": "#ffffff",
|
||||
"color.surface.muted": "#f2f6fb",
|
||||
"color.surface.strong": "#e8f0fa",
|
||||
"color.text": "#102035",
|
||||
"color.text.muted": "#52647a",
|
||||
"color.border": "#d8e2ee",
|
||||
"color.border.strong": "#bdcad9",
|
||||
"color.action.primary": "{color.blue.700}",
|
||||
"color.action.primary.hover": "{color.blue.800}",
|
||||
"color.action.conversion": "{color.orange.700}",
|
||||
"color.action.conversion.hover": "#9a3412",
|
||||
"color.focus": "#f97316",
|
||||
"color.on.inverse": "#f8fafc",
|
||||
"color.soft.blue": "#eef5ff",
|
||||
"color.soft.orange": "#fff7ed",
|
||||
"shadow.color": "rgba(8,20,38,.12)"
|
||||
},
|
||||
"dark": {
|
||||
"color.canvas": "{color.navy.950}",
|
||||
"color.surface": "{color.navy.900}",
|
||||
"color.surface.raised": "{color.navy.850}",
|
||||
"color.surface.muted": "#0b1a2d",
|
||||
"color.surface.strong": "#172d48",
|
||||
"color.text": "#eef5ff",
|
||||
"color.text.muted": "#adbed2",
|
||||
"color.border": "#263c56",
|
||||
"color.border.strong": "#3a536e",
|
||||
"color.action.primary": "#76a9ff",
|
||||
"color.action.primary.hover": "#9bc2ff",
|
||||
"color.action.conversion": "{color.orange.400}",
|
||||
"color.action.conversion.hover": "#fdba74",
|
||||
"color.focus": "{color.orange.400}",
|
||||
"color.on.inverse": "{color.navy.950}",
|
||||
"color.soft.blue": "#10284a",
|
||||
"color.soft.orange": "#3a2015",
|
||||
"shadow.color": "rgba(0,0,0,.36)"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
:root {
|
||||
--color-blue-50: #eff6ff;
|
||||
--color-blue-100: #dbeafe;
|
||||
--color-blue-200: #bfdbfe;
|
||||
--color-blue-500: #2874e8;
|
||||
--color-blue-600: #1b5dd8;
|
||||
--color-blue-700: #174bb5;
|
||||
--color-blue-800: #183d88;
|
||||
--color-orange-100: #ffedd5;
|
||||
--color-orange-400: #fb923c;
|
||||
--color-orange-600: #ea580c;
|
||||
--color-orange-700: #c2410c;
|
||||
--color-navy-950: #081426;
|
||||
--color-navy-900: #0d1b2e;
|
||||
--color-navy-850: #11233b;
|
||||
--color-navy-800: #162b46;
|
||||
--color-gray-25: #fbfdff;
|
||||
--color-gray-50: #f7f9fc;
|
||||
--color-gray-100: #eef2f7;
|
||||
--color-gray-200: #dbe3ed;
|
||||
--color-gray-300: #c6d0dc;
|
||||
--color-gray-500: #64748b;
|
||||
--color-gray-600: #475569;
|
||||
--color-gray-700: #334155;
|
||||
--color-gray-800: #1e293b;
|
||||
--color-gray-900: #0f172a;
|
||||
--color-green-100: #dcfce7;
|
||||
--color-green-700: #15803d;
|
||||
--color-amber-100: #fef3c7;
|
||||
--color-amber-800: #92400e;
|
||||
--color-red-100: #fee2e2;
|
||||
--color-red-700: #b91c1c;
|
||||
--space-0: 0px;
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-7: 28px;
|
||||
--space-8: 32px;
|
||||
--space-9: 36px;
|
||||
--space-10: 40px;
|
||||
--space-11: 44px;
|
||||
--space-12: 48px;
|
||||
--space-13: 52px;
|
||||
--space-14: 56px;
|
||||
--space-15: 60px;
|
||||
--space-16: 64px;
|
||||
--space-17: 68px;
|
||||
--space-18: 72px;
|
||||
--space-19: 76px;
|
||||
--space-20: 80px;
|
||||
--space-21: 84px;
|
||||
--space-22: 88px;
|
||||
--space-23: 92px;
|
||||
--space-24: 96px;
|
||||
--radius-sm: 10px;
|
||||
--radius-md: 16px;
|
||||
--radius-lg: 24px;
|
||||
--radius-xl: 32px;
|
||||
--radius-pill: 999px;
|
||||
--size-touch-min: 44px;
|
||||
--size-container-max: 1280px;
|
||||
--duration-fast: 120ms;
|
||||
--duration-standard: 160ms;
|
||||
--duration-overlay: 220ms;
|
||||
--easing-standard: ease;
|
||||
--easing-productive: cubic-bezier(.2,0,0,1);
|
||||
--font-latin: Inter Variable, Inter, Arial, sans-serif;
|
||||
--font-arabic: Noto Sans Arabic, Arial, sans-serif;
|
||||
--breakpoint-medium: 768px;
|
||||
--breakpoint-wide: 1120px;
|
||||
}
|
||||
|
||||
html[data-theme="light"] {
|
||||
--color-canvas: var(--color-gray-25);
|
||||
--color-surface: #ffffff;
|
||||
--color-surface-raised: #ffffff;
|
||||
--color-surface-muted: #f2f6fb;
|
||||
--color-surface-strong: #e8f0fa;
|
||||
--color-text: #102035;
|
||||
--color-text-muted: #52647a;
|
||||
--color-border: #d8e2ee;
|
||||
--color-border-strong: #bdcad9;
|
||||
--color-action-primary: var(--color-blue-700);
|
||||
--color-action-primary-hover: var(--color-blue-800);
|
||||
--color-action-conversion: var(--color-orange-700);
|
||||
--color-action-conversion-hover: #9a3412;
|
||||
--color-focus: #f97316;
|
||||
--color-on-inverse: #f8fafc;
|
||||
--color-soft-blue: #eef5ff;
|
||||
--color-soft-orange: #fff7ed;
|
||||
--shadow-color: rgba(8,20,38,.12);
|
||||
color-scheme: light;
|
||||
}
|
||||
html[data-theme="dark"] {
|
||||
--color-canvas: var(--color-navy-950);
|
||||
--color-surface: var(--color-navy-900);
|
||||
--color-surface-raised: var(--color-navy-850);
|
||||
--color-surface-muted: #0b1a2d;
|
||||
--color-surface-strong: #172d48;
|
||||
--color-text: #eef5ff;
|
||||
--color-text-muted: #adbed2;
|
||||
--color-border: #263c56;
|
||||
--color-border-strong: #3a536e;
|
||||
--color-action-primary: #76a9ff;
|
||||
--color-action-primary-hover: #9bc2ff;
|
||||
--color-action-conversion: var(--color-orange-400);
|
||||
--color-action-conversion-hover: #fdba74;
|
||||
--color-focus: var(--color-orange-400);
|
||||
--color-on-inverse: var(--color-navy-950);
|
||||
--color-soft-blue: #10284a;
|
||||
--color-soft-orange: #3a2015;
|
||||
--shadow-color: rgba(0,0,0,.36);
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
html { scroll-behavior: auto; }
|
||||
*, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export const breakpoints = { medium: 768, wide: 1120 } as const;
|
||||
export const themePreferences = ["light", "dark", "system"] as const;
|
||||
export type ThemePreference = (typeof themePreferences)[number];
|
||||
export type ResolvedTheme = Exclude<ThemePreference, "system">;
|
||||
export const layout = { containerMaxPx: 1280, touchTargetMinPx: 44, spacingBasePx: 4 } as const;
|
||||
export const motion = { fastMs: 120, standardMs: 160, overlayMs: 220 } as const;
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"status": "PASSED",
|
||||
"checks": 33,
|
||||
"contrast": {
|
||||
"light conversion": 5.18,
|
||||
"dark conversion": 7.54,
|
||||
"light primary": 7.75,
|
||||
"dark primary": 7.81
|
||||
},
|
||||
"errors": []
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"status": "PASSED",
|
||||
"checks": 38,
|
||||
"files": 18
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
# homePageCar — Phase 9 Validation Results
|
||||
|
||||
**Version:** 1.0
|
||||
**Package status:** PASSED for developer handoff completeness
|
||||
**Production release status:** BLOCKED by the explicit issue register
|
||||
|
||||
## Automated results
|
||||
|
||||
- Required artifact, route, locale-shape, token, and issue-owner checks passed.
|
||||
- JSON syntax and CSV column consistency passed across the package.
|
||||
- English, French, and Arabic locale structures are identical and contain no empty scalar values.
|
||||
- Theme bootstrap and package validator JavaScript passed syntax checks.
|
||||
- Key action contrast checks passed: light conversion 5.18:1, dark conversion 7.54:1, light primary 7.75:1, and dark primary 7.81:1.
|
||||
- Six annotated reference captures were generated for desktop, tablet, mobile RTL, RTL drawer, demo dialog, and product tour states.
|
||||
|
||||
## What this validation does not prove
|
||||
|
||||
It does not prove participant comprehension, native French or Arabic quality, production CRM behavior, legal consent, analytics compliance, real browser/assistive-technology coverage, approved product evidence, or deployed performance. Those remain release gates in `OPEN_ISSUE_REGISTER_v1.0.csv` and `DEFINITION_OF_DONE_v1.0.md`.
|
||||