From 5d017f533a2f8d28603b435ee123efacb090c6f0 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 25 Jun 2026 19:06:59 -0400 Subject: [PATCH] init project --- CONTRIBUTING.md | 39 + Dockerfile | 30 + PHASE_10_PACKAGE_MANIFEST_v1.0.json | 749 +++ PHASE_11_PACKAGE_MANIFEST_v1.0.json | 1024 ++++ PHASE_12_PACKAGE_MANIFEST_v1.0.json | 1704 ++++++ PHASE_13_PACKAGE_MANIFEST_v1.0.json | 1810 ++++++ README 2.md | 103 + contracts/phase9/09_DEVELOPER_HANDOFF_v1.0.md | 147 + contracts/phase9/DECISION_LOG_v9.0.md | 198 + contracts/phase9/DEFINITION_OF_DONE_v1.0.md | 54 + contracts/phase9/OPEN_ISSUE_REGISTER_v1.0.csv | 18 + contracts/phase9/OPEN_QUESTIONS_v1.0.md | 26 + contracts/phase9/PACKAGE_MANIFEST_v1.0.json | 315 + contracts/phase9/PHASE_9_HANDOFF_v1.0.md | 9 + contracts/phase9/README_v1.0.md | 30 + contracts/phase9/SOURCE_TRACEABILITY_v1.0.csv | 8 + .../phase9/annotated/ANNOTATION_INDEX_v1.0.md | 12 + .../annotated/SCREEN_ANNOTATIONS_v1.0.csv | 16 + .../annotated/demo-dialog-en-light_v1.0.png | Bin 0 -> 51457 bytes .../annotated/desktop-en-light_v1.0.png | Bin 0 -> 144908 bytes .../phase9/annotated/mobile-ar-dark_v1.0.png | Bin 0 -> 75193 bytes .../annotated/mobile-drawer-ar-dark_v1.0.png | Bin 0 -> 28321 bytes .../phase9/annotated/tablet-fr-light_v1.0.png | Bin 0 -> 102305 bytes .../annotated/tour-dialog-fr-dark_v1.0.png | Bin 0 -> 94445 bytes .../phase9/assets/ASSET_MANIFEST_v1.0.csv | 8 + .../phase9/assets/ASSET_USAGE_RULES_v1.0.md | 7 + contracts/phase9/assets/brand-mark_v1.0.svg | 6 + .../phase9/assets/logo-horizontal_v1.0.svg | 6 + .../components/COMPONENT_CONTRACTS_v1.0.md | 385 ++ .../COMPONENT_STATE_MATRIX_v1.0.csv | 21 + .../components/CONTENT_CONSTRAINTS_v1.0.csv | 13 + .../RESPONSIVE_BEHAVIOR_MATRIX_v1.0.csv | 20 + .../components/RTL_THEME_MATRIX_v1.0.csv | 21 + .../implementation/TECHNOLOGY_PROFILE_v1.0.md | 43 + .../component-contracts_v1.0.ts | 26 + .../implementation/hreflang-generator_v1.0.ts | 13 + .../localization-config_v1.0.ts | 10 + .../implementation/theme-config_v1.0.ts | 8 + .../interaction/ANALYTICS_EVENT_SPEC_v1.0.csv | 19 + .../interaction/INTERACTION_NOTES_v1.0.md | 33 + .../interaction/analytics-contract_v1.0.ts | 9 + .../interaction/demo-form-contract_v1.0.ts | 5 + .../interaction/theme-bootstrap_v1.0.js | 14 + .../LOCALIZATION_IMPLEMENTATION_v1.0.md | 39 + .../localization/ROUTE_MANIFEST_v1.0.json | 90 + .../TRANSLATION_KEY_INVENTORY_v1.0.csv | 247 + .../localization/locales/ar/homepage.json | 430 ++ .../localization/locales/en/homepage.json | 430 ++ .../localization/locales/fr/homepage.json | 430 ++ .../qa/ACCESSIBILITY_CHECKLIST_v1.0.csv | 17 + .../phase9/qa/BROWSER_SUPPORT_MATRIX_v1.0.csv | 10 + .../phase9/qa/PERFORMANCE_BUDGETS_v1.0.json | 28 + .../qa/PLAYWRIGHT_ACCEPTANCE_SPEC_v1.0.md | 7 + contracts/phase9/qa/QA_MATRIX_v1.0.csv | 27 + contracts/phase9/qa/test-ids_v1.0.csv | 14 + .../qa/validate-phase9-package_v1.0.mjs | 24 + .../qa/visual-regression-scenarios_v1.0.json | 86 + .../phase9/reference/FINDINGS_REPORT_v1.0.md | 37 + .../phase9/reference/PHASE_8_HANDOFF_v1.0.md | 19 + .../reference/PRIORITIZED_REVISIONS_v1.0.csv | 8 + .../phase9/reference/SUCCESS_METRICS_v1.0.csv | 13 + .../reference/VALIDATION_RESULTS_v1.0.md | 35 + .../phase9/tokens/TOKEN_USAGE_RULES_v1.0.md | 12 + .../phase9/tokens/design-tokens_v1.0.json | 150 + .../phase9/tokens/semantic-tokens_v1.0.css | 122 + contracts/phase9/tokens/tokens_v1.0.ts | 6 + ...CONTENT_AND_STRUCTURE_VALIDATION_v1.0.json | 11 + .../STATIC_VALIDATION_RESULTS_v1.0.json | 5 + .../validation/VALIDATION_RESULTS_v1.0.md | 18 + docs/BRAND_MIGRATION_v1.0.md | 25 + docs/DECISION_LOG_v12.0.md | 58 + docs/DECISION_LOG_v13.0.md | 52 + docs/DEPENDENCY_MANIFEST_v1.0.md | 60 + docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv | 22 + docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv | 26 + docs/IMPLEMENTATION_ISSUE_REGISTER_v1.2.csv | 31 + docs/IMPLEMENTATION_ISSUE_REGISTER_v1.3.csv | 34 + docs/PHASE_10_HANDOFF_v1.0.md | 68 + docs/PHASE_10_IMPLEMENTATION_REPORT_v1.0.md | 126 + docs/PHASE_11_IMPLEMENTATION_REPORT_v1.0.md | 346 ++ docs/PHASE_12_HANDOFF_v1.0.md | 193 + docs/PHASE_12_IMPLEMENTATION_REPORT_v1.0.md | 177 + docs/PHASE_13_HANDOFF_v1.0.md | 212 + docs/PHASE_13_IMPLEMENTATION_REPORT_v1.0.md | 106 + docs/TOKEN_IMPLEMENTATION_v1.0.md | 45 + .../ADR-0001_REPOSITORY_FOUNDATION.md | 153 + .../ADR-0002_PHASE_11_FOUNDATIONS.md | 63 + .../ADR-0003_PHASE_12_COMPONENT_SYSTEM.md | 26 + .../ACCESSIBILITY_BEHAVIOR_MATRIX_v1.0.csv | 61 + docs/phase12/BUNDLE_IMPACT_REPORT_v1.0.md | 22 + docs/phase12/COMPONENT_CATALOG_v1.0.md | 77 + docs/phase12/COMPONENT_INVENTORY_v1.0.json | 1439 +++++ ...PONENT_SPECIFICATION_TRACEABILITY_v1.0.csv | 61 + .../phase12/DEFINITION_OF_DONE_STATUS_v1.0.md | 22 + docs/phase12/DEPENDENCY_CHANGE_REPORT_v1.0.md | 25 + .../RESPONSIVE_VALIDATION_MATRIX_v1.0.csv | 95 + .../RTL_BEHAVIOR_MATRIX_UPDATE_v1.0.csv | 61 + .../STORY_AND_FIXTURE_INVENTORY_v1.0.csv | 3 + docs/phase12/TEST_COVERAGE_REPORT_v1.0.csv | 9 + docs/phase12/VARIANT_INVENTORY_v1.0.csv | 177 + docs/phase13/COMPONENT_VARIANT_UPDATE_v1.0.md | 7 + docs/phase13/HOMEPAGE_CONTENT_MODEL_v1.0.md | 39 + docs/phase13/HOMEPAGE_SECTION_MATRIX_v1.0.csv | 13 + docs/quality/MANUAL_QA_RESULTS_v1.0.csv | 18 + docs/quality/PHASE_11_COMMAND_LOG_v1.0.txt | 47 + docs/quality/PHASE_11_FILE_CHANGES_v1.0.txt | 89 + .../PHASE_11_VALIDATION_RESULTS_v1.0.json | 50 + .../PHASE_11_VALIDATION_RESULTS_v1.0.md | 62 + docs/quality/PHASE_12_COMMAND_LOG_v1.0.txt | 76 + docs/quality/PHASE_12_FILE_CHANGES_v1.0.txt | 61 + .../PHASE_12_HTTP_ROUTE_RESULTS_v1.0.json | 56 + .../PHASE_12_MANUAL_QA_RESULTS_v1.0.csv | 21 + .../PHASE_12_VALIDATION_RESULTS_v1.0.json | 162 + .../PHASE_12_VALIDATION_RESULTS_v1.0.md | 23 + ...ASE_12_VISUAL_REGRESSION_RESULTS_v1.0.json | 23 + docs/quality/PHASE_13_COMMAND_LOG_v1.0.txt | 14 + docs/quality/PHASE_13_FILE_CHANGES_v1.0.txt | 26 + .../PHASE_13_HTTP_ROUTE_RESULTS_v1.0.json | 30 + .../PHASE_13_MANUAL_QA_RESULTS_v1.0.csv | 11 + .../PHASE_13_VALIDATION_RESULTS_v1.0.json | 85 + .../PHASE_13_VALIDATION_RESULTS_v1.0.md | 41 + docs/quality/VALIDATION_RESULTS_v1.0.json | 32 + docs/quality/VALIDATION_RESULTS_v1.0.md | 33 + .../VISUAL_REGRESSION_RESULTS_v1.0.json | 20 + docs/quality/logs/build-initial.log | 29 + .../logs/build-missing-site-origin.exit | 1 + .../logs/build-missing-site-origin.log | 19 + docs/quality/logs/build.exit | 1 + docs/quality/logs/build.log | 29 + docs/quality/logs/file-diff-summary.log | 47 + docs/quality/logs/format-check.exit | 1 + docs/quality/logs/format-check.log | 6 + docs/quality/logs/format-write.exit | 1 + docs/quality/logs/format-write.log | 222 + docs/quality/logs/lint.exit | 1 + docs/quality/logs/lint.log | 4 + docs/quality/logs/next-typegen.exit | 1 + docs/quality/logs/next-typegen.log | 2 + docs/quality/logs/npm-install-fallback.log | 7 + docs/quality/logs/playwright-browser-a11y.log | 57 + .../logs/playwright-test-inventory.log | 47 + docs/quality/logs/pnpm-audit.log | 3 + docs/quality/logs/pnpm-install-frozen.log | 30 + docs/quality/logs/standalone-server.log | 4 + docs/quality/logs/typecheck.exit | 1 + docs/quality/logs/typecheck.log | 4 + docs/quality/logs/unit.exit | 1 + docs/quality/logs/unit.log | 34 + docs/quality/logs/validate.exit | 1 + docs/quality/logs/validate.log | 14 + eslint.config.mjs | 40 + next-env.d.ts | 6 + next.config.ts | 10 + package.json | 72 + playwright.config.ts | 57 + pnpm-lock.yaml | 5135 +++++++++++++++++ pnpm-workspace.yaml | 21 + prettier.config.mjs | 9 + public/.gitkeep | 0 scripts/generate-phase10-manifest.mjs | 55 + scripts/generate-phase11-manifest.mjs | 55 + scripts/generate-phase12-manifest.mjs | 52 + scripts/generate-phase13-manifest.mjs | 56 + scripts/lib.mjs | 46 + scripts/prepare-standalone.mjs | 24 + scripts/run-checks.mjs | 19 + scripts/run-validations.mjs | 19 + scripts/validate-css-logical.mjs | 26 + scripts/validate-locales.mjs | 47 + scripts/validate-metadata.mjs | 39 + scripts/validate-phase10-manifest.mjs | 30 + scripts/validate-phase11-foundation.mjs | 89 + scripts/validate-phase11-manifest.mjs | 87 + scripts/validate-phase12-components.mjs | 97 + scripts/validate-phase12-manifest.mjs | 65 + scripts/validate-phase13-homepage.mjs | 68 + scripts/validate-phase13-manifest.mjs | 69 + scripts/validate-phase9-contract.mjs | 41 + scripts/validate-prohibited-content.mjs | 28 + scripts/validate-routes.mjs | 50 + scripts/validate-runtime-dependencies.mjs | 55 + scripts/validate-tokens.mjs | 50 + src/app/[locale]/[slug]/page.tsx | 70 + .../component-lab/ComponentLabInteractive.tsx | 96 + .../[locale]/component-lab/page.module.css | 32 + src/app/[locale]/component-lab/page.tsx | 81 + src/app/[locale]/error.tsx | 23 + src/app/[locale]/layout.tsx | 70 + src/app/[locale]/loading.tsx | 5 + src/app/[locale]/not-found.tsx | 5 + src/app/[locale]/page.module.css | 219 + src/app/[locale]/page.tsx | 334 ++ src/app/robots.ts | 11 + src/components/actions/ActionLink.module.css | 59 + src/components/actions/ActionLink.tsx | 76 + src/components/actions/Button.module.css | 139 + src/components/actions/Button.tsx | 97 + src/components/app-shell/BrandLink.tsx | 22 + src/components/app-shell/Controls.module.css | 38 + src/components/app-shell/DisabledAction.tsx | 29 + src/components/app-shell/HeaderNavigation.tsx | 57 + src/components/app-shell/LocaleSelector.tsx | 52 + src/components/app-shell/LocalizedLoading.tsx | 15 + .../app-shell/LocalizedNotFound.tsx | 20 + src/components/app-shell/MobileNavigation.tsx | 135 + .../app-shell/SiteFooter.module.css | 118 + src/components/app-shell/SiteFooter.tsx | 153 + .../app-shell/SiteHeader.module.css | 263 + src/components/app-shell/SiteHeader.tsx | 69 + .../app-shell/StateShell.module.css | 104 + src/components/app-shell/StateShell.tsx | 55 + src/components/app-shell/ThemeController.tsx | 31 + src/components/app-shell/ThemeSelector.tsx | 74 + src/components/controls/Accordion.module.css | 41 + src/components/controls/Accordion.tsx | 33 + src/components/controls/Pagination.module.css | 33 + src/components/controls/Pagination.tsx | 51 + .../controls/SegmentedControl.module.css | 31 + src/components/controls/SegmentedControl.tsx | 44 + src/components/controls/Tabs.module.css | 33 + src/components/controls/Tabs.tsx | 116 + src/components/feedback/Alert.module.css | 34 + src/components/feedback/Alert.tsx | 45 + src/components/feedback/Loading.module.css | 43 + src/components/feedback/Loading.tsx | 38 + src/components/feedback/Progress.module.css | 16 + src/components/feedback/Progress.tsx | 31 + .../feedback/StateMessage.module.css | 17 + src/components/feedback/StateMessage.tsx | 25 + .../forms/ChoiceControls.module.css | 77 + src/components/forms/ChoiceControls.tsx | 58 + src/components/forms/ErrorSummary.module.css | 24 + src/components/forms/ErrorSummary.tsx | 31 + src/components/forms/FormField.module.css | 47 + src/components/forms/FormField.tsx | 69 + src/components/forms/TextInput.module.css | 43 + src/components/forms/TextInput.tsx | 91 + src/components/foundation/AccessibleIcon.tsx | 17 + src/components/foundation/BidiText.module.css | 3 + src/components/foundation/BidiText.tsx | 23 + src/components/foundation/Icon.module.css | 25 + src/components/foundation/Icon.tsx | 139 + .../foundation/LiveRegion.module.css | 11 + src/components/foundation/LiveRegion.tsx | 15 + .../foundation/StatusBadge.module.css | 34 + src/components/foundation/StatusBadge.tsx | 29 + src/components/foundation/VisuallyHidden.tsx | 14 + src/components/foundation/client-hooks.ts | 74 + .../layout/LayoutPrimitives.module.css | 81 + src/components/layout/LayoutPrimitives.tsx | 92 + src/components/marketing/CTA.module.css | 42 + src/components/marketing/CTA.tsx | 65 + .../marketing/Comparison.module.css | 35 + src/components/marketing/Comparison.tsx | 51 + src/components/marketing/Evidence.module.css | 25 + src/components/marketing/Evidence.tsx | 81 + .../marketing/FeatureCard.module.css | 18 + src/components/marketing/FeatureCard.tsx | 50 + .../marketing/ProductPreview.module.css | 69 + src/components/marketing/ProductPreview.tsx | 71 + .../marketing/SectionHeader.module.css | 13 + src/components/marketing/SectionHeader.tsx | 31 + .../marketing/SectionPatterns.module.css | 44 + src/components/marketing/SectionPatterns.tsx | 36 + src/components/marketing/Workflow.module.css | 48 + src/components/marketing/Workflow.tsx | 43 + src/components/media/MediaFrame.module.css | 39 + src/components/media/MediaFrame.tsx | 47 + .../navigation/Breadcrumbs.module.css | 18 + src/components/navigation/Breadcrumbs.tsx | 39 + .../navigation/FooterLinkGroup.module.css | 11 + src/components/navigation/FooterLinkGroup.tsx | 30 + .../navigation/SectionNavigation.module.css | 20 + .../navigation/SectionNavigation.tsx | 35 + src/components/overlays/Dialog.module.css | 71 + src/components/overlays/Dialog.tsx | 99 + .../overlays/DropdownMenu.module.css | 39 + src/components/overlays/DropdownMenu.tsx | 90 + src/components/overlays/Tooltip.module.css | 41 + src/components/overlays/Tooltip.tsx | 22 + src/components/surfaces/Callout.module.css | 16 + src/components/surfaces/Callout.tsx | 23 + src/components/surfaces/Card.module.css | 50 + src/components/surfaces/Card.tsx | 43 + .../typography/Typography.module.css | 70 + src/components/typography/Typography.tsx | 67 + src/content/development/component-lab.ts | 373 ++ src/content/homepage-model.ts | 273 + src/content/locales/ar/homepage.json | 296 + src/content/locales/ar/shell.json | 94 + src/content/locales/en/homepage.json | 308 + src/content/locales/en/shell.json | 100 + src/content/locales/fr/homepage.json | 327 ++ src/content/locales/fr/shell.json | 109 + src/contracts/phase9/analytics-contract.ts | 41 + src/contracts/phase9/analytics-event-spec.csv | 19 + src/contracts/phase9/component-contracts.ts | 136 + src/contracts/phase9/demo-form-contract.ts | 23 + src/contracts/phase9/design-tokens.json | 150 + src/contracts/phase9/performance-budgets.json | 28 + src/contracts/phase9/route-manifest.json | 68 + .../phase9/visual-regression-scenarios.json | 62 + src/lib/components/classNames.ts | 3 + src/lib/localization/client-messages.ts | 15 + src/lib/localization/client.ts | 18 + src/lib/localization/config.ts | 140 + src/lib/localization/format.ts | 88 + src/lib/localization/messages.ts | 26 + src/lib/localization/site-origin.ts | 22 + src/lib/metadata/build-metadata.ts | 57 + src/lib/security/csp.ts | 25 + src/lib/theme/bootstrap-script.ts | 13 + src/lib/theme/client.ts | 44 + src/lib/theme/config.ts | 19 + src/proxy.ts | 71 + src/styles/component-tokens.css | 127 + src/styles/globals.css | 156 + src/styles/tokens.css | 122 + tests/a11y/component-system.a11y.spec.ts | 12 + tests/a11y/homepage.a11y.spec.ts | 24 + tests/a11y/shell.a11y.spec.ts | 27 + tests/browser/component-system.spec.ts | 45 + tests/browser/homepage.spec.ts | 51 + tests/browser/navigation.spec.ts | 28 + tests/browser/no-javascript.spec.ts | 12 + tests/browser/responsive.spec.ts | 24 + tests/browser/shell.spec.ts | 58 + tests/browser/text-expansion.spec.ts | 20 + tests/browser/theme-csp.spec.ts | 58 + tests/fixtures/README.md | 5 + .../component-system/component-matrix.json | 9 + tests/fixtures/foundation-matrix.json | 22 + tests/setup.ts | 1 + tests/types/component-contracts.test-d.tsx | 16 + tests/unit/components/actions.test.tsx | 35 + tests/unit/components/controls.test.tsx | 31 + tests/unit/components/evidence.test.tsx | 39 + tests/unit/components/forms.test.tsx | 41 + tests/unit/csp.test.ts | 20 + tests/unit/format.test.ts | 40 + tests/unit/homepage-content.test.ts | 42 + tests/unit/localization.test.ts | 58 + tests/unit/theme.test.ts | 18 + tests/visual/README.md | 10 + tests/visual/component-system.visual.spec.ts | 20 + tests/visual/homepage.visual.spec.ts | 30 + tests/visual/shell.visual.spec.ts | 63 + tsconfig.json | 45 + vitest.config.ts | 29 + 349 files changed, 31330 insertions(+) create mode 100644 CONTRIBUTING.md create mode 100644 Dockerfile create mode 100644 PHASE_10_PACKAGE_MANIFEST_v1.0.json create mode 100644 PHASE_11_PACKAGE_MANIFEST_v1.0.json create mode 100644 PHASE_12_PACKAGE_MANIFEST_v1.0.json create mode 100644 PHASE_13_PACKAGE_MANIFEST_v1.0.json create mode 100644 README 2.md create mode 100644 contracts/phase9/09_DEVELOPER_HANDOFF_v1.0.md create mode 100644 contracts/phase9/DECISION_LOG_v9.0.md create mode 100644 contracts/phase9/DEFINITION_OF_DONE_v1.0.md create mode 100644 contracts/phase9/OPEN_ISSUE_REGISTER_v1.0.csv create mode 100644 contracts/phase9/OPEN_QUESTIONS_v1.0.md create mode 100644 contracts/phase9/PACKAGE_MANIFEST_v1.0.json create mode 100644 contracts/phase9/PHASE_9_HANDOFF_v1.0.md create mode 100644 contracts/phase9/README_v1.0.md create mode 100644 contracts/phase9/SOURCE_TRACEABILITY_v1.0.csv create mode 100644 contracts/phase9/annotated/ANNOTATION_INDEX_v1.0.md create mode 100644 contracts/phase9/annotated/SCREEN_ANNOTATIONS_v1.0.csv create mode 100644 contracts/phase9/annotated/demo-dialog-en-light_v1.0.png create mode 100644 contracts/phase9/annotated/desktop-en-light_v1.0.png create mode 100644 contracts/phase9/annotated/mobile-ar-dark_v1.0.png create mode 100644 contracts/phase9/annotated/mobile-drawer-ar-dark_v1.0.png create mode 100644 contracts/phase9/annotated/tablet-fr-light_v1.0.png create mode 100644 contracts/phase9/annotated/tour-dialog-fr-dark_v1.0.png create mode 100644 contracts/phase9/assets/ASSET_MANIFEST_v1.0.csv create mode 100644 contracts/phase9/assets/ASSET_USAGE_RULES_v1.0.md create mode 100644 contracts/phase9/assets/brand-mark_v1.0.svg create mode 100644 contracts/phase9/assets/logo-horizontal_v1.0.svg create mode 100644 contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md create mode 100644 contracts/phase9/components/COMPONENT_STATE_MATRIX_v1.0.csv create mode 100644 contracts/phase9/components/CONTENT_CONSTRAINTS_v1.0.csv create mode 100644 contracts/phase9/components/RESPONSIVE_BEHAVIOR_MATRIX_v1.0.csv create mode 100644 contracts/phase9/components/RTL_THEME_MATRIX_v1.0.csv create mode 100644 contracts/phase9/implementation/TECHNOLOGY_PROFILE_v1.0.md create mode 100644 contracts/phase9/implementation/component-contracts_v1.0.ts create mode 100644 contracts/phase9/implementation/hreflang-generator_v1.0.ts create mode 100644 contracts/phase9/implementation/localization-config_v1.0.ts create mode 100644 contracts/phase9/implementation/theme-config_v1.0.ts create mode 100644 contracts/phase9/interaction/ANALYTICS_EVENT_SPEC_v1.0.csv create mode 100644 contracts/phase9/interaction/INTERACTION_NOTES_v1.0.md create mode 100644 contracts/phase9/interaction/analytics-contract_v1.0.ts create mode 100644 contracts/phase9/interaction/demo-form-contract_v1.0.ts create mode 100644 contracts/phase9/interaction/theme-bootstrap_v1.0.js create mode 100644 contracts/phase9/localization/LOCALIZATION_IMPLEMENTATION_v1.0.md create mode 100644 contracts/phase9/localization/ROUTE_MANIFEST_v1.0.json create mode 100644 contracts/phase9/localization/TRANSLATION_KEY_INVENTORY_v1.0.csv create mode 100644 contracts/phase9/localization/locales/ar/homepage.json create mode 100644 contracts/phase9/localization/locales/en/homepage.json create mode 100644 contracts/phase9/localization/locales/fr/homepage.json create mode 100644 contracts/phase9/qa/ACCESSIBILITY_CHECKLIST_v1.0.csv create mode 100644 contracts/phase9/qa/BROWSER_SUPPORT_MATRIX_v1.0.csv create mode 100644 contracts/phase9/qa/PERFORMANCE_BUDGETS_v1.0.json create mode 100644 contracts/phase9/qa/PLAYWRIGHT_ACCEPTANCE_SPEC_v1.0.md create mode 100644 contracts/phase9/qa/QA_MATRIX_v1.0.csv create mode 100644 contracts/phase9/qa/test-ids_v1.0.csv create mode 100644 contracts/phase9/qa/validate-phase9-package_v1.0.mjs create mode 100644 contracts/phase9/qa/visual-regression-scenarios_v1.0.json create mode 100644 contracts/phase9/reference/FINDINGS_REPORT_v1.0.md create mode 100644 contracts/phase9/reference/PHASE_8_HANDOFF_v1.0.md create mode 100644 contracts/phase9/reference/PRIORITIZED_REVISIONS_v1.0.csv create mode 100644 contracts/phase9/reference/SUCCESS_METRICS_v1.0.csv create mode 100644 contracts/phase9/reference/VALIDATION_RESULTS_v1.0.md create mode 100644 contracts/phase9/tokens/TOKEN_USAGE_RULES_v1.0.md create mode 100644 contracts/phase9/tokens/design-tokens_v1.0.json create mode 100644 contracts/phase9/tokens/semantic-tokens_v1.0.css create mode 100644 contracts/phase9/tokens/tokens_v1.0.ts create mode 100644 contracts/phase9/validation/CONTENT_AND_STRUCTURE_VALIDATION_v1.0.json create mode 100644 contracts/phase9/validation/STATIC_VALIDATION_RESULTS_v1.0.json create mode 100644 contracts/phase9/validation/VALIDATION_RESULTS_v1.0.md create mode 100644 docs/BRAND_MIGRATION_v1.0.md create mode 100644 docs/DECISION_LOG_v12.0.md create mode 100644 docs/DECISION_LOG_v13.0.md create mode 100644 docs/DEPENDENCY_MANIFEST_v1.0.md create mode 100644 docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv create mode 100644 docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv create mode 100644 docs/IMPLEMENTATION_ISSUE_REGISTER_v1.2.csv create mode 100644 docs/IMPLEMENTATION_ISSUE_REGISTER_v1.3.csv create mode 100644 docs/PHASE_10_HANDOFF_v1.0.md create mode 100644 docs/PHASE_10_IMPLEMENTATION_REPORT_v1.0.md create mode 100644 docs/PHASE_11_IMPLEMENTATION_REPORT_v1.0.md create mode 100644 docs/PHASE_12_HANDOFF_v1.0.md create mode 100644 docs/PHASE_12_IMPLEMENTATION_REPORT_v1.0.md create mode 100644 docs/PHASE_13_HANDOFF_v1.0.md create mode 100644 docs/PHASE_13_IMPLEMENTATION_REPORT_v1.0.md create mode 100644 docs/TOKEN_IMPLEMENTATION_v1.0.md create mode 100644 docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md create mode 100644 docs/architecture/ADR-0002_PHASE_11_FOUNDATIONS.md create mode 100644 docs/architecture/ADR-0003_PHASE_12_COMPONENT_SYSTEM.md create mode 100644 docs/phase12/ACCESSIBILITY_BEHAVIOR_MATRIX_v1.0.csv create mode 100644 docs/phase12/BUNDLE_IMPACT_REPORT_v1.0.md create mode 100644 docs/phase12/COMPONENT_CATALOG_v1.0.md create mode 100644 docs/phase12/COMPONENT_INVENTORY_v1.0.json create mode 100644 docs/phase12/COMPONENT_SPECIFICATION_TRACEABILITY_v1.0.csv create mode 100644 docs/phase12/DEFINITION_OF_DONE_STATUS_v1.0.md create mode 100644 docs/phase12/DEPENDENCY_CHANGE_REPORT_v1.0.md create mode 100644 docs/phase12/RESPONSIVE_VALIDATION_MATRIX_v1.0.csv create mode 100644 docs/phase12/RTL_BEHAVIOR_MATRIX_UPDATE_v1.0.csv create mode 100644 docs/phase12/STORY_AND_FIXTURE_INVENTORY_v1.0.csv create mode 100644 docs/phase12/TEST_COVERAGE_REPORT_v1.0.csv create mode 100644 docs/phase12/VARIANT_INVENTORY_v1.0.csv create mode 100644 docs/phase13/COMPONENT_VARIANT_UPDATE_v1.0.md create mode 100644 docs/phase13/HOMEPAGE_CONTENT_MODEL_v1.0.md create mode 100644 docs/phase13/HOMEPAGE_SECTION_MATRIX_v1.0.csv create mode 100644 docs/quality/MANUAL_QA_RESULTS_v1.0.csv create mode 100644 docs/quality/PHASE_11_COMMAND_LOG_v1.0.txt create mode 100644 docs/quality/PHASE_11_FILE_CHANGES_v1.0.txt create mode 100644 docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.json create mode 100644 docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.md create mode 100644 docs/quality/PHASE_12_COMMAND_LOG_v1.0.txt create mode 100644 docs/quality/PHASE_12_FILE_CHANGES_v1.0.txt create mode 100644 docs/quality/PHASE_12_HTTP_ROUTE_RESULTS_v1.0.json create mode 100644 docs/quality/PHASE_12_MANUAL_QA_RESULTS_v1.0.csv create mode 100644 docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.json create mode 100644 docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.md create mode 100644 docs/quality/PHASE_12_VISUAL_REGRESSION_RESULTS_v1.0.json create mode 100644 docs/quality/PHASE_13_COMMAND_LOG_v1.0.txt create mode 100644 docs/quality/PHASE_13_FILE_CHANGES_v1.0.txt create mode 100644 docs/quality/PHASE_13_HTTP_ROUTE_RESULTS_v1.0.json create mode 100644 docs/quality/PHASE_13_MANUAL_QA_RESULTS_v1.0.csv create mode 100644 docs/quality/PHASE_13_VALIDATION_RESULTS_v1.0.json create mode 100644 docs/quality/PHASE_13_VALIDATION_RESULTS_v1.0.md create mode 100644 docs/quality/VALIDATION_RESULTS_v1.0.json create mode 100644 docs/quality/VALIDATION_RESULTS_v1.0.md create mode 100644 docs/quality/VISUAL_REGRESSION_RESULTS_v1.0.json create mode 100644 docs/quality/logs/build-initial.log create mode 100644 docs/quality/logs/build-missing-site-origin.exit create mode 100644 docs/quality/logs/build-missing-site-origin.log create mode 100644 docs/quality/logs/build.exit create mode 100644 docs/quality/logs/build.log create mode 100644 docs/quality/logs/file-diff-summary.log create mode 100644 docs/quality/logs/format-check.exit create mode 100644 docs/quality/logs/format-check.log create mode 100644 docs/quality/logs/format-write.exit create mode 100644 docs/quality/logs/format-write.log create mode 100644 docs/quality/logs/lint.exit create mode 100644 docs/quality/logs/lint.log create mode 100644 docs/quality/logs/next-typegen.exit create mode 100644 docs/quality/logs/next-typegen.log create mode 100644 docs/quality/logs/npm-install-fallback.log create mode 100644 docs/quality/logs/playwright-browser-a11y.log create mode 100644 docs/quality/logs/playwright-test-inventory.log create mode 100644 docs/quality/logs/pnpm-audit.log create mode 100644 docs/quality/logs/pnpm-install-frozen.log create mode 100644 docs/quality/logs/standalone-server.log create mode 100644 docs/quality/logs/typecheck.exit create mode 100644 docs/quality/logs/typecheck.log create mode 100644 docs/quality/logs/unit.exit create mode 100644 docs/quality/logs/unit.log create mode 100644 docs/quality/logs/validate.exit create mode 100644 docs/quality/logs/validate.log create mode 100644 eslint.config.mjs create mode 100644 next-env.d.ts create mode 100644 next.config.ts create mode 100644 package.json create mode 100644 playwright.config.ts create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml create mode 100644 prettier.config.mjs create mode 100644 public/.gitkeep create mode 100644 scripts/generate-phase10-manifest.mjs create mode 100644 scripts/generate-phase11-manifest.mjs create mode 100644 scripts/generate-phase12-manifest.mjs create mode 100644 scripts/generate-phase13-manifest.mjs create mode 100644 scripts/lib.mjs create mode 100644 scripts/prepare-standalone.mjs create mode 100644 scripts/run-checks.mjs create mode 100644 scripts/run-validations.mjs create mode 100644 scripts/validate-css-logical.mjs create mode 100644 scripts/validate-locales.mjs create mode 100644 scripts/validate-metadata.mjs create mode 100644 scripts/validate-phase10-manifest.mjs create mode 100644 scripts/validate-phase11-foundation.mjs create mode 100644 scripts/validate-phase11-manifest.mjs create mode 100644 scripts/validate-phase12-components.mjs create mode 100644 scripts/validate-phase12-manifest.mjs create mode 100644 scripts/validate-phase13-homepage.mjs create mode 100644 scripts/validate-phase13-manifest.mjs create mode 100644 scripts/validate-phase9-contract.mjs create mode 100644 scripts/validate-prohibited-content.mjs create mode 100644 scripts/validate-routes.mjs create mode 100644 scripts/validate-runtime-dependencies.mjs create mode 100644 scripts/validate-tokens.mjs create mode 100644 src/app/[locale]/[slug]/page.tsx create mode 100644 src/app/[locale]/component-lab/ComponentLabInteractive.tsx create mode 100644 src/app/[locale]/component-lab/page.module.css create mode 100644 src/app/[locale]/component-lab/page.tsx create mode 100644 src/app/[locale]/error.tsx create mode 100644 src/app/[locale]/layout.tsx create mode 100644 src/app/[locale]/loading.tsx create mode 100644 src/app/[locale]/not-found.tsx create mode 100644 src/app/[locale]/page.module.css create mode 100644 src/app/[locale]/page.tsx create mode 100644 src/app/robots.ts create mode 100644 src/components/actions/ActionLink.module.css create mode 100644 src/components/actions/ActionLink.tsx create mode 100644 src/components/actions/Button.module.css create mode 100644 src/components/actions/Button.tsx create mode 100644 src/components/app-shell/BrandLink.tsx create mode 100644 src/components/app-shell/Controls.module.css create mode 100644 src/components/app-shell/DisabledAction.tsx create mode 100644 src/components/app-shell/HeaderNavigation.tsx create mode 100644 src/components/app-shell/LocaleSelector.tsx create mode 100644 src/components/app-shell/LocalizedLoading.tsx create mode 100644 src/components/app-shell/LocalizedNotFound.tsx create mode 100644 src/components/app-shell/MobileNavigation.tsx create mode 100644 src/components/app-shell/SiteFooter.module.css create mode 100644 src/components/app-shell/SiteFooter.tsx create mode 100644 src/components/app-shell/SiteHeader.module.css create mode 100644 src/components/app-shell/SiteHeader.tsx create mode 100644 src/components/app-shell/StateShell.module.css create mode 100644 src/components/app-shell/StateShell.tsx create mode 100644 src/components/app-shell/ThemeController.tsx create mode 100644 src/components/app-shell/ThemeSelector.tsx create mode 100644 src/components/controls/Accordion.module.css create mode 100644 src/components/controls/Accordion.tsx create mode 100644 src/components/controls/Pagination.module.css create mode 100644 src/components/controls/Pagination.tsx create mode 100644 src/components/controls/SegmentedControl.module.css create mode 100644 src/components/controls/SegmentedControl.tsx create mode 100644 src/components/controls/Tabs.module.css create mode 100644 src/components/controls/Tabs.tsx create mode 100644 src/components/feedback/Alert.module.css create mode 100644 src/components/feedback/Alert.tsx create mode 100644 src/components/feedback/Loading.module.css create mode 100644 src/components/feedback/Loading.tsx create mode 100644 src/components/feedback/Progress.module.css create mode 100644 src/components/feedback/Progress.tsx create mode 100644 src/components/feedback/StateMessage.module.css create mode 100644 src/components/feedback/StateMessage.tsx create mode 100644 src/components/forms/ChoiceControls.module.css create mode 100644 src/components/forms/ChoiceControls.tsx create mode 100644 src/components/forms/ErrorSummary.module.css create mode 100644 src/components/forms/ErrorSummary.tsx create mode 100644 src/components/forms/FormField.module.css create mode 100644 src/components/forms/FormField.tsx create mode 100644 src/components/forms/TextInput.module.css create mode 100644 src/components/forms/TextInput.tsx create mode 100644 src/components/foundation/AccessibleIcon.tsx create mode 100644 src/components/foundation/BidiText.module.css create mode 100644 src/components/foundation/BidiText.tsx create mode 100644 src/components/foundation/Icon.module.css create mode 100644 src/components/foundation/Icon.tsx create mode 100644 src/components/foundation/LiveRegion.module.css create mode 100644 src/components/foundation/LiveRegion.tsx create mode 100644 src/components/foundation/StatusBadge.module.css create mode 100644 src/components/foundation/StatusBadge.tsx create mode 100644 src/components/foundation/VisuallyHidden.tsx create mode 100644 src/components/foundation/client-hooks.ts create mode 100644 src/components/layout/LayoutPrimitives.module.css create mode 100644 src/components/layout/LayoutPrimitives.tsx create mode 100644 src/components/marketing/CTA.module.css create mode 100644 src/components/marketing/CTA.tsx create mode 100644 src/components/marketing/Comparison.module.css create mode 100644 src/components/marketing/Comparison.tsx create mode 100644 src/components/marketing/Evidence.module.css create mode 100644 src/components/marketing/Evidence.tsx create mode 100644 src/components/marketing/FeatureCard.module.css create mode 100644 src/components/marketing/FeatureCard.tsx create mode 100644 src/components/marketing/ProductPreview.module.css create mode 100644 src/components/marketing/ProductPreview.tsx create mode 100644 src/components/marketing/SectionHeader.module.css create mode 100644 src/components/marketing/SectionHeader.tsx create mode 100644 src/components/marketing/SectionPatterns.module.css create mode 100644 src/components/marketing/SectionPatterns.tsx create mode 100644 src/components/marketing/Workflow.module.css create mode 100644 src/components/marketing/Workflow.tsx create mode 100644 src/components/media/MediaFrame.module.css create mode 100644 src/components/media/MediaFrame.tsx create mode 100644 src/components/navigation/Breadcrumbs.module.css create mode 100644 src/components/navigation/Breadcrumbs.tsx create mode 100644 src/components/navigation/FooterLinkGroup.module.css create mode 100644 src/components/navigation/FooterLinkGroup.tsx create mode 100644 src/components/navigation/SectionNavigation.module.css create mode 100644 src/components/navigation/SectionNavigation.tsx create mode 100644 src/components/overlays/Dialog.module.css create mode 100644 src/components/overlays/Dialog.tsx create mode 100644 src/components/overlays/DropdownMenu.module.css create mode 100644 src/components/overlays/DropdownMenu.tsx create mode 100644 src/components/overlays/Tooltip.module.css create mode 100644 src/components/overlays/Tooltip.tsx create mode 100644 src/components/surfaces/Callout.module.css create mode 100644 src/components/surfaces/Callout.tsx create mode 100644 src/components/surfaces/Card.module.css create mode 100644 src/components/surfaces/Card.tsx create mode 100644 src/components/typography/Typography.module.css create mode 100644 src/components/typography/Typography.tsx create mode 100644 src/content/development/component-lab.ts create mode 100644 src/content/homepage-model.ts create mode 100644 src/content/locales/ar/homepage.json create mode 100644 src/content/locales/ar/shell.json create mode 100644 src/content/locales/en/homepage.json create mode 100644 src/content/locales/en/shell.json create mode 100644 src/content/locales/fr/homepage.json create mode 100644 src/content/locales/fr/shell.json create mode 100644 src/contracts/phase9/analytics-contract.ts create mode 100644 src/contracts/phase9/analytics-event-spec.csv create mode 100644 src/contracts/phase9/component-contracts.ts create mode 100644 src/contracts/phase9/demo-form-contract.ts create mode 100644 src/contracts/phase9/design-tokens.json create mode 100644 src/contracts/phase9/performance-budgets.json create mode 100644 src/contracts/phase9/route-manifest.json create mode 100644 src/contracts/phase9/visual-regression-scenarios.json create mode 100644 src/lib/components/classNames.ts create mode 100644 src/lib/localization/client-messages.ts create mode 100644 src/lib/localization/client.ts create mode 100644 src/lib/localization/config.ts create mode 100644 src/lib/localization/format.ts create mode 100644 src/lib/localization/messages.ts create mode 100644 src/lib/localization/site-origin.ts create mode 100644 src/lib/metadata/build-metadata.ts create mode 100644 src/lib/security/csp.ts create mode 100644 src/lib/theme/bootstrap-script.ts create mode 100644 src/lib/theme/client.ts create mode 100644 src/lib/theme/config.ts create mode 100644 src/proxy.ts create mode 100644 src/styles/component-tokens.css create mode 100644 src/styles/globals.css create mode 100644 src/styles/tokens.css create mode 100644 tests/a11y/component-system.a11y.spec.ts create mode 100644 tests/a11y/homepage.a11y.spec.ts create mode 100644 tests/a11y/shell.a11y.spec.ts create mode 100644 tests/browser/component-system.spec.ts create mode 100644 tests/browser/homepage.spec.ts create mode 100644 tests/browser/navigation.spec.ts create mode 100644 tests/browser/no-javascript.spec.ts create mode 100644 tests/browser/responsive.spec.ts create mode 100644 tests/browser/shell.spec.ts create mode 100644 tests/browser/text-expansion.spec.ts create mode 100644 tests/browser/theme-csp.spec.ts create mode 100644 tests/fixtures/README.md create mode 100644 tests/fixtures/component-system/component-matrix.json create mode 100644 tests/fixtures/foundation-matrix.json create mode 100644 tests/setup.ts create mode 100644 tests/types/component-contracts.test-d.tsx create mode 100644 tests/unit/components/actions.test.tsx create mode 100644 tests/unit/components/controls.test.tsx create mode 100644 tests/unit/components/evidence.test.tsx create mode 100644 tests/unit/components/forms.test.tsx create mode 100644 tests/unit/csp.test.ts create mode 100644 tests/unit/format.test.ts create mode 100644 tests/unit/homepage-content.test.ts create mode 100644 tests/unit/localization.test.ts create mode 100644 tests/unit/theme.test.ts create mode 100644 tests/visual/README.md create mode 100644 tests/visual/component-system.visual.spec.ts create mode 100644 tests/visual/homepage.visual.spec.ts create mode 100644 tests/visual/shell.visual.spec.ts create mode 100644 tsconfig.json create mode 100644 vitest.config.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..6256091 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,39 @@ +# Contributing to RentalDriveGo Web + +## Required runtime + +Use Node.js `24.17.0` and pnpm `11.9.0`. Exact dependency versions and the frozen lockfile are part of the architecture contract, not optional decoration. + +## Before editing + +1. Read `docs/PHASE_12_HANDOFF_v1.0.md` for component rules. +2. Check `docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv` before adding copy, routes, claims, destinations, integrations, or evidence. +3. Preserve `contracts/phase9` byte-for-byte. +4. Consume component-facing tokens from `src/styles/component-tokens.css`. +5. Use translation resources and route IDs rather than hard-coded visible copy or paths. + +## Required checks + +```bash +pnpm install --frozen-lockfile +pnpm validate +pnpm format:check +pnpm lint +pnpm typecheck +pnpm test:unit +SITE_ORIGIN=http://127.0.0.1:3000 PUBLIC_RELEASE_APPROVED=false pnpm build +pnpm test:e2e +``` + +Before packaging a reviewed release candidate: + +```bash +pnpm manifest:generate +pnpm validate:package +``` + +Do not regenerate visual snapshots merely to silence a failure. A consistently wrong screenshot is still wrong, just more organized. + +## Architecture changes + +Changes to routing, localization loading, token authority, theme persistence, CSP, styling system, state management, metadata generation, or the server/client boundary require an ADR before implementation. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8e1772b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,30 @@ +# syntax=docker/dockerfile:1.7 +FROM node:24.17.0-bookworm-slim AS base +ENV PNPM_HOME=/pnpm +ENV PATH=$PNPM_HOME:$PATH +RUN corepack enable && corepack prepare pnpm@11.9.0 --activate +WORKDIR /app + +FROM base AS dependencies +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./ +RUN pnpm install --frozen-lockfile + +FROM base AS builder +COPY --from=dependencies /app/node_modules ./node_modules +COPY . . +ENV NEXT_TELEMETRY_DISABLED=1 +RUN pnpm validate && pnpm typecheck && pnpm lint && SITE_ORIGIN=http://127.0.0.1:3000 PUBLIC_RELEASE_APPROVED=false pnpm build + +FROM node:24.17.0-bookworm-slim AS runner +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 +ENV PORT=3000 +ENV HOSTNAME=0.0.0.0 +WORKDIR /app +RUN groupadd --system --gid 1001 nodejs && useradd --system --uid 1001 --gid nodejs nextjs +COPY --from=builder /app/public ./public +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static +USER nextjs +EXPOSE 3000 +CMD ["node", "server.js"] diff --git a/PHASE_10_PACKAGE_MANIFEST_v1.0.json b/PHASE_10_PACKAGE_MANIFEST_v1.0.json new file mode 100644 index 0000000..ea19a28 --- /dev/null +++ b/PHASE_10_PACKAGE_MANIFEST_v1.0.json @@ -0,0 +1,749 @@ +{ + "schema_version": "1.0", + "project": "RentalDriveGo", + "phase": 10, + "generated_at": "2026-06-25", + "excludes": [ + ".git", + ".next", + "node_modules", + "coverage", + "playwright-report", + "test-results", + "PHASE_10_PACKAGE_MANIFEST_v1.0.json", + "tsconfig.tsbuildinfo" + ], + "file_count": 146, + "files": [ + { + "path": ".dockerignore", + "bytes": 97, + "sha256": "d78b037a836881c2d63f074d525b8027b2ecb06fefe3af4d5356327ec01dc5e1" + }, + { + "path": ".editorconfig", + "bytes": 188, + "sha256": "a6b98ea7cb6d61ed8d430dd0dffa46c87012b5cf859d4ce7207898954951fdcd" + }, + { + "path": ".env.example", + "bytes": 221, + "sha256": "8b9baf40c7a324b56c2b0876f761070a995328843a0f56d7bf97bfeafd06b297" + }, + { + "path": ".github/dependabot.yml", + "bytes": 416, + "sha256": "0a9bdd1890c8fcb78f61f91071df45fecbdcfbbd48441f7da0dba266ba168d82" + }, + { + "path": ".github/workflows/ci.yml", + "bytes": 1705, + "sha256": "b6778e7919fd7e27c2ab77e460af402bcf170bcedd3a0bc0887af07b9c5890f1" + }, + { + "path": ".gitignore", + "bytes": 135, + "sha256": "01c7cded7467134f023106b85684e3ce5df721149fc3ff4af5e02ef79541bb14" + }, + { + "path": ".node-version", + "bytes": 8, + "sha256": "98182b41c9ce3357797985cf12dc3b0124490ef88bc918a905373e7688e6aec9" + }, + { + "path": ".npmrc", + "bytes": 146, + "sha256": "e696a3cc1b84316377f18da909b079072ce02383d16c8fed410f8cabbb9ac054" + }, + { + "path": ".nvmrc", + "bytes": 8, + "sha256": "98182b41c9ce3357797985cf12dc3b0124490ef88bc918a905373e7688e6aec9" + }, + { + "path": ".prettierignore", + "bytes": 129, + "sha256": "272622f9ebbe7cc23717e19053be7c49a6fc63353cad9be57f107cd96b96a142" + }, + { + "path": "contracts/phase9/09_DEVELOPER_HANDOFF_v1.0.md", + "bytes": 8091, + "sha256": "e82d486f1e566d1bf0263f1baa7dd8035ae62da5c36bb6bfa417e61331ec8d51" + }, + { + "path": "contracts/phase9/annotated/ANNOTATION_INDEX_v1.0.md", + "bytes": 685, + "sha256": "a2e87dfdb138409604cac4cc5f52375cce97940da7363f7778af30490699decd" + }, + { + "path": "contracts/phase9/annotated/demo-dialog-en-light_v1.0.png", + "bytes": 51457, + "sha256": "d91bf102100af48feac31478770f8bfdded994ac8b47f60845e4465c50462394" + }, + { + "path": "contracts/phase9/annotated/desktop-en-light_v1.0.png", + "bytes": 144908, + "sha256": "a4151a788317aa9bf8f7262f09f645ebdb54d4a3e1254ab5703ae37e8d3cec16" + }, + { + "path": "contracts/phase9/annotated/mobile-ar-dark_v1.0.png", + "bytes": 75193, + "sha256": "6adcaf68b48bacbf105b670e71edda078a60aa26b732831bd194e1cb9da11556" + }, + { + "path": "contracts/phase9/annotated/mobile-drawer-ar-dark_v1.0.png", + "bytes": 28321, + "sha256": "bc0c14447fb6e80ce904ffcb13c237b51eaa92723702191139bee59b0f7ebdeb" + }, + { + "path": "contracts/phase9/annotated/SCREEN_ANNOTATIONS_v1.0.csv", + "bytes": 1457, + "sha256": "d7b8120926a545f472b62a436b87d2a9d20320a4d95fcf90aa96162c50e8a6da" + }, + { + "path": "contracts/phase9/annotated/tablet-fr-light_v1.0.png", + "bytes": 102305, + "sha256": "dd526fe6859e470ea4c67b4c1ef511cfe0e11126561f86bcff07e57378084347" + }, + { + "path": "contracts/phase9/annotated/tour-dialog-fr-dark_v1.0.png", + "bytes": 94445, + "sha256": "2dd7b24f6505f16a565ac1b5490499ccdae91d0257de608c97c54b7d5b6c2c78" + }, + { + "path": "contracts/phase9/assets/ASSET_MANIFEST_v1.0.csv", + "bytes": 1049, + "sha256": "dd77547327096b4c4084ec8b9311aaff719e378a91f16c2b3ea39832d1bc7b3a" + }, + { + "path": "contracts/phase9/assets/ASSET_USAGE_RULES_v1.0.md", + "bytes": 747, + "sha256": "46821e8e6588a62eba860e4d228b2910a05aa60124610966bdc524a86921f658" + }, + { + "path": "contracts/phase9/assets/brand-mark_v1.0.svg", + "bytes": 443, + "sha256": "bcb3a3fb8037aec69d92da06f0d60fab969547b979a0112f12e6a5c2ab8efdaa" + }, + { + "path": "contracts/phase9/assets/logo-horizontal_v1.0.svg", + "bytes": 576, + "sha256": "04be1c45e1b6e85586efc6dbd36bf3e1e9275fa138a36b93cf6532bbd7409b02" + }, + { + "path": "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "bytes": 9800, + "sha256": "84b455fe725bff11b6ab54bb13373b1aa52991b062a36fad07db47a940187a53" + }, + { + "path": "contracts/phase9/components/COMPONENT_STATE_MATRIX_v1.0.csv", + "bytes": 4283, + "sha256": "c85f96f6d5e020a27c2bd44427a2c3aed3f3cad8657d88a22fc2de9ecd3f6cda" + }, + { + "path": "contracts/phase9/components/CONTENT_CONSTRAINTS_v1.0.csv", + "bytes": 1147, + "sha256": "f4d32b7775f856ff4aac775791566427e3cc340f39cd3f9845d8a3271167228b" + }, + { + "path": "contracts/phase9/components/RESPONSIVE_BEHAVIOR_MATRIX_v1.0.csv", + "bytes": 1416, + "sha256": "0e0e262c0388c37e41f5ab7f3e80835b8edb09e00a9264e81d92953743893353" + }, + { + "path": "contracts/phase9/components/RTL_THEME_MATRIX_v1.0.csv", + "bytes": 4048, + "sha256": "b47f4b3b4e50f1fed6b1b69523a05d61952773e95a966288bfba85dd414edb15" + }, + { + "path": "contracts/phase9/DECISION_LOG_v9.0.md", + "bytes": 38775, + "sha256": "85569a7418f8cad57d094ee9ec1d83b7727b5ab91a405cbda26de0271a8d76a1" + }, + { + "path": "contracts/phase9/DEFINITION_OF_DONE_v1.0.md", + "bytes": 3234, + "sha256": "dfe53a550b7853f015901b83adb960ffb26ab08fa6d7f9f8f8a3386adc705179" + }, + { + "path": "contracts/phase9/implementation/component-contracts_v1.0.ts", + "bytes": 2844, + "sha256": "177dd2420b804290cf1296e43f41a7e759c8859b3253073fbdc523a81f6f94c0" + }, + { + "path": "contracts/phase9/implementation/hreflang-generator_v1.0.ts", + "bytes": 751, + "sha256": "ab919a36a5d08a28c38ae51b4ddd0d84cef5d3ec3bed13649ebd26c3fb80ac8a" + }, + { + "path": "contracts/phase9/implementation/localization-config_v1.0.ts", + "bytes": 772, + "sha256": "bd8ca09f121bfe516ece817948a81d58136e9205fbd2c05dad2ce87f2d7a1782" + }, + { + "path": "contracts/phase9/implementation/TECHNOLOGY_PROFILE_v1.0.md", + "bytes": 1953, + "sha256": "a59504c81bdbb6396eb21e68518ca84862ac89c6c65744de710e9ae273e47c7b" + }, + { + "path": "contracts/phase9/implementation/theme-config_v1.0.ts", + "bytes": 725, + "sha256": "f56d37da4129d5830ba9ebd77b18cd6084a144e8514bfd8a8152387ecf76607c" + }, + { + "path": "contracts/phase9/interaction/ANALYTICS_EVENT_SPEC_v1.0.csv", + "bytes": 1713, + "sha256": "1282ebca5b031f6267f8139033db437e30b62ac391d25823c8a4783b64151008" + }, + { + "path": "contracts/phase9/interaction/analytics-contract_v1.0.ts", + "bytes": 832, + "sha256": "2716eb69cc98032005e068ab7bdc265a4c896a8e1a1bed682c7fdd4f45368123" + }, + { + "path": "contracts/phase9/interaction/demo-form-contract_v1.0.ts", + "bytes": 632, + "sha256": "194db77f7cfca417dbe35e6f2c2ea94cdd02806b83b1d0f1993fe509d8c10154" + }, + { + "path": "contracts/phase9/interaction/INTERACTION_NOTES_v1.0.md", + "bytes": 2332, + "sha256": "0456815622cbb072f1a7594e6b47f52e572e2570280c3a618876246e1b43d2a7" + }, + { + "path": "contracts/phase9/interaction/theme-bootstrap_v1.0.js", + "bytes": 753, + "sha256": "7b89a849bdcd72e1049714ebf76f0c0decb39e44261480f0cb08bb7dfe734e4a" + }, + { + "path": "contracts/phase9/localization/locales/ar/homepage.json", + "bytes": 18615, + "sha256": "fe08aabd60203dbdebc718117f5e497b52a453a8a6fb671fe0bca28651bf0d47" + }, + { + "path": "contracts/phase9/localization/locales/en/homepage.json", + "bytes": 13869, + "sha256": "a5ed956c7f07fad016ca39b40b770c25e8beeae2799ff0fece82dbf087f18e51" + }, + { + "path": "contracts/phase9/localization/locales/fr/homepage.json", + "bytes": 15512, + "sha256": "24079356bd47431ffeb66b7eb2981e108c03080205861b1bb42514b03b945a0a" + }, + { + "path": "contracts/phase9/localization/LOCALIZATION_IMPLEMENTATION_v1.0.md", + "bytes": 2062, + "sha256": "87a494d7ef7ed9f5012ed1699edf90e38995aa89a0efc3800db854e1d57e1024" + }, + { + "path": "contracts/phase9/localization/ROUTE_MANIFEST_v1.0.json", + "bytes": 1573, + "sha256": "fa29b8d31da1f36f87d216a1228fd1bbe1cde337636950b40b0024a10efaf49a" + }, + { + "path": "contracts/phase9/localization/TRANSLATION_KEY_INVENTORY_v1.0.csv", + "bytes": 10599, + "sha256": "01289dc9eb94d546ae717b881b2aed4dfc63b38df38e7767054800122bbb46c2" + }, + { + "path": "contracts/phase9/OPEN_ISSUE_REGISTER_v1.0.csv", + "bytes": 3519, + "sha256": "b8778b3dc7d1e47446584cac046d490a9932c3dfdfa03750716f29852694a214" + }, + { + "path": "contracts/phase9/OPEN_QUESTIONS_v1.0.md", + "bytes": 1085, + "sha256": "82a2abd71830fa4023d346f3b42b138de9e1bbdff74a827d770e6b660d89bd0e" + }, + { + "path": "contracts/phase9/PACKAGE_MANIFEST_v1.0.json", + "bytes": 10649, + "sha256": "1a143f086f40f83414460bd4519e86bd3a34617079e3cfef4c5736375460a24e" + }, + { + "path": "contracts/phase9/PHASE_9_HANDOFF_v1.0.md", + "bytes": 939, + "sha256": "90530b4e70d1fd64d5d934429c009431902639c0570e7944cf050e6d67eb73a3" + }, + { + "path": "contracts/phase9/qa/ACCESSIBILITY_CHECKLIST_v1.0.csv", + "bytes": 1498, + "sha256": "0d9c108e0c02b78aaf11badf6b5f5125cac2b03876cfddf82bd2e97230fdd28b" + }, + { + "path": "contracts/phase9/qa/BROWSER_SUPPORT_MATRIX_v1.0.csv", + "bytes": 986, + "sha256": "5ffb43732fea90530b1b088fb68172b9fc7b2c2683198448734a21cf39c234d1" + }, + { + "path": "contracts/phase9/qa/PERFORMANCE_BUDGETS_v1.0.json", + "bytes": 815, + "sha256": "e1679ce45d8a1225c46c085c7533d3230a41279c32d0812de5c5f05cb55eefa8" + }, + { + "path": "contracts/phase9/qa/PLAYWRIGHT_ACCEPTANCE_SPEC_v1.0.md", + "bytes": 800, + "sha256": "b16384a861d06eb76db5a836868d9a6e03cf72a6a896209279330e19a8d1a785" + }, + { + "path": "contracts/phase9/qa/QA_MATRIX_v1.0.csv", + "bytes": 3557, + "sha256": "6b14b92ce20a9d706de7d6d4cf9f0bb450ecceed27673ed62ae01e145d2143f8" + }, + { + "path": "contracts/phase9/qa/test-ids_v1.0.csv", + "bytes": 598, + "sha256": "6201007ae98632654a2684a0b09ce95d85d9870e0f29774687df0a9876048202" + }, + { + "path": "contracts/phase9/qa/validate-phase9-package_v1.0.mjs", + "bytes": 2534, + "sha256": "631892318cf95c0530a605e5bf08def9b06c93af79b555205f3aeb8a2bcd87ed" + }, + { + "path": "contracts/phase9/qa/visual-regression-scenarios_v1.0.json", + "bytes": 1401, + "sha256": "08a04f676cbb93e73b4c6bc112a55ebf287cb97be3dd3176ab80161e6de743c2" + }, + { + "path": "contracts/phase9/README_v1.0.md", + "bytes": 1258, + "sha256": "ef0010b98ba641c4db453d875171a0d1dad4cb17e991ad23698acde8ac4783ae" + }, + { + "path": "contracts/phase9/reference/FINDINGS_REPORT_v1.0.md", + "bytes": 3062, + "sha256": "ba34afd535856d0eaa8ed7e174c23a7b5f0eae87344c8fcee5daafe00c068ce4" + }, + { + "path": "contracts/phase9/reference/PHASE_8_HANDOFF_v1.0.md", + "bytes": 1117, + "sha256": "2e51ed6645fcc99f30cd4aa9da11ac59e5c2e331c384bfbd758739ad6f42c788" + }, + { + "path": "contracts/phase9/reference/PRIORITIZED_REVISIONS_v1.0.csv", + "bytes": 1071, + "sha256": "65b17813756a2d01c8a9df9faa049b170dca197f243b62a44e070d69f8959df5" + }, + { + "path": "contracts/phase9/reference/SUCCESS_METRICS_v1.0.csv", + "bytes": 1552, + "sha256": "e7b734564735ab65dcaf84ab8374ba163472cca48db1257c4c626415a779ecbe" + }, + { + "path": "contracts/phase9/reference/VALIDATION_RESULTS_v1.0.md", + "bytes": 2068, + "sha256": "3cb17f099569e5bdf4bcd731fe7f687d1636f0e82623c205e07df2cdc2b7d2f2" + }, + { + "path": "contracts/phase9/SOURCE_TRACEABILITY_v1.0.csv", + "bytes": 765, + "sha256": "76dc8677ad0d50263301fd5242bc0649c23bb01d3bbd099bdc8a7e2c04fc2d46" + }, + { + "path": "contracts/phase9/tokens/design-tokens_v1.0.json", + "bytes": 3771, + "sha256": "470d7bc9d4a466cce4e51f0fdc21fe199ec5b0d4007f5063704c523ce1b9ef0c" + }, + { + "path": "contracts/phase9/tokens/semantic-tokens_v1.0.css", + "bytes": 3553, + "sha256": "99912762e078bfc78b4878fc46b8c7d03d90c073e9c236942a58d83f6585a1b9" + }, + { + "path": "contracts/phase9/tokens/TOKEN_USAGE_RULES_v1.0.md", + "bytes": 1222, + "sha256": "b9f7d9b0a9c0595e6f6df2a53e0bcf4acfb47a56abfc6c590a6281c15b04a7b2" + }, + { + "path": "contracts/phase9/tokens/tokens_v1.0.ts", + "bytes": 442, + "sha256": "ec265270251f8dd01d9166aeca3fcec9be2b5e534d825c9058fb6ed3f51e3224" + }, + { + "path": "contracts/phase9/validation/CONTENT_AND_STRUCTURE_VALIDATION_v1.0.json", + "bytes": 189, + "sha256": "e055ef15c2de2191a3465d85ed54f4cf6bd9e1cde4d5d2bba787e14873027b73" + }, + { + "path": "contracts/phase9/validation/STATIC_VALIDATION_RESULTS_v1.0.json", + "bytes": 56, + "sha256": "b60367adf55cf4c61b705d11131b7adebc0aae6ff53732c8272ec9cf2bc95dd3" + }, + { + "path": "contracts/phase9/validation/VALIDATION_RESULTS_v1.0.md", + "bytes": 1179, + "sha256": "6f9df81e75d7149d3826ce215143c21784f39b154660fcefc5325ac114ac70b2" + }, + { + "path": "Dockerfile", + "bytes": 1033, + "sha256": "5e586fd24911d9635ac45d36b9dcba24a44c8eb161b61df7d931f1103e0d70f2" + }, + { + "path": "docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md", + "bytes": 8931, + "sha256": "e2933f3ff3bd9c3066027e20049805fbc2e1ce720534998882f110024afba375" + }, + { + "path": "docs/BRAND_MIGRATION_v1.0.md", + "bytes": 1322, + "sha256": "b1fb78b8a0c50b629c8f3af36ec841aa2126739008069a80021b18f8219a3d1c" + }, + { + "path": "docs/DEPENDENCY_MANIFEST_v1.0.md", + "bytes": 4109, + "sha256": "0dfdaf10352a56b1468ad35436dd873a16d12171e3ea14eac2268359ec02823a" + }, + { + "path": "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv", + "bytes": 5347, + "sha256": "4300820e10088d76f6407ee358a8cc1a3cab89fe6554f658fd770469c8c6c77d" + }, + { + "path": "docs/PHASE_10_HANDOFF_v1.0.md", + "bytes": 3370, + "sha256": "8cf52ee1b49cabbf0678da222413b0186ed982fb0c8cfc805482ca18eb1fefc7" + }, + { + "path": "docs/PHASE_10_IMPLEMENTATION_REPORT_v1.0.md", + "bytes": 6805, + "sha256": "6a2e5da443bf15351a0e88e5c92117c8f7c780509d51f2e44c4a148a26a6d4e2" + }, + { + "path": "docs/quality/VALIDATION_RESULTS_v1.0.json", + "bytes": 1397, + "sha256": "9b663f7667620496bcbd872e3fc06c725adfb7dbbf6d7bfe8848896f400105d7" + }, + { + "path": "docs/quality/VALIDATION_RESULTS_v1.0.md", + "bytes": 4623, + "sha256": "47d44ee6095cb0bc68fe23148c98403d39309edbb4dd6acdf4a696019e9f0065" + }, + { + "path": "eslint.config.mjs", + "bytes": 1031, + "sha256": "14ef56a9899d4c5440c6fe71e713f321b1e1db3de2041b6ad13cd8f798a5225d" + }, + { + "path": "next-env.d.ts", + "bytes": 247, + "sha256": "7b550dda9686c16f36a17bf9051d5dbf31e98555b30d114ac49fc49a1e712651" + }, + { + "path": "next.config.ts", + "bytes": 198, + "sha256": "cd5d6988c4b5ba3b924c236876af7df12edf1f6df71d654ed67500ad450a48eb" + }, + { + "path": "package.json", + "bytes": 2475, + "sha256": "40f66cebb737aa1c8ddb5d93c1bb8fabdf241a73d66dd28de55f0ecd7bf1b1f5" + }, + { + "path": "playwright.config.ts", + "bytes": 1598, + "sha256": "21d4bf2dfc8b8f3b31a411bef9ea2d264f89b21030d778867efff5c8821ad579" + }, + { + "path": "pnpm-lock.yaml", + "bytes": 168864, + "sha256": "c8b40337671246d5a691a4c2c322f6ed184c6b7f99c10095519cf768eb1ace3d" + }, + { + "path": "pnpm-workspace.yaml", + "bytes": 338, + "sha256": "568eba518a28bcd58534a51483092d0a27919aefaec2446e6dd5c6d6ddd80160" + }, + { + "path": "prettier.config.mjs", + "bytes": 164, + "sha256": "2d5316ad27ef10ead128dd2ee82e11b79f067fcf25ea6d504624966739260335" + }, + { + "path": "public/.gitkeep", + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "path": "README.md", + "bytes": 2279, + "sha256": "83218f88d0cebd5c0f27a36c5b0af931437b23d7fb2bde7fe04eb589867311fc" + }, + { + "path": "scripts/generate-phase10-manifest.mjs", + "bytes": 1800, + "sha256": "6917fd46f99aacf9de7c89f058380facbf4c8c4adf0baaafb0bf7d1333497808" + }, + { + "path": "scripts/lib.mjs", + "bytes": 1446, + "sha256": "81c8af9b271572e92ade805dd317dc8738647efe8e89cb37a7c9d1873b5d5edc" + }, + { + "path": "scripts/prepare-standalone.mjs", + "bytes": 813, + "sha256": "f1c1398022048160d71ae14bfa53dd2e431dd2f5aca8f39571de159259af535b" + }, + { + "path": "scripts/run-checks.mjs", + "bytes": 600, + "sha256": "aa1d0192134b288c86ffe68b314b2e379d7865d2e8d5ad0d1f7b29c8e744c7ee" + }, + { + "path": "scripts/run-validations.mjs", + "bytes": 468, + "sha256": "ebbcc54935bee9cc92d05e0871d31ae0f2218ebbf1712118bfdc5c150a8438bf" + }, + { + "path": "scripts/validate-css-logical.mjs", + "bytes": 943, + "sha256": "d47f0346ba94621442c5dc700b53a0219ade3dda7485b4c7f49fb384738c424c" + }, + { + "path": "scripts/validate-locales.mjs", + "bytes": 1875, + "sha256": "dfaf3f34079ea571b17dd2d71d0abf47b48be924818b39c5df93495188b95f43" + }, + { + "path": "scripts/validate-phase10-manifest.mjs", + "bytes": 1192, + "sha256": "29386f182d08ee9096e51a01ea115ae145023724f3d8527fc3ac550152f34d20" + }, + { + "path": "scripts/validate-phase9-contract.mjs", + "bytes": 1424, + "sha256": "5fce16d33bf6cf7d95136b89f62fd595f109c5d003d54652998dfe3e5b866d6e" + }, + { + "path": "scripts/validate-prohibited-content.mjs", + "bytes": 1057, + "sha256": "a5977c8dae45a632ee1d90d93bd933a09e0b4bf0be0c4c9d858cb539d2b340cd" + }, + { + "path": "scripts/validate-routes.mjs", + "bytes": 1293, + "sha256": "63b4cdf3e4336987563b0e4881843a71381a8ccc6ef0e4fbe182f98ed7055675" + }, + { + "path": "scripts/validate-tokens.mjs", + "bytes": 1682, + "sha256": "a508dbee00fe1f991d4f09c2072719e508eb9e14f3ab7d474ba67ca826f45557" + }, + { + "path": "src/app/[locale]/layout.tsx", + "bytes": 2188, + "sha256": "f4e261b06bee967dd340f3c456eebcfd2b3f780de28499195d9185a7ecbc165b" + }, + { + "path": "src/app/[locale]/page.module.css", + "bytes": 985, + "sha256": "ae34228ae39d572ef8a154f4e4cde305419dab4e967512313ee7255392eec017" + }, + { + "path": "src/app/[locale]/page.tsx", + "bytes": 1792, + "sha256": "914d72f687565df88fea30ebf036b5c367682baf0eda35430e125206e552febe" + }, + { + "path": "src/app/robots.ts", + "bytes": 397, + "sha256": "6c1e263671da52c65da390bcbf38b2a11ec9c580a0072295cad11028e082900f" + }, + { + "path": "src/components/app-shell/LocaleSelector.tsx", + "bytes": 881, + "sha256": "cafa7b4095785297c065a7dcba8e6f0c7deb1a73cb7c7b7cce3b12fa04213b9a" + }, + { + "path": "src/components/app-shell/SiteHeader.module.css", + "bytes": 1355, + "sha256": "dd125d995a3f0acc459ac4c71910c065fcda0ea1996e7772683c53e00296c8eb" + }, + { + "path": "src/components/app-shell/SiteHeader.tsx", + "bytes": 1380, + "sha256": "953ac72f38b5bacc211adfe626b7c19339fe2c1c97ba60452484e7587688ab55" + }, + { + "path": "src/components/app-shell/ThemeController.tsx", + "bytes": 1017, + "sha256": "e3e646ff02c7480a191d4700971ba03b947ddff769687af1f3769e11cd740ce9" + }, + { + "path": "src/components/app-shell/ThemeSelector.tsx", + "bytes": 1040, + "sha256": "0f6baf74a2b2f90510d6d1f370f0ac6bdad313efab80c3bee0fc7de308fe5ad1" + }, + { + "path": "src/content/locales/ar/homepage.json", + "bytes": 17425, + "sha256": "6f0cba2a159531a55b72f345f760344b44bd670e3cd29685712a9215de5b1721" + }, + { + "path": "src/content/locales/ar/shell.json", + "bytes": 197, + "sha256": "80b5fbd63770def8fe1af4b2ae1fe499f4bb80b7c6643ef07f744f490ca534e4" + }, + { + "path": "src/content/locales/en/homepage.json", + "bytes": 12775, + "sha256": "c55d2883811bafd7262792169ebc19700e4a39721f9fe63a2baf096593140f8b" + }, + { + "path": "src/content/locales/en/shell.json", + "bytes": 130, + "sha256": "c7487774c8df58b6cd27a9a10bfbf092dfd6dc864d69d5d517191ce028496d17" + }, + { + "path": "src/content/locales/fr/homepage.json", + "bytes": 14570, + "sha256": "3d1e4143ff05d562bc8a86ff216840f7cb15168c27b982ae90a5e58bb73ecc6e" + }, + { + "path": "src/content/locales/fr/shell.json", + "bytes": 138, + "sha256": "f54ea4a7396d6868003db116c88959a0c3cc1ec66ef04b015896d1d088ee14d0" + }, + { + "path": "src/contracts/phase9/analytics-contract.ts", + "bytes": 918, + "sha256": "d79b32503a5f8346816c647b8a7f45a62468b96f4fc9525d6d5147b5d2f2ec45" + }, + { + "path": "src/contracts/phase9/analytics-event-spec.csv", + "bytes": 1713, + "sha256": "1282ebca5b031f6267f8139033db437e30b62ac391d25823c8a4783b64151008" + }, + { + "path": "src/contracts/phase9/component-contracts.ts", + "bytes": 3041, + "sha256": "45fb0222d99308b2f28014572316b13c2d7308bc16b1bd02f63b6e2257148399" + }, + { + "path": "src/contracts/phase9/demo-form-contract.ts", + "bytes": 699, + "sha256": "073cf70224f93312d177f77abd7987704205628209e30c44824ae45f929ee59e" + }, + { + "path": "src/contracts/phase9/design-tokens.json", + "bytes": 3771, + "sha256": "470d7bc9d4a466cce4e51f0fdc21fe199ec5b0d4007f5063704c523ce1b9ef0c" + }, + { + "path": "src/contracts/phase9/performance-budgets.json", + "bytes": 815, + "sha256": "e1679ce45d8a1225c46c085c7533d3230a41279c32d0812de5c5f05cb55eefa8" + }, + { + "path": "src/contracts/phase9/route-manifest.json", + "bytes": 1433, + "sha256": "e08ac94ba1f3899bb02dfa934695f530d1089f9f03b0fadaa0feabd466ad8ec4" + }, + { + "path": "src/contracts/phase9/visual-regression-scenarios.json", + "bytes": 1209, + "sha256": "27d961c33c32775485475f7037b8d3bbd13f634b65fe2f59d6eea898860edf5f" + }, + { + "path": "src/lib/localization/config.ts", + "bytes": 3907, + "sha256": "3868d2cfbdd9656d0bea1d17df82b2696d78b964712d0e525efa20244e42a186" + }, + { + "path": "src/lib/localization/messages.ts", + "bytes": 878, + "sha256": "9307df65a80b08e7e1ea7c4e16358fc5fcbde299a00810076bcb36d0a13f9ced" + }, + { + "path": "src/lib/localization/site-origin.ts", + "bytes": 771, + "sha256": "40400ce29fc4adbd9c4490b456968e41fc7596d77ac5bea1c65179e0e4e760ff" + }, + { + "path": "src/lib/security/csp.ts", + "bytes": 830, + "sha256": "f9244e061cc397fbe8720a055e5415b6df34e6c74d0c439ae8d25054d1239c5e" + }, + { + "path": "src/lib/theme/bootstrap-script.ts", + "bytes": 755, + "sha256": "ad1ac642ca61e133f41a5e5b3c062f1b23046f24a58565c6baaacf8c9b261f12" + }, + { + "path": "src/lib/theme/client.ts", + "bytes": 1130, + "sha256": "78663300bbdb2e639d1be58fb3f364171992fa63b720dc34d174e4fda2b7d4a8" + }, + { + "path": "src/lib/theme/config.ts", + "bytes": 821, + "sha256": "c04cd00ce7838fc964d5bdbfaa4c2380f7cd774a9d754987946c97ee8849e60c" + }, + { + "path": "src/proxy.ts", + "bytes": 2566, + "sha256": "16dcb2bdabd8b5bff91a6b8fe381c6714abd2b8f1d0156a75100c248b7195277" + }, + { + "path": "src/styles/globals.css", + "bytes": 1288, + "sha256": "b1ecbb8f758f45b3e9c9447a3f92e3475347bbe5d3e164f525fab6222efd7ff4" + }, + { + "path": "src/styles/tokens.css", + "bytes": 3553, + "sha256": "99912762e078bfc78b4878fc46b8c7d03d90c073e9c236942a58d83f6585a1b9" + }, + { + "path": "tests/a11y/shell.a11y.spec.ts", + "bytes": 781, + "sha256": "9f6299337a822d8e4f6783cbfbb3e5da02e42bcca99d8e4519d7f0193072b205" + }, + { + "path": "tests/browser/shell.spec.ts", + "bytes": 1336, + "sha256": "f46239d8bd4c9040f9a11cb85962c340770c941310dbb1eed38d58a91efe5dc8" + }, + { + "path": "tests/browser/theme-csp.spec.ts", + "bytes": 1350, + "sha256": "e11eb5c9842fb3c924e30a352c35b31d04159fdd26f8edea525ee1dacce94c73" + }, + { + "path": "tests/setup.ts", + "bytes": 43, + "sha256": "91a3c8962a0edcb956206a501d943fe99e1c78c6d4d8b5c9a948a3362c75978c" + }, + { + "path": "tests/unit/csp.test.ts", + "bytes": 969, + "sha256": "18e4aa4145976102239e92a9c147cc8f0b8442b1bce37b84888246b137280de9" + }, + { + "path": "tests/unit/localization.test.ts", + "bytes": 1860, + "sha256": "501c561559f46f9f599d730aee45d9d6a6880df3a3920f552325c6142e053e40" + }, + { + "path": "tests/unit/theme.test.ts", + "bytes": 734, + "sha256": "45f25fd23f69af3df199473053c47fe219c88fb36a58cffac20a125bdbd47433" + }, + { + "path": "tests/visual/shell.visual.spec.ts", + "bytes": 1079, + "sha256": "2e0fcfe68b9d056641b8b11256ecfd05219aa9429a2e20d0ec7ecc4db3e376a3" + }, + { + "path": "tsconfig.json", + "bytes": 1042, + "sha256": "3d16e624dcc305c31675190a283744e11177f07106f10a60d2e89c753695433b" + }, + { + "path": "vitest.config.ts", + "bytes": 699, + "sha256": "c2ac8f10ad2894df28a93e3d2bba2c213f24b9a044db25307078648e010dc3d5" + } + ] +} diff --git a/PHASE_11_PACKAGE_MANIFEST_v1.0.json b/PHASE_11_PACKAGE_MANIFEST_v1.0.json new file mode 100644 index 0000000..f23c898 --- /dev/null +++ b/PHASE_11_PACKAGE_MANIFEST_v1.0.json @@ -0,0 +1,1024 @@ +{ + "schema_version": "1.0", + "project": "RentalDriveGo", + "phase": 11, + "generated_at": "2026-06-25", + "excludes": [ + ".git", + ".next", + "node_modules", + "coverage", + "playwright-report", + "test-results", + "PHASE_11_PACKAGE_MANIFEST_v1.0.json", + "tsconfig.tsbuildinfo" + ], + "file_count": 201, + "files": [ + { + "path": ".dockerignore", + "bytes": 97, + "sha256": "d78b037a836881c2d63f074d525b8027b2ecb06fefe3af4d5356327ec01dc5e1" + }, + { + "path": ".editorconfig", + "bytes": 188, + "sha256": "a6b98ea7cb6d61ed8d430dd0dffa46c87012b5cf859d4ce7207898954951fdcd" + }, + { + "path": ".env.example", + "bytes": 221, + "sha256": "8b9baf40c7a324b56c2b0876f761070a995328843a0f56d7bf97bfeafd06b297" + }, + { + "path": ".github/dependabot.yml", + "bytes": 416, + "sha256": "0a9bdd1890c8fcb78f61f91071df45fecbdcfbbd48441f7da0dba266ba168d82" + }, + { + "path": ".github/workflows/ci.yml", + "bytes": 1739, + "sha256": "c3d1671011688d7ebc4be9f38265e82b290b1aefc9ddd237c1d82fafd3e765f4" + }, + { + "path": ".gitignore", + "bytes": 135, + "sha256": "01c7cded7467134f023106b85684e3ce5df721149fc3ff4af5e02ef79541bb14" + }, + { + "path": ".node-version", + "bytes": 8, + "sha256": "98182b41c9ce3357797985cf12dc3b0124490ef88bc918a905373e7688e6aec9" + }, + { + "path": ".npmrc", + "bytes": 146, + "sha256": "e696a3cc1b84316377f18da909b079072ce02383d16c8fed410f8cabbb9ac054" + }, + { + "path": ".nvmrc", + "bytes": 8, + "sha256": "98182b41c9ce3357797985cf12dc3b0124490ef88bc918a905373e7688e6aec9" + }, + { + "path": ".prettierignore", + "bytes": 129, + "sha256": "272622f9ebbe7cc23717e19053be7c49a6fc63353cad9be57f107cd96b96a142" + }, + { + "path": "contracts/phase9/09_DEVELOPER_HANDOFF_v1.0.md", + "bytes": 8091, + "sha256": "e82d486f1e566d1bf0263f1baa7dd8035ae62da5c36bb6bfa417e61331ec8d51" + }, + { + "path": "contracts/phase9/annotated/ANNOTATION_INDEX_v1.0.md", + "bytes": 685, + "sha256": "a2e87dfdb138409604cac4cc5f52375cce97940da7363f7778af30490699decd" + }, + { + "path": "contracts/phase9/annotated/demo-dialog-en-light_v1.0.png", + "bytes": 51457, + "sha256": "d91bf102100af48feac31478770f8bfdded994ac8b47f60845e4465c50462394" + }, + { + "path": "contracts/phase9/annotated/desktop-en-light_v1.0.png", + "bytes": 144908, + "sha256": "a4151a788317aa9bf8f7262f09f645ebdb54d4a3e1254ab5703ae37e8d3cec16" + }, + { + "path": "contracts/phase9/annotated/mobile-ar-dark_v1.0.png", + "bytes": 75193, + "sha256": "6adcaf68b48bacbf105b670e71edda078a60aa26b732831bd194e1cb9da11556" + }, + { + "path": "contracts/phase9/annotated/mobile-drawer-ar-dark_v1.0.png", + "bytes": 28321, + "sha256": "bc0c14447fb6e80ce904ffcb13c237b51eaa92723702191139bee59b0f7ebdeb" + }, + { + "path": "contracts/phase9/annotated/SCREEN_ANNOTATIONS_v1.0.csv", + "bytes": 1457, + "sha256": "d7b8120926a545f472b62a436b87d2a9d20320a4d95fcf90aa96162c50e8a6da" + }, + { + "path": "contracts/phase9/annotated/tablet-fr-light_v1.0.png", + "bytes": 102305, + "sha256": "dd526fe6859e470ea4c67b4c1ef511cfe0e11126561f86bcff07e57378084347" + }, + { + "path": "contracts/phase9/annotated/tour-dialog-fr-dark_v1.0.png", + "bytes": 94445, + "sha256": "2dd7b24f6505f16a565ac1b5490499ccdae91d0257de608c97c54b7d5b6c2c78" + }, + { + "path": "contracts/phase9/assets/ASSET_MANIFEST_v1.0.csv", + "bytes": 1049, + "sha256": "dd77547327096b4c4084ec8b9311aaff719e378a91f16c2b3ea39832d1bc7b3a" + }, + { + "path": "contracts/phase9/assets/ASSET_USAGE_RULES_v1.0.md", + "bytes": 747, + "sha256": "46821e8e6588a62eba860e4d228b2910a05aa60124610966bdc524a86921f658" + }, + { + "path": "contracts/phase9/assets/brand-mark_v1.0.svg", + "bytes": 443, + "sha256": "bcb3a3fb8037aec69d92da06f0d60fab969547b979a0112f12e6a5c2ab8efdaa" + }, + { + "path": "contracts/phase9/assets/logo-horizontal_v1.0.svg", + "bytes": 576, + "sha256": "04be1c45e1b6e85586efc6dbd36bf3e1e9275fa138a36b93cf6532bbd7409b02" + }, + { + "path": "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "bytes": 9800, + "sha256": "84b455fe725bff11b6ab54bb13373b1aa52991b062a36fad07db47a940187a53" + }, + { + "path": "contracts/phase9/components/COMPONENT_STATE_MATRIX_v1.0.csv", + "bytes": 4283, + "sha256": "c85f96f6d5e020a27c2bd44427a2c3aed3f3cad8657d88a22fc2de9ecd3f6cda" + }, + { + "path": "contracts/phase9/components/CONTENT_CONSTRAINTS_v1.0.csv", + "bytes": 1147, + "sha256": "f4d32b7775f856ff4aac775791566427e3cc340f39cd3f9845d8a3271167228b" + }, + { + "path": "contracts/phase9/components/RESPONSIVE_BEHAVIOR_MATRIX_v1.0.csv", + "bytes": 1416, + "sha256": "0e0e262c0388c37e41f5ab7f3e80835b8edb09e00a9264e81d92953743893353" + }, + { + "path": "contracts/phase9/components/RTL_THEME_MATRIX_v1.0.csv", + "bytes": 4048, + "sha256": "b47f4b3b4e50f1fed6b1b69523a05d61952773e95a966288bfba85dd414edb15" + }, + { + "path": "contracts/phase9/DECISION_LOG_v9.0.md", + "bytes": 38775, + "sha256": "85569a7418f8cad57d094ee9ec1d83b7727b5ab91a405cbda26de0271a8d76a1" + }, + { + "path": "contracts/phase9/DEFINITION_OF_DONE_v1.0.md", + "bytes": 3234, + "sha256": "dfe53a550b7853f015901b83adb960ffb26ab08fa6d7f9f8f8a3386adc705179" + }, + { + "path": "contracts/phase9/implementation/component-contracts_v1.0.ts", + "bytes": 2844, + "sha256": "177dd2420b804290cf1296e43f41a7e759c8859b3253073fbdc523a81f6f94c0" + }, + { + "path": "contracts/phase9/implementation/hreflang-generator_v1.0.ts", + "bytes": 751, + "sha256": "ab919a36a5d08a28c38ae51b4ddd0d84cef5d3ec3bed13649ebd26c3fb80ac8a" + }, + { + "path": "contracts/phase9/implementation/localization-config_v1.0.ts", + "bytes": 772, + "sha256": "bd8ca09f121bfe516ece817948a81d58136e9205fbd2c05dad2ce87f2d7a1782" + }, + { + "path": "contracts/phase9/implementation/TECHNOLOGY_PROFILE_v1.0.md", + "bytes": 1953, + "sha256": "a59504c81bdbb6396eb21e68518ca84862ac89c6c65744de710e9ae273e47c7b" + }, + { + "path": "contracts/phase9/implementation/theme-config_v1.0.ts", + "bytes": 725, + "sha256": "f56d37da4129d5830ba9ebd77b18cd6084a144e8514bfd8a8152387ecf76607c" + }, + { + "path": "contracts/phase9/interaction/ANALYTICS_EVENT_SPEC_v1.0.csv", + "bytes": 1713, + "sha256": "1282ebca5b031f6267f8139033db437e30b62ac391d25823c8a4783b64151008" + }, + { + "path": "contracts/phase9/interaction/analytics-contract_v1.0.ts", + "bytes": 832, + "sha256": "2716eb69cc98032005e068ab7bdc265a4c896a8e1a1bed682c7fdd4f45368123" + }, + { + "path": "contracts/phase9/interaction/demo-form-contract_v1.0.ts", + "bytes": 632, + "sha256": "194db77f7cfca417dbe35e6f2c2ea94cdd02806b83b1d0f1993fe509d8c10154" + }, + { + "path": "contracts/phase9/interaction/INTERACTION_NOTES_v1.0.md", + "bytes": 2332, + "sha256": "0456815622cbb072f1a7594e6b47f52e572e2570280c3a618876246e1b43d2a7" + }, + { + "path": "contracts/phase9/interaction/theme-bootstrap_v1.0.js", + "bytes": 753, + "sha256": "7b89a849bdcd72e1049714ebf76f0c0decb39e44261480f0cb08bb7dfe734e4a" + }, + { + "path": "contracts/phase9/localization/locales/ar/homepage.json", + "bytes": 18615, + "sha256": "fe08aabd60203dbdebc718117f5e497b52a453a8a6fb671fe0bca28651bf0d47" + }, + { + "path": "contracts/phase9/localization/locales/en/homepage.json", + "bytes": 13869, + "sha256": "a5ed956c7f07fad016ca39b40b770c25e8beeae2799ff0fece82dbf087f18e51" + }, + { + "path": "contracts/phase9/localization/locales/fr/homepage.json", + "bytes": 15512, + "sha256": "24079356bd47431ffeb66b7eb2981e108c03080205861b1bb42514b03b945a0a" + }, + { + "path": "contracts/phase9/localization/LOCALIZATION_IMPLEMENTATION_v1.0.md", + "bytes": 2062, + "sha256": "87a494d7ef7ed9f5012ed1699edf90e38995aa89a0efc3800db854e1d57e1024" + }, + { + "path": "contracts/phase9/localization/ROUTE_MANIFEST_v1.0.json", + "bytes": 1573, + "sha256": "fa29b8d31da1f36f87d216a1228fd1bbe1cde337636950b40b0024a10efaf49a" + }, + { + "path": "contracts/phase9/localization/TRANSLATION_KEY_INVENTORY_v1.0.csv", + "bytes": 10599, + "sha256": "01289dc9eb94d546ae717b881b2aed4dfc63b38df38e7767054800122bbb46c2" + }, + { + "path": "contracts/phase9/OPEN_ISSUE_REGISTER_v1.0.csv", + "bytes": 3519, + "sha256": "b8778b3dc7d1e47446584cac046d490a9932c3dfdfa03750716f29852694a214" + }, + { + "path": "contracts/phase9/OPEN_QUESTIONS_v1.0.md", + "bytes": 1085, + "sha256": "82a2abd71830fa4023d346f3b42b138de9e1bbdff74a827d770e6b660d89bd0e" + }, + { + "path": "contracts/phase9/PACKAGE_MANIFEST_v1.0.json", + "bytes": 10649, + "sha256": "1a143f086f40f83414460bd4519e86bd3a34617079e3cfef4c5736375460a24e" + }, + { + "path": "contracts/phase9/PHASE_9_HANDOFF_v1.0.md", + "bytes": 939, + "sha256": "90530b4e70d1fd64d5d934429c009431902639c0570e7944cf050e6d67eb73a3" + }, + { + "path": "contracts/phase9/qa/ACCESSIBILITY_CHECKLIST_v1.0.csv", + "bytes": 1498, + "sha256": "0d9c108e0c02b78aaf11badf6b5f5125cac2b03876cfddf82bd2e97230fdd28b" + }, + { + "path": "contracts/phase9/qa/BROWSER_SUPPORT_MATRIX_v1.0.csv", + "bytes": 986, + "sha256": "5ffb43732fea90530b1b088fb68172b9fc7b2c2683198448734a21cf39c234d1" + }, + { + "path": "contracts/phase9/qa/PERFORMANCE_BUDGETS_v1.0.json", + "bytes": 815, + "sha256": "e1679ce45d8a1225c46c085c7533d3230a41279c32d0812de5c5f05cb55eefa8" + }, + { + "path": "contracts/phase9/qa/PLAYWRIGHT_ACCEPTANCE_SPEC_v1.0.md", + "bytes": 800, + "sha256": "b16384a861d06eb76db5a836868d9a6e03cf72a6a896209279330e19a8d1a785" + }, + { + "path": "contracts/phase9/qa/QA_MATRIX_v1.0.csv", + "bytes": 3557, + "sha256": "6b14b92ce20a9d706de7d6d4cf9f0bb450ecceed27673ed62ae01e145d2143f8" + }, + { + "path": "contracts/phase9/qa/test-ids_v1.0.csv", + "bytes": 598, + "sha256": "6201007ae98632654a2684a0b09ce95d85d9870e0f29774687df0a9876048202" + }, + { + "path": "contracts/phase9/qa/validate-phase9-package_v1.0.mjs", + "bytes": 2534, + "sha256": "631892318cf95c0530a605e5bf08def9b06c93af79b555205f3aeb8a2bcd87ed" + }, + { + "path": "contracts/phase9/qa/visual-regression-scenarios_v1.0.json", + "bytes": 1401, + "sha256": "08a04f676cbb93e73b4c6bc112a55ebf287cb97be3dd3176ab80161e6de743c2" + }, + { + "path": "contracts/phase9/README_v1.0.md", + "bytes": 1258, + "sha256": "ef0010b98ba641c4db453d875171a0d1dad4cb17e991ad23698acde8ac4783ae" + }, + { + "path": "contracts/phase9/reference/FINDINGS_REPORT_v1.0.md", + "bytes": 3062, + "sha256": "ba34afd535856d0eaa8ed7e174c23a7b5f0eae87344c8fcee5daafe00c068ce4" + }, + { + "path": "contracts/phase9/reference/PHASE_8_HANDOFF_v1.0.md", + "bytes": 1117, + "sha256": "2e51ed6645fcc99f30cd4aa9da11ac59e5c2e331c384bfbd758739ad6f42c788" + }, + { + "path": "contracts/phase9/reference/PRIORITIZED_REVISIONS_v1.0.csv", + "bytes": 1071, + "sha256": "65b17813756a2d01c8a9df9faa049b170dca197f243b62a44e070d69f8959df5" + }, + { + "path": "contracts/phase9/reference/SUCCESS_METRICS_v1.0.csv", + "bytes": 1552, + "sha256": "e7b734564735ab65dcaf84ab8374ba163472cca48db1257c4c626415a779ecbe" + }, + { + "path": "contracts/phase9/reference/VALIDATION_RESULTS_v1.0.md", + "bytes": 2068, + "sha256": "3cb17f099569e5bdf4bcd731fe7f687d1636f0e82623c205e07df2cdc2b7d2f2" + }, + { + "path": "contracts/phase9/SOURCE_TRACEABILITY_v1.0.csv", + "bytes": 765, + "sha256": "76dc8677ad0d50263301fd5242bc0649c23bb01d3bbd099bdc8a7e2c04fc2d46" + }, + { + "path": "contracts/phase9/tokens/design-tokens_v1.0.json", + "bytes": 3771, + "sha256": "470d7bc9d4a466cce4e51f0fdc21fe199ec5b0d4007f5063704c523ce1b9ef0c" + }, + { + "path": "contracts/phase9/tokens/semantic-tokens_v1.0.css", + "bytes": 3553, + "sha256": "99912762e078bfc78b4878fc46b8c7d03d90c073e9c236942a58d83f6585a1b9" + }, + { + "path": "contracts/phase9/tokens/TOKEN_USAGE_RULES_v1.0.md", + "bytes": 1222, + "sha256": "b9f7d9b0a9c0595e6f6df2a53e0bcf4acfb47a56abfc6c590a6281c15b04a7b2" + }, + { + "path": "contracts/phase9/tokens/tokens_v1.0.ts", + "bytes": 442, + "sha256": "ec265270251f8dd01d9166aeca3fcec9be2b5e534d825c9058fb6ed3f51e3224" + }, + { + "path": "contracts/phase9/validation/CONTENT_AND_STRUCTURE_VALIDATION_v1.0.json", + "bytes": 189, + "sha256": "e055ef15c2de2191a3465d85ed54f4cf6bd9e1cde4d5d2bba787e14873027b73" + }, + { + "path": "contracts/phase9/validation/STATIC_VALIDATION_RESULTS_v1.0.json", + "bytes": 56, + "sha256": "b60367adf55cf4c61b705d11131b7adebc0aae6ff53732c8272ec9cf2bc95dd3" + }, + { + "path": "contracts/phase9/validation/VALIDATION_RESULTS_v1.0.md", + "bytes": 1179, + "sha256": "6f9df81e75d7149d3826ce215143c21784f39b154660fcefc5325ac114ac70b2" + }, + { + "path": "CONTRIBUTING.md", + "bytes": 1333, + "sha256": "861bf32c35fc615f060dc6e4c3191ed336281fa73946e9049bd7f21713a2df0d" + }, + { + "path": "Dockerfile", + "bytes": 1033, + "sha256": "5e586fd24911d9635ac45d36b9dcba24a44c8eb161b61df7d931f1103e0d70f2" + }, + { + "path": "docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md", + "bytes": 8931, + "sha256": "e2933f3ff3bd9c3066027e20049805fbc2e1ce720534998882f110024afba375" + }, + { + "path": "docs/architecture/ADR-0002_PHASE_11_FOUNDATIONS.md", + "bytes": 4154, + "sha256": "2f04e81f0fac6439fd94a4620c8fa88f062ea7c32ae83c0b26a6b488255e651d" + }, + { + "path": "docs/BRAND_MIGRATION_v1.0.md", + "bytes": 1322, + "sha256": "b1fb78b8a0c50b629c8f3af36ec841aa2126739008069a80021b18f8219a3d1c" + }, + { + "path": "docs/DEPENDENCY_MANIFEST_v1.0.md", + "bytes": 4109, + "sha256": "0dfdaf10352a56b1468ad35436dd873a16d12171e3ea14eac2268359ec02823a" + }, + { + "path": "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv", + "bytes": 5347, + "sha256": "4300820e10088d76f6407ee358a8cc1a3cab89fe6554f658fd770469c8c6c77d" + }, + { + "path": "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv", + "bytes": 6721, + "sha256": "8569e669ddf280d82ebb68526191315aecb108163cb34e4ad1e32a810888cb93" + }, + { + "path": "docs/PHASE_10_HANDOFF_v1.0.md", + "bytes": 3370, + "sha256": "8cf52ee1b49cabbf0678da222413b0186ed982fb0c8cfc805482ca18eb1fefc7" + }, + { + "path": "docs/PHASE_10_IMPLEMENTATION_REPORT_v1.0.md", + "bytes": 6805, + "sha256": "6a2e5da443bf15351a0e88e5c92117c8f7c780509d51f2e44c4a148a26a6d4e2" + }, + { + "path": "docs/PHASE_11_IMPLEMENTATION_REPORT_v1.0.md", + "bytes": 13394, + "sha256": "79c1a01be6d5188db29d0bb4a3d2d30b18a5c25b5fa367c7d878309fb5e4dfbb" + }, + { + "path": "docs/PHASE_12_HANDOFF_v1.0.md", + "bytes": 7671, + "sha256": "04000f05533c3accf2409e7810e95ca3188338e33ddae98914ee30e059a09c25" + }, + { + "path": "docs/quality/MANUAL_QA_RESULTS_v1.0.csv", + "bytes": 2842, + "sha256": "dba020cda7ffbbc6b05f275fb1c479d102e1f00900ddfc910b6a436f54322a08" + }, + { + "path": "docs/quality/PHASE_11_COMMAND_LOG_v1.0.txt", + "bytes": 2779, + "sha256": "e750ffab91024cb562f5919b8229ce7ed7c0753bc62e96956e7e7275df330cae" + }, + { + "path": "docs/quality/PHASE_11_FILE_CHANGES_v1.0.txt", + "bytes": 3003, + "sha256": "8ac89bb910a600664d799605b51d08b6bc1b99887e36c880b70f9862b684b09c" + }, + { + "path": "docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.json", + "bytes": 1169, + "sha256": "f61ba0cf4eb87f5d4f3b7343c5b0b1c9ce242b28ac673dd9c22a88fdd49f3d47" + }, + { + "path": "docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.md", + "bytes": 2235, + "sha256": "e8eac6f793b461586119e219caa89979b87f3d3ea0254f8fa4602777b2cb7f7d" + }, + { + "path": "docs/quality/VALIDATION_RESULTS_v1.0.json", + "bytes": 1397, + "sha256": "9b663f7667620496bcbd872e3fc06c725adfb7dbbf6d7bfe8848896f400105d7" + }, + { + "path": "docs/quality/VALIDATION_RESULTS_v1.0.md", + "bytes": 4623, + "sha256": "47d44ee6095cb0bc68fe23148c98403d39309edbb4dd6acdf4a696019e9f0065" + }, + { + "path": "docs/quality/VISUAL_REGRESSION_RESULTS_v1.0.json", + "bytes": 659, + "sha256": "2e94e41c1bdae854d8b1b1db8f62027e896783ece58df0108287c181c7e8caa5" + }, + { + "path": "docs/TOKEN_IMPLEMENTATION_v1.0.md", + "bytes": 2281, + "sha256": "fe6cb88b5689f989cd325a961f2d28cde6f20bea31d2cf572d2a5706c2d7fed7" + }, + { + "path": "eslint.config.mjs", + "bytes": 1031, + "sha256": "14ef56a9899d4c5440c6fe71e713f321b1e1db3de2041b6ad13cd8f798a5225d" + }, + { + "path": "next-env.d.ts", + "bytes": 247, + "sha256": "7b550dda9686c16f36a17bf9051d5dbf31e98555b30d114ac49fc49a1e712651" + }, + { + "path": "next.config.ts", + "bytes": 198, + "sha256": "cd5d6988c4b5ba3b924c236876af7df12edf1f6df71d654ed67500ad450a48eb" + }, + { + "path": "package.json", + "bytes": 2612, + "sha256": "0b425c45cb1f31afd3c89ddcf3b78e1e4006cf773d0ced11f16dfaecb2c4213e" + }, + { + "path": "PHASE_10_PACKAGE_MANIFEST_v1.0.json", + "bytes": 25522, + "sha256": "5a6e185cba91cf3801480ef83f07ed392cd2a85f1f717bb2c4b341235613269c" + }, + { + "path": "playwright.config.ts", + "bytes": 1598, + "sha256": "21d4bf2dfc8b8f3b31a411bef9ea2d264f89b21030d778867efff5c8821ad579" + }, + { + "path": "pnpm-lock.yaml", + "bytes": 168864, + "sha256": "c8b40337671246d5a691a4c2c322f6ed184c6b7f99c10095519cf768eb1ace3d" + }, + { + "path": "pnpm-workspace.yaml", + "bytes": 338, + "sha256": "568eba518a28bcd58534a51483092d0a27919aefaec2446e6dd5c6d6ddd80160" + }, + { + "path": "prettier.config.mjs", + "bytes": 164, + "sha256": "2d5316ad27ef10ead128dd2ee82e11b79f067fcf25ea6d504624966739260335" + }, + { + "path": "public/.gitkeep", + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "path": "README.md", + "bytes": 3040, + "sha256": "486adbbe390eb254302df15b11f110b3beb301d14a82415115fc3083af3c2e3a" + }, + { + "path": "scripts/generate-phase10-manifest.mjs", + "bytes": 1800, + "sha256": "6917fd46f99aacf9de7c89f058380facbf4c8c4adf0baaafb0bf7d1333497808" + }, + { + "path": "scripts/generate-phase11-manifest.mjs", + "bytes": 1800, + "sha256": "4f659193f9741a6c4d0b1bfc8153b426952ce7a9a895b8229bc8fe82530d832b" + }, + { + "path": "scripts/lib.mjs", + "bytes": 1446, + "sha256": "81c8af9b271572e92ade805dd317dc8738647efe8e89cb37a7c9d1873b5d5edc" + }, + { + "path": "scripts/prepare-standalone.mjs", + "bytes": 813, + "sha256": "f1c1398022048160d71ae14bfa53dd2e431dd2f5aca8f39571de159259af535b" + }, + { + "path": "scripts/run-checks.mjs", + "bytes": 600, + "sha256": "aa1d0192134b288c86ffe68b314b2e379d7865d2e8d5ad0d1f7b29c8e744c7ee" + }, + { + "path": "scripts/run-validations.mjs", + "bytes": 536, + "sha256": "abf0034583c0fd35fa1ae65b0e4087878d7193fdc9a826fd18a7eb49dec24c4b" + }, + { + "path": "scripts/validate-css-logical.mjs", + "bytes": 943, + "sha256": "d47f0346ba94621442c5dc700b53a0219ade3dda7485b4c7f49fb384738c424c" + }, + { + "path": "scripts/validate-locales.mjs", + "bytes": 1875, + "sha256": "dfaf3f34079ea571b17dd2d71d0abf47b48be924818b39c5df93495188b95f43" + }, + { + "path": "scripts/validate-metadata.mjs", + "bytes": 1268, + "sha256": "78127c2c0387e38914388f1a6292ed7a408d672739f8ef5a51e3919fdd2addb0" + }, + { + "path": "scripts/validate-phase10-manifest.mjs", + "bytes": 1192, + "sha256": "29386f182d08ee9096e51a01ea115ae145023724f3d8527fc3ac550152f34d20" + }, + { + "path": "scripts/validate-phase11-foundation.mjs", + "bytes": 2898, + "sha256": "6ada4344545ae50710d9207e0de636c1a8452e6a6bbe3815d51f82ae66667b0d" + }, + { + "path": "scripts/validate-phase11-manifest.mjs", + "bytes": 2950, + "sha256": "977c184291541ad5c6926f8075f96e093dd8957ffc6fe722cc4481a7c079aab7" + }, + { + "path": "scripts/validate-phase9-contract.mjs", + "bytes": 1424, + "sha256": "5fce16d33bf6cf7d95136b89f62fd595f109c5d003d54652998dfe3e5b866d6e" + }, + { + "path": "scripts/validate-prohibited-content.mjs", + "bytes": 1068, + "sha256": "3dd645162ad8cd95a28395840fba47a11e2b34e744c7cebdd61a0a9ed3003872" + }, + { + "path": "scripts/validate-routes.mjs", + "bytes": 1611, + "sha256": "d495d43cdfc9505c951b1ed4f7c717d5369b2a637ca31b0b87aae118295c9568" + }, + { + "path": "scripts/validate-runtime-dependencies.mjs", + "bytes": 2175, + "sha256": "32f053bf6c36b13df326cad86fe2b170c1aeb8570d0695c151f19d37a7b83c0c" + }, + { + "path": "scripts/validate-tokens.mjs", + "bytes": 1682, + "sha256": "a508dbee00fe1f991d4f09c2072719e508eb9e14f3ab7d474ba67ca826f45557" + }, + { + "path": "src/app/[locale]/[slug]/page.tsx", + "bytes": 2222, + "sha256": "1f0a103dc658ba88003f5203e3842ec13dc5bdc2bc10695510968043f9ea4dfd" + }, + { + "path": "src/app/[locale]/error.tsx", + "bytes": 693, + "sha256": "129089239ad9e7e5fb941607803ef5dded6df716d3d913b355db015901cea2b5" + }, + { + "path": "src/app/[locale]/layout.tsx", + "bytes": 2401, + "sha256": "669bfd406ae09fb9d45c36a3d86bf168c76188f58ce03e8166ceeaad9110a547" + }, + { + "path": "src/app/[locale]/loading.tsx", + "bytes": 146, + "sha256": "54cff43832c7ad9d05b82cddb5e2262ec11589a937a54b3c5a2c0da3da6c46b5" + }, + { + "path": "src/app/[locale]/not-found.tsx", + "bytes": 150, + "sha256": "ddb7a1c6f57acebb313117af5c5312398b39a6b698f7347b8fed69c4816e9c00" + }, + { + "path": "src/app/[locale]/page.module.css", + "bytes": 1496, + "sha256": "2b639fd3aaba8171143139914f4dda014e7642d6b6f3bef017b1932b290955c5" + }, + { + "path": "src/app/[locale]/page.tsx", + "bytes": 2742, + "sha256": "f0aeeb12927b1bc326d039d6a96102f0db91109c81ff37756554acb8ab26f3c6" + }, + { + "path": "src/app/robots.ts", + "bytes": 397, + "sha256": "6c1e263671da52c65da390bcbf38b2a11ec9c580a0072295cad11028e082900f" + }, + { + "path": "src/components/app-shell/BrandLink.tsx", + "bytes": 684, + "sha256": "54c482a2e5be262941b943cf2ed123b61dbd4199993d225ec5d22be530b375bb" + }, + { + "path": "src/components/app-shell/Controls.module.css", + "bytes": 743, + "sha256": "fde735d74c28c3131a4c2c6b91146fd844e4af1af351d481033b32e2a8ec1a8c" + }, + { + "path": "src/components/app-shell/DisabledAction.tsx", + "bytes": 682, + "sha256": "4c8327532ccd967895c9ea03477b136eef7f47b169e04ecc728e3af80a152073" + }, + { + "path": "src/components/app-shell/HeaderNavigation.tsx", + "bytes": 1634, + "sha256": "ebfd217810ca31dbafd64ceeaaf8de45a89c6e2aa1d4806a66f2f25dd55e0188" + }, + { + "path": "src/components/app-shell/LocaleSelector.tsx", + "bytes": 1330, + "sha256": "bfcda377c8177aab6e2f5e17fc761dd77009e0310fd281f7dbc07a72f88c162d" + }, + { + "path": "src/components/app-shell/LocalizedLoading.tsx", + "bytes": 503, + "sha256": "b362aa5b94495c599c7cc22e0a3cfa04a29229b6c7f74dde71202f5027a831a5" + }, + { + "path": "src/components/app-shell/LocalizedNotFound.tsx", + "bytes": 794, + "sha256": "3b7a9c001bd3e9818c7bda6f25bc29c9df816d4ced1486542be2b31ccdc476e9" + }, + { + "path": "src/components/app-shell/MobileNavigation.tsx", + "bytes": 4006, + "sha256": "36fb3ec9295a25c55d3075cad06f501fc0159fe08dbd71d54b2622e62af13a6a" + }, + { + "path": "src/components/app-shell/SiteFooter.module.css", + "bytes": 2260, + "sha256": "491af5e5b3137180ffec3833ff2d9e6bfe1d47cf7615a886034e1ff12b89cceb" + }, + { + "path": "src/components/app-shell/SiteFooter.tsx", + "bytes": 4726, + "sha256": "595a6e92ea6a9368d5a2b5c22285f8f3438f47a9d50917875675c13c5f1c64a6" + }, + { + "path": "src/components/app-shell/SiteHeader.module.css", + "bytes": 5120, + "sha256": "587e511e7825b133c964bd9a873c642d9d89152462ba8b6c09e328e24167c21c" + }, + { + "path": "src/components/app-shell/SiteHeader.tsx", + "bytes": 2385, + "sha256": "863439879586af6480dec6ccb640d0955a5d9ac7c5bf54883e73f7944ee07b98" + }, + { + "path": "src/components/app-shell/StateShell.module.css", + "bytes": 2014, + "sha256": "acdf7af0cd11250c411dd44291e36cc5053a195a07d3849c2ca9050f6524cf40" + }, + { + "path": "src/components/app-shell/StateShell.tsx", + "bytes": 1378, + "sha256": "633c5d35f024d6c1c7a7b5f2bc128d13ef35a25ac07820c7428dc871d5c01f50" + }, + { + "path": "src/components/app-shell/ThemeController.tsx", + "bytes": 1017, + "sha256": "e3e646ff02c7480a191d4700971ba03b947ddff769687af1f3769e11cd740ce9" + }, + { + "path": "src/components/app-shell/ThemeSelector.tsx", + "bytes": 2319, + "sha256": "04bb79e8b99006786e669ccae0a8d1a845efafceebe6b5d0ab43380a190d1b6f" + }, + { + "path": "src/components/foundation/AccessibleIcon.tsx", + "bytes": 352, + "sha256": "cc68b314b3a704037460272f12a05e4185bfbcc08be62bf0facd0d1efa5a5f5c" + }, + { + "path": "src/components/foundation/BidiText.module.css", + "bytes": 35, + "sha256": "0d9480f398007b7e1395f25afd4ba982c6a5dcf299f796ee96fdc1302e5f8b06" + }, + { + "path": "src/components/foundation/BidiText.tsx", + "bytes": 404, + "sha256": "18adca60aab9f2afb2edbed001fb955b21cde0bb2a8c020107396c9c1a27f6ce" + }, + { + "path": "src/components/foundation/LiveRegion.module.css", + "bytes": 184, + "sha256": "f5793a73b271c20d10b389245651d7c79fae6417c29e55701e381c0025d20df0" + }, + { + "path": "src/components/foundation/LiveRegion.tsx", + "bytes": 403, + "sha256": "d64aad4af939e2696b955a0632b2869533409698ae3dffede57a18a776e64acf" + }, + { + "path": "src/components/foundation/StatusBadge.module.css", + "bytes": 391, + "sha256": "76149c815fdacd7b25761c672448ea6248b93f8a3c55d766845972e34d41365a" + }, + { + "path": "src/components/foundation/StatusBadge.tsx", + "bytes": 175, + "sha256": "0ee477e4f511702093014e9edbfff1cda70b8ae6dc52cefc445d72c66c7c8c85" + }, + { + "path": "src/components/layout/LayoutPrimitives.module.css", + "bytes": 1106, + "sha256": "4463342699789f2bc38703a7178b62138f10a255555347b692855ea07536dbcc" + }, + { + "path": "src/components/layout/LayoutPrimitives.tsx", + "bytes": 2161, + "sha256": "e3eceb28bcaec129f0324558fd2a13fbfe413615c16943cc691a2a993089de33" + }, + { + "path": "src/content/locales/ar/homepage.json", + "bytes": 17425, + "sha256": "6f0cba2a159531a55b72f345f760344b44bd670e3cd29685712a9215de5b1721" + }, + { + "path": "src/content/locales/ar/shell.json", + "bytes": 5061, + "sha256": "2e6075e7c7cb42d9e3fbd45e7f15eadf7204d7c1a534e7d784f8af19ad442507" + }, + { + "path": "src/content/locales/en/homepage.json", + "bytes": 12775, + "sha256": "c55d2883811bafd7262792169ebc19700e4a39721f9fe63a2baf096593140f8b" + }, + { + "path": "src/content/locales/en/shell.json", + "bytes": 3778, + "sha256": "ce64b8164eb01e289c98487b25ada0cf2afc9677c90b6d73c5482784885fdd95" + }, + { + "path": "src/content/locales/fr/homepage.json", + "bytes": 14570, + "sha256": "3d1e4143ff05d562bc8a86ff216840f7cb15168c27b982ae90a5e58bb73ecc6e" + }, + { + "path": "src/content/locales/fr/shell.json", + "bytes": 4295, + "sha256": "df3c3663d487dcb9fd25d8f8cdf52a31df1f3a7f0518fcaf1d7cf99178928213" + }, + { + "path": "src/contracts/phase9/analytics-contract.ts", + "bytes": 918, + "sha256": "d79b32503a5f8346816c647b8a7f45a62468b96f4fc9525d6d5147b5d2f2ec45" + }, + { + "path": "src/contracts/phase9/analytics-event-spec.csv", + "bytes": 1713, + "sha256": "1282ebca5b031f6267f8139033db437e30b62ac391d25823c8a4783b64151008" + }, + { + "path": "src/contracts/phase9/component-contracts.ts", + "bytes": 3041, + "sha256": "45fb0222d99308b2f28014572316b13c2d7308bc16b1bd02f63b6e2257148399" + }, + { + "path": "src/contracts/phase9/demo-form-contract.ts", + "bytes": 699, + "sha256": "073cf70224f93312d177f77abd7987704205628209e30c44824ae45f929ee59e" + }, + { + "path": "src/contracts/phase9/design-tokens.json", + "bytes": 3771, + "sha256": "470d7bc9d4a466cce4e51f0fdc21fe199ec5b0d4007f5063704c523ce1b9ef0c" + }, + { + "path": "src/contracts/phase9/performance-budgets.json", + "bytes": 815, + "sha256": "e1679ce45d8a1225c46c085c7533d3230a41279c32d0812de5c5f05cb55eefa8" + }, + { + "path": "src/contracts/phase9/route-manifest.json", + "bytes": 1433, + "sha256": "e08ac94ba1f3899bb02dfa934695f530d1089f9f03b0fadaa0feabd466ad8ec4" + }, + { + "path": "src/contracts/phase9/visual-regression-scenarios.json", + "bytes": 1209, + "sha256": "27d961c33c32775485475f7037b8d3bbd13f634b65fe2f59d6eea898860edf5f" + }, + { + "path": "src/lib/localization/client-messages.ts", + "bytes": 499, + "sha256": "402d73487e9c57e7f68b2b91b77de8cae27027bac56ac344f310eacd0bb41bd3" + }, + { + "path": "src/lib/localization/client.ts", + "bytes": 602, + "sha256": "8041847762d3b78102e56ee9407f7689c6b8174a330aa6d0ebe97f89eb64cc99" + }, + { + "path": "src/lib/localization/config.ts", + "bytes": 4758, + "sha256": "5658aebdfbb912e86b20cef052f6f2784ce64ea89c82fa3d2c05a3a32ec03ed8" + }, + { + "path": "src/lib/localization/format.ts", + "bytes": 2327, + "sha256": "a8f9fbe9bdb5838a910e86897ed13ef9bbfdca6e86514e466bc6a212c236bbfc" + }, + { + "path": "src/lib/localization/messages.ts", + "bytes": 878, + "sha256": "9307df65a80b08e7e1ea7c4e16358fc5fcbde299a00810076bcb36d0a13f9ced" + }, + { + "path": "src/lib/localization/site-origin.ts", + "bytes": 771, + "sha256": "40400ce29fc4adbd9c4490b456968e41fc7596d77ac5bea1c65179e0e4e760ff" + }, + { + "path": "src/lib/metadata/build-metadata.ts", + "bytes": 1322, + "sha256": "3496f11871e635ea6622746de07d74de63a09e648bae9ade02f7c75f042cde7e" + }, + { + "path": "src/lib/security/csp.ts", + "bytes": 830, + "sha256": "f9244e061cc397fbe8720a055e5415b6df34e6c74d0c439ae8d25054d1239c5e" + }, + { + "path": "src/lib/theme/bootstrap-script.ts", + "bytes": 755, + "sha256": "ad1ac642ca61e133f41a5e5b3c062f1b23046f24a58565c6baaacf8c9b261f12" + }, + { + "path": "src/lib/theme/client.ts", + "bytes": 1368, + "sha256": "8bdad550d093755a6f1a20f8b5b59b9d19e0dbd78dbf24c3f4eda5a6dec5811f" + }, + { + "path": "src/lib/theme/config.ts", + "bytes": 821, + "sha256": "c04cd00ce7838fc964d5bdbfaa4c2380f7cd774a9d754987946c97ee8849e60c" + }, + { + "path": "src/proxy.ts", + "bytes": 2625, + "sha256": "522ad1c3650646e652099d61b403075000b4d6e12272df381f5653dbd4745dea" + }, + { + "path": "src/styles/component-tokens.css", + "bytes": 5898, + "sha256": "70665f8912d1e45cbcd1a2674a5cb547395391dae053d0951da157ad88d7de51" + }, + { + "path": "src/styles/globals.css", + "bytes": 2472, + "sha256": "15c39da4ef19e6127bd7f40db21a98d7d2599463af1a13bbd2c3ce786a7ef385" + }, + { + "path": "src/styles/tokens.css", + "bytes": 3553, + "sha256": "99912762e078bfc78b4878fc46b8c7d03d90c073e9c236942a58d83f6585a1b9" + }, + { + "path": "tests/a11y/shell.a11y.spec.ts", + "bytes": 781, + "sha256": "9f6299337a822d8e4f6783cbfbb3e5da02e42bcca99d8e4519d7f0193072b205" + }, + { + "path": "tests/browser/navigation.spec.ts", + "bytes": 1120, + "sha256": "7b4aa8bcb7b5c2f09fe82f6c4a5405673e69d45fb5f0833cbe37ee1d237c4c7a" + }, + { + "path": "tests/browser/no-javascript.spec.ts", + "bytes": 568, + "sha256": "a57739c1d0c7c45960129256218a9e95b87ac80a17fc7dee8bd4c95295280fbc" + }, + { + "path": "tests/browser/responsive.spec.ts", + "bytes": 877, + "sha256": "81c9a61d757632741f43c4c2aed519af6cc88601e3587653c2a157a16563a337" + }, + { + "path": "tests/browser/shell.spec.ts", + "bytes": 2425, + "sha256": "bdd0ce3d9f5e53ff485c45a3f9442e28fb6157d08cb0eccf02268351e18202e6" + }, + { + "path": "tests/browser/text-expansion.spec.ts", + "bytes": 683, + "sha256": "a573f9cbb7e8b0783ad8aa0abd4b57cf5ffbc6a7319c906e861ffebac5ca66d2" + }, + { + "path": "tests/browser/theme-csp.spec.ts", + "bytes": 2402, + "sha256": "276d56b704685ff434f9d46233e1e2eff5fb16565944d9704ca6bcd6d4de89f4" + }, + { + "path": "tests/fixtures/foundation-matrix.json", + "bytes": 581, + "sha256": "60f25c2853c5cd0ac1bece6da316d222e38fa1ae0c714c227b28a1135b3e40d6" + }, + { + "path": "tests/fixtures/README.md", + "bytes": 495, + "sha256": "e3dba7bdd085bbb1fa43a6b33a94e66641b4437cd01bcfaaaf9c329eee93d3ec" + }, + { + "path": "tests/setup.ts", + "bytes": 43, + "sha256": "91a3c8962a0edcb956206a501d943fe99e1c78c6d4d8b5c9a948a3362c75978c" + }, + { + "path": "tests/unit/csp.test.ts", + "bytes": 969, + "sha256": "18e4aa4145976102239e92a9c147cc8f0b8442b1bce37b84888246b137280de9" + }, + { + "path": "tests/unit/format.test.ts", + "bytes": 1488, + "sha256": "e7bc5eb89fa3017739180208a1dcfb3f03f3cb3077997dfc7e6e03faa68a9ad1" + }, + { + "path": "tests/unit/localization.test.ts", + "bytes": 2155, + "sha256": "b2e65d904e9ee8018a837ba0c275287d98b44341b9bca65abdb754c09f897511" + }, + { + "path": "tests/unit/theme.test.ts", + "bytes": 734, + "sha256": "45f25fd23f69af3df199473053c47fe219c88fb36a58cffac20a125bdbd47433" + }, + { + "path": "tests/visual/README.md", + "bytes": 525, + "sha256": "27327d51bda7fc0725a73f6ebb06db1cfa84abd3508985edbb0723da66d18667" + }, + { + "path": "tests/visual/shell.visual.spec.ts", + "bytes": 2273, + "sha256": "07bd6dd398cbab81176ea19741eb8737859bcacaa313a8c17308cd47f736ea5b" + }, + { + "path": "tsconfig.json", + "bytes": 1042, + "sha256": "3d16e624dcc305c31675190a283744e11177f07106f10a60d2e89c753695433b" + }, + { + "path": "vitest.config.ts", + "bytes": 699, + "sha256": "c2ac8f10ad2894df28a93e3d2bba2c213f24b9a044db25307078648e010dc3d5" + } + ] +} diff --git a/PHASE_12_PACKAGE_MANIFEST_v1.0.json b/PHASE_12_PACKAGE_MANIFEST_v1.0.json new file mode 100644 index 0000000..ec46441 --- /dev/null +++ b/PHASE_12_PACKAGE_MANIFEST_v1.0.json @@ -0,0 +1,1704 @@ +{ + "schema_version": "1.0", + "project": "RentalDriveGo", + "phase": 12, + "generated_at": "2026-06-25", + "excludes": [ + ".git", + ".next", + "node_modules", + "coverage", + "playwright-report", + "test-results", + "PHASE_12_PACKAGE_MANIFEST_v1.0.json", + "tsconfig.tsbuildinfo" + ], + "file_count": 337, + "files": [ + { + "path": ".dockerignore", + "bytes": 97, + "sha256": "d78b037a836881c2d63f074d525b8027b2ecb06fefe3af4d5356327ec01dc5e1" + }, + { + "path": ".editorconfig", + "bytes": 188, + "sha256": "a6b98ea7cb6d61ed8d430dd0dffa46c87012b5cf859d4ce7207898954951fdcd" + }, + { + "path": ".env.example", + "bytes": 221, + "sha256": "8b9baf40c7a324b56c2b0876f761070a995328843a0f56d7bf97bfeafd06b297" + }, + { + "path": ".github/dependabot.yml", + "bytes": 416, + "sha256": "0a9bdd1890c8fcb78f61f91071df45fecbdcfbbd48441f7da0dba266ba168d82" + }, + { + "path": ".github/workflows/ci.yml", + "bytes": 1739, + "sha256": "c3d1671011688d7ebc4be9f38265e82b290b1aefc9ddd237c1d82fafd3e765f4" + }, + { + "path": ".gitignore", + "bytes": 135, + "sha256": "01c7cded7467134f023106b85684e3ce5df721149fc3ff4af5e02ef79541bb14" + }, + { + "path": ".node-version", + "bytes": 8, + "sha256": "98182b41c9ce3357797985cf12dc3b0124490ef88bc918a905373e7688e6aec9" + }, + { + "path": ".npmrc", + "bytes": 146, + "sha256": "e696a3cc1b84316377f18da909b079072ce02383d16c8fed410f8cabbb9ac054" + }, + { + "path": ".nvmrc", + "bytes": 8, + "sha256": "98182b41c9ce3357797985cf12dc3b0124490ef88bc918a905373e7688e6aec9" + }, + { + "path": ".prettierignore", + "bytes": 129, + "sha256": "272622f9ebbe7cc23717e19053be7c49a6fc63353cad9be57f107cd96b96a142" + }, + { + "path": "contracts/phase9/09_DEVELOPER_HANDOFF_v1.0.md", + "bytes": 8091, + "sha256": "e82d486f1e566d1bf0263f1baa7dd8035ae62da5c36bb6bfa417e61331ec8d51" + }, + { + "path": "contracts/phase9/annotated/ANNOTATION_INDEX_v1.0.md", + "bytes": 685, + "sha256": "a2e87dfdb138409604cac4cc5f52375cce97940da7363f7778af30490699decd" + }, + { + "path": "contracts/phase9/annotated/demo-dialog-en-light_v1.0.png", + "bytes": 51457, + "sha256": "d91bf102100af48feac31478770f8bfdded994ac8b47f60845e4465c50462394" + }, + { + "path": "contracts/phase9/annotated/desktop-en-light_v1.0.png", + "bytes": 144908, + "sha256": "a4151a788317aa9bf8f7262f09f645ebdb54d4a3e1254ab5703ae37e8d3cec16" + }, + { + "path": "contracts/phase9/annotated/mobile-ar-dark_v1.0.png", + "bytes": 75193, + "sha256": "6adcaf68b48bacbf105b670e71edda078a60aa26b732831bd194e1cb9da11556" + }, + { + "path": "contracts/phase9/annotated/mobile-drawer-ar-dark_v1.0.png", + "bytes": 28321, + "sha256": "bc0c14447fb6e80ce904ffcb13c237b51eaa92723702191139bee59b0f7ebdeb" + }, + { + "path": "contracts/phase9/annotated/SCREEN_ANNOTATIONS_v1.0.csv", + "bytes": 1457, + "sha256": "d7b8120926a545f472b62a436b87d2a9d20320a4d95fcf90aa96162c50e8a6da" + }, + { + "path": "contracts/phase9/annotated/tablet-fr-light_v1.0.png", + "bytes": 102305, + "sha256": "dd526fe6859e470ea4c67b4c1ef511cfe0e11126561f86bcff07e57378084347" + }, + { + "path": "contracts/phase9/annotated/tour-dialog-fr-dark_v1.0.png", + "bytes": 94445, + "sha256": "2dd7b24f6505f16a565ac1b5490499ccdae91d0257de608c97c54b7d5b6c2c78" + }, + { + "path": "contracts/phase9/assets/ASSET_MANIFEST_v1.0.csv", + "bytes": 1049, + "sha256": "dd77547327096b4c4084ec8b9311aaff719e378a91f16c2b3ea39832d1bc7b3a" + }, + { + "path": "contracts/phase9/assets/ASSET_USAGE_RULES_v1.0.md", + "bytes": 747, + "sha256": "46821e8e6588a62eba860e4d228b2910a05aa60124610966bdc524a86921f658" + }, + { + "path": "contracts/phase9/assets/brand-mark_v1.0.svg", + "bytes": 443, + "sha256": "bcb3a3fb8037aec69d92da06f0d60fab969547b979a0112f12e6a5c2ab8efdaa" + }, + { + "path": "contracts/phase9/assets/logo-horizontal_v1.0.svg", + "bytes": 576, + "sha256": "04be1c45e1b6e85586efc6dbd36bf3e1e9275fa138a36b93cf6532bbd7409b02" + }, + { + "path": "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "bytes": 9800, + "sha256": "84b455fe725bff11b6ab54bb13373b1aa52991b062a36fad07db47a940187a53" + }, + { + "path": "contracts/phase9/components/COMPONENT_STATE_MATRIX_v1.0.csv", + "bytes": 4283, + "sha256": "c85f96f6d5e020a27c2bd44427a2c3aed3f3cad8657d88a22fc2de9ecd3f6cda" + }, + { + "path": "contracts/phase9/components/CONTENT_CONSTRAINTS_v1.0.csv", + "bytes": 1147, + "sha256": "f4d32b7775f856ff4aac775791566427e3cc340f39cd3f9845d8a3271167228b" + }, + { + "path": "contracts/phase9/components/RESPONSIVE_BEHAVIOR_MATRIX_v1.0.csv", + "bytes": 1416, + "sha256": "0e0e262c0388c37e41f5ab7f3e80835b8edb09e00a9264e81d92953743893353" + }, + { + "path": "contracts/phase9/components/RTL_THEME_MATRIX_v1.0.csv", + "bytes": 4048, + "sha256": "b47f4b3b4e50f1fed6b1b69523a05d61952773e95a966288bfba85dd414edb15" + }, + { + "path": "contracts/phase9/DECISION_LOG_v9.0.md", + "bytes": 38775, + "sha256": "85569a7418f8cad57d094ee9ec1d83b7727b5ab91a405cbda26de0271a8d76a1" + }, + { + "path": "contracts/phase9/DEFINITION_OF_DONE_v1.0.md", + "bytes": 3234, + "sha256": "dfe53a550b7853f015901b83adb960ffb26ab08fa6d7f9f8f8a3386adc705179" + }, + { + "path": "contracts/phase9/implementation/component-contracts_v1.0.ts", + "bytes": 2844, + "sha256": "177dd2420b804290cf1296e43f41a7e759c8859b3253073fbdc523a81f6f94c0" + }, + { + "path": "contracts/phase9/implementation/hreflang-generator_v1.0.ts", + "bytes": 751, + "sha256": "ab919a36a5d08a28c38ae51b4ddd0d84cef5d3ec3bed13649ebd26c3fb80ac8a" + }, + { + "path": "contracts/phase9/implementation/localization-config_v1.0.ts", + "bytes": 772, + "sha256": "bd8ca09f121bfe516ece817948a81d58136e9205fbd2c05dad2ce87f2d7a1782" + }, + { + "path": "contracts/phase9/implementation/TECHNOLOGY_PROFILE_v1.0.md", + "bytes": 1953, + "sha256": "a59504c81bdbb6396eb21e68518ca84862ac89c6c65744de710e9ae273e47c7b" + }, + { + "path": "contracts/phase9/implementation/theme-config_v1.0.ts", + "bytes": 725, + "sha256": "f56d37da4129d5830ba9ebd77b18cd6084a144e8514bfd8a8152387ecf76607c" + }, + { + "path": "contracts/phase9/interaction/ANALYTICS_EVENT_SPEC_v1.0.csv", + "bytes": 1713, + "sha256": "1282ebca5b031f6267f8139033db437e30b62ac391d25823c8a4783b64151008" + }, + { + "path": "contracts/phase9/interaction/analytics-contract_v1.0.ts", + "bytes": 832, + "sha256": "2716eb69cc98032005e068ab7bdc265a4c896a8e1a1bed682c7fdd4f45368123" + }, + { + "path": "contracts/phase9/interaction/demo-form-contract_v1.0.ts", + "bytes": 632, + "sha256": "194db77f7cfca417dbe35e6f2c2ea94cdd02806b83b1d0f1993fe509d8c10154" + }, + { + "path": "contracts/phase9/interaction/INTERACTION_NOTES_v1.0.md", + "bytes": 2332, + "sha256": "0456815622cbb072f1a7594e6b47f52e572e2570280c3a618876246e1b43d2a7" + }, + { + "path": "contracts/phase9/interaction/theme-bootstrap_v1.0.js", + "bytes": 753, + "sha256": "7b89a849bdcd72e1049714ebf76f0c0decb39e44261480f0cb08bb7dfe734e4a" + }, + { + "path": "contracts/phase9/localization/locales/ar/homepage.json", + "bytes": 18615, + "sha256": "fe08aabd60203dbdebc718117f5e497b52a453a8a6fb671fe0bca28651bf0d47" + }, + { + "path": "contracts/phase9/localization/locales/en/homepage.json", + "bytes": 13869, + "sha256": "a5ed956c7f07fad016ca39b40b770c25e8beeae2799ff0fece82dbf087f18e51" + }, + { + "path": "contracts/phase9/localization/locales/fr/homepage.json", + "bytes": 15512, + "sha256": "24079356bd47431ffeb66b7eb2981e108c03080205861b1bb42514b03b945a0a" + }, + { + "path": "contracts/phase9/localization/LOCALIZATION_IMPLEMENTATION_v1.0.md", + "bytes": 2062, + "sha256": "87a494d7ef7ed9f5012ed1699edf90e38995aa89a0efc3800db854e1d57e1024" + }, + { + "path": "contracts/phase9/localization/ROUTE_MANIFEST_v1.0.json", + "bytes": 1573, + "sha256": "fa29b8d31da1f36f87d216a1228fd1bbe1cde337636950b40b0024a10efaf49a" + }, + { + "path": "contracts/phase9/localization/TRANSLATION_KEY_INVENTORY_v1.0.csv", + "bytes": 10599, + "sha256": "01289dc9eb94d546ae717b881b2aed4dfc63b38df38e7767054800122bbb46c2" + }, + { + "path": "contracts/phase9/OPEN_ISSUE_REGISTER_v1.0.csv", + "bytes": 3519, + "sha256": "b8778b3dc7d1e47446584cac046d490a9932c3dfdfa03750716f29852694a214" + }, + { + "path": "contracts/phase9/OPEN_QUESTIONS_v1.0.md", + "bytes": 1085, + "sha256": "82a2abd71830fa4023d346f3b42b138de9e1bbdff74a827d770e6b660d89bd0e" + }, + { + "path": "contracts/phase9/PACKAGE_MANIFEST_v1.0.json", + "bytes": 10649, + "sha256": "1a143f086f40f83414460bd4519e86bd3a34617079e3cfef4c5736375460a24e" + }, + { + "path": "contracts/phase9/PHASE_9_HANDOFF_v1.0.md", + "bytes": 939, + "sha256": "90530b4e70d1fd64d5d934429c009431902639c0570e7944cf050e6d67eb73a3" + }, + { + "path": "contracts/phase9/qa/ACCESSIBILITY_CHECKLIST_v1.0.csv", + "bytes": 1498, + "sha256": "0d9c108e0c02b78aaf11badf6b5f5125cac2b03876cfddf82bd2e97230fdd28b" + }, + { + "path": "contracts/phase9/qa/BROWSER_SUPPORT_MATRIX_v1.0.csv", + "bytes": 986, + "sha256": "5ffb43732fea90530b1b088fb68172b9fc7b2c2683198448734a21cf39c234d1" + }, + { + "path": "contracts/phase9/qa/PERFORMANCE_BUDGETS_v1.0.json", + "bytes": 815, + "sha256": "e1679ce45d8a1225c46c085c7533d3230a41279c32d0812de5c5f05cb55eefa8" + }, + { + "path": "contracts/phase9/qa/PLAYWRIGHT_ACCEPTANCE_SPEC_v1.0.md", + "bytes": 800, + "sha256": "b16384a861d06eb76db5a836868d9a6e03cf72a6a896209279330e19a8d1a785" + }, + { + "path": "contracts/phase9/qa/QA_MATRIX_v1.0.csv", + "bytes": 3557, + "sha256": "6b14b92ce20a9d706de7d6d4cf9f0bb450ecceed27673ed62ae01e145d2143f8" + }, + { + "path": "contracts/phase9/qa/test-ids_v1.0.csv", + "bytes": 598, + "sha256": "6201007ae98632654a2684a0b09ce95d85d9870e0f29774687df0a9876048202" + }, + { + "path": "contracts/phase9/qa/validate-phase9-package_v1.0.mjs", + "bytes": 2534, + "sha256": "631892318cf95c0530a605e5bf08def9b06c93af79b555205f3aeb8a2bcd87ed" + }, + { + "path": "contracts/phase9/qa/visual-regression-scenarios_v1.0.json", + "bytes": 1401, + "sha256": "08a04f676cbb93e73b4c6bc112a55ebf287cb97be3dd3176ab80161e6de743c2" + }, + { + "path": "contracts/phase9/README_v1.0.md", + "bytes": 1258, + "sha256": "ef0010b98ba641c4db453d875171a0d1dad4cb17e991ad23698acde8ac4783ae" + }, + { + "path": "contracts/phase9/reference/FINDINGS_REPORT_v1.0.md", + "bytes": 3062, + "sha256": "ba34afd535856d0eaa8ed7e174c23a7b5f0eae87344c8fcee5daafe00c068ce4" + }, + { + "path": "contracts/phase9/reference/PHASE_8_HANDOFF_v1.0.md", + "bytes": 1117, + "sha256": "2e51ed6645fcc99f30cd4aa9da11ac59e5c2e331c384bfbd758739ad6f42c788" + }, + { + "path": "contracts/phase9/reference/PRIORITIZED_REVISIONS_v1.0.csv", + "bytes": 1071, + "sha256": "65b17813756a2d01c8a9df9faa049b170dca197f243b62a44e070d69f8959df5" + }, + { + "path": "contracts/phase9/reference/SUCCESS_METRICS_v1.0.csv", + "bytes": 1552, + "sha256": "e7b734564735ab65dcaf84ab8374ba163472cca48db1257c4c626415a779ecbe" + }, + { + "path": "contracts/phase9/reference/VALIDATION_RESULTS_v1.0.md", + "bytes": 2068, + "sha256": "3cb17f099569e5bdf4bcd731fe7f687d1636f0e82623c205e07df2cdc2b7d2f2" + }, + { + "path": "contracts/phase9/SOURCE_TRACEABILITY_v1.0.csv", + "bytes": 765, + "sha256": "76dc8677ad0d50263301fd5242bc0649c23bb01d3bbd099bdc8a7e2c04fc2d46" + }, + { + "path": "contracts/phase9/tokens/design-tokens_v1.0.json", + "bytes": 3771, + "sha256": "470d7bc9d4a466cce4e51f0fdc21fe199ec5b0d4007f5063704c523ce1b9ef0c" + }, + { + "path": "contracts/phase9/tokens/semantic-tokens_v1.0.css", + "bytes": 3553, + "sha256": "99912762e078bfc78b4878fc46b8c7d03d90c073e9c236942a58d83f6585a1b9" + }, + { + "path": "contracts/phase9/tokens/TOKEN_USAGE_RULES_v1.0.md", + "bytes": 1222, + "sha256": "b9f7d9b0a9c0595e6f6df2a53e0bcf4acfb47a56abfc6c590a6281c15b04a7b2" + }, + { + "path": "contracts/phase9/tokens/tokens_v1.0.ts", + "bytes": 442, + "sha256": "ec265270251f8dd01d9166aeca3fcec9be2b5e534d825c9058fb6ed3f51e3224" + }, + { + "path": "contracts/phase9/validation/CONTENT_AND_STRUCTURE_VALIDATION_v1.0.json", + "bytes": 189, + "sha256": "e055ef15c2de2191a3465d85ed54f4cf6bd9e1cde4d5d2bba787e14873027b73" + }, + { + "path": "contracts/phase9/validation/STATIC_VALIDATION_RESULTS_v1.0.json", + "bytes": 56, + "sha256": "b60367adf55cf4c61b705d11131b7adebc0aae6ff53732c8272ec9cf2bc95dd3" + }, + { + "path": "contracts/phase9/validation/VALIDATION_RESULTS_v1.0.md", + "bytes": 1179, + "sha256": "6f9df81e75d7149d3826ce215143c21784f39b154660fcefc5325ac114ac70b2" + }, + { + "path": "CONTRIBUTING.md", + "bytes": 1333, + "sha256": "861bf32c35fc615f060dc6e4c3191ed336281fa73946e9049bd7f21713a2df0d" + }, + { + "path": "Dockerfile", + "bytes": 1033, + "sha256": "5e586fd24911d9635ac45d36b9dcba24a44c8eb161b61df7d931f1103e0d70f2" + }, + { + "path": "docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md", + "bytes": 8931, + "sha256": "e2933f3ff3bd9c3066027e20049805fbc2e1ce720534998882f110024afba375" + }, + { + "path": "docs/architecture/ADR-0002_PHASE_11_FOUNDATIONS.md", + "bytes": 4154, + "sha256": "2f04e81f0fac6439fd94a4620c8fa88f062ea7c32ae83c0b26a6b488255e651d" + }, + { + "path": "docs/architecture/ADR-0003_PHASE_12_COMPONENT_SYSTEM.md", + "bytes": 1918, + "sha256": "7ba7bed100e43614b5904d6a20161c55ce99460dbf5e35376cd80b02df9a12eb" + }, + { + "path": "docs/BRAND_MIGRATION_v1.0.md", + "bytes": 1322, + "sha256": "b1fb78b8a0c50b629c8f3af36ec841aa2126739008069a80021b18f8219a3d1c" + }, + { + "path": "docs/DECISION_LOG_v12.0.md", + "bytes": 2835, + "sha256": "c69af78a6af60ba743b057c0c8b50691f7d826923d91c204179fc0683487a0af" + }, + { + "path": "docs/DEPENDENCY_MANIFEST_v1.0.md", + "bytes": 4109, + "sha256": "0dfdaf10352a56b1468ad35436dd873a16d12171e3ea14eac2268359ec02823a" + }, + { + "path": "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv", + "bytes": 5347, + "sha256": "4300820e10088d76f6407ee358a8cc1a3cab89fe6554f658fd770469c8c6c77d" + }, + { + "path": "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv", + "bytes": 6721, + "sha256": "8569e669ddf280d82ebb68526191315aecb108163cb34e4ad1e32a810888cb93" + }, + { + "path": "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.2.csv", + "bytes": 8902, + "sha256": "24725fbb71279b0e6bfdfb05a8d48d01ec132b863fb311eb8d012d9b2151f3d1" + }, + { + "path": "docs/PHASE_10_HANDOFF_v1.0.md", + "bytes": 3370, + "sha256": "8cf52ee1b49cabbf0678da222413b0186ed982fb0c8cfc805482ca18eb1fefc7" + }, + { + "path": "docs/PHASE_10_IMPLEMENTATION_REPORT_v1.0.md", + "bytes": 6805, + "sha256": "6a2e5da443bf15351a0e88e5c92117c8f7c780509d51f2e44c4a148a26a6d4e2" + }, + { + "path": "docs/PHASE_11_IMPLEMENTATION_REPORT_v1.0.md", + "bytes": 13394, + "sha256": "79c1a01be6d5188db29d0bb4a3d2d30b18a5c25b5fa367c7d878309fb5e4dfbb" + }, + { + "path": "docs/PHASE_12_HANDOFF_v1.0.md", + "bytes": 7671, + "sha256": "04000f05533c3accf2409e7810e95ca3188338e33ddae98914ee30e059a09c25" + }, + { + "path": "docs/PHASE_12_IMPLEMENTATION_REPORT_v1.0.md", + "bytes": 12420, + "sha256": "b52db7413ef0365f9ae917133ac4449bf22a95760b25c8bef2fca4f64f3f6040" + }, + { + "path": "docs/PHASE_13_HANDOFF_v1.0.md", + "bytes": 11204, + "sha256": "f82e319eb0d11c861a7d77c4abdc3bcb48e966cb8cfa610389d7807bbaeedb0a" + }, + { + "path": "docs/phase12/ACCESSIBILITY_BEHAVIOR_MATRIX_v1.0.csv", + "bytes": 10934, + "sha256": "bf23d29033b091f0556f7a5c07ffc86e31484d82c6fd01a80ffcc33c5daedb0c" + }, + { + "path": "docs/phase12/BUNDLE_IMPACT_REPORT_v1.0.md", + "bytes": 1704, + "sha256": "795ab11fc56780f57c8bba78821106cd5ea00dd02e9aac63c3ddc8865af7f453" + }, + { + "path": "docs/phase12/COMPONENT_CATALOG_v1.0.md", + "bytes": 26256, + "sha256": "93c3d22539c7489166119a8126712995d81fefade081cd06488f3898fa7d519c" + }, + { + "path": "docs/phase12/COMPONENT_INVENTORY_v1.0.json", + "bytes": 42210, + "sha256": "b64cff5d50f7777e6384e6ca19e49a38430925b4a19a53543d35e4452f42d112" + }, + { + "path": "docs/phase12/COMPONENT_SPECIFICATION_TRACEABILITY_v1.0.csv", + "bytes": 11328, + "sha256": "1d352fd6ce9bc3dae7e135725c1deb2ebd44faf679658e8eeb8622266ee08b58" + }, + { + "path": "docs/phase12/DEFINITION_OF_DONE_STATUS_v1.0.md", + "bytes": 1581, + "sha256": "692e3847c7e120939a2ee16dbadd9e6908decaf7f04fa9187e1063f5337dd016" + }, + { + "path": "docs/phase12/DEPENDENCY_CHANGE_REPORT_v1.0.md", + "bytes": 1273, + "sha256": "7c668afb6d310a56fa94d3b88a20cdde5b0594b7005857c915a27edb40aaba0e" + }, + { + "path": "docs/phase12/RESPONSIVE_VALIDATION_MATRIX_v1.0.csv", + "bytes": 16762, + "sha256": "9542e345b81d123e67b12167afc67b946667729cf35a3ce469756627b5368c4d" + }, + { + "path": "docs/phase12/RTL_BEHAVIOR_MATRIX_UPDATE_v1.0.csv", + "bytes": 17557, + "sha256": "c172ed56ff3513bb986894d6fd5814b05391ffcdc432ba3282005e7b8e7c8953" + }, + { + "path": "docs/phase12/STORY_AND_FIXTURE_INVENTORY_v1.0.csv", + "bytes": 565, + "sha256": "f1b3f012c7319e3eacf5b625ada085856dab9fe4392302cc2eb67d79042b5d64" + }, + { + "path": "docs/phase12/TEST_COVERAGE_REPORT_v1.0.csv", + "bytes": 983, + "sha256": "fa174206dec0855a7a9ce328981132ad2114dca73a8511aba8dfd2e953ac9535" + }, + { + "path": "docs/phase12/VARIANT_INVENTORY_v1.0.csv", + "bytes": 17312, + "sha256": "58b988f565cf4e92175bcbd14b0c242b6785d24b5f695e1c12a2a53cb18d0bd1" + }, + { + "path": "docs/quality/logs/build-initial.log", + "bytes": 719, + "sha256": "9245b913520a4477ec638d0cdce23f2079c575bdc4a989d0fe68b9d437a5e3b3" + }, + { + "path": "docs/quality/logs/build-missing-site-origin.exit", + "bytes": 2, + "sha256": "4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865" + }, + { + "path": "docs/quality/logs/build-missing-site-origin.log", + "bytes": 922, + "sha256": "b2bff4cccbc95305d2f9304982446920ca76ecfbb6addc9fbff2d95a1538c1f5" + }, + { + "path": "docs/quality/logs/build.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/build.log", + "bytes": 719, + "sha256": "dd0cee291d02930e6ba19eb4a24ab40d03111c67c2b0dadddcf9de6b07caaa7c" + }, + { + "path": "docs/quality/logs/file-diff-summary.log", + "bytes": 5005, + "sha256": "fbcbd30011449146fddd37ee1436880cb0847febaadacccfcfbc18fc707a957f" + }, + { + "path": "docs/quality/logs/format-check.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/format-check.log", + "bytes": 128, + "sha256": "35faa5623e1ca69a144301db1bcd12a99642c93e392c00f27f0e373494758bdc" + }, + { + "path": "docs/quality/logs/format-write.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/format-write.log", + "bytes": 13943, + "sha256": "98740297fc6e5972e6da3d76ac01cdfccc56b5babdbc4ffa74ca96b2584128c7" + }, + { + "path": "docs/quality/logs/lint.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/lint.log", + "bytes": 61, + "sha256": "60d1821dc1b8a730153d1b48f9c84e86346955bb7638b724d0d3c321faa5c3f1" + }, + { + "path": "docs/quality/logs/next-typegen.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/next-typegen.log", + "bytes": 59, + "sha256": "adba4af9194e10e47dda75ff0fd0f8c2b756474896d0eba5612799c527ff372a" + }, + { + "path": "docs/quality/logs/npm-install-fallback.log", + "bytes": 284, + "sha256": "e19919345ade861c8cd863d631f57f11c3453e7cc7385a09af24f268875eabd7" + }, + { + "path": "docs/quality/logs/playwright-browser-a11y.log", + "bytes": 61590, + "sha256": "18073dbbf92df28ad060b108985fe0e16e7e6c8ae67ff73bc041cd6024ba6339" + }, + { + "path": "docs/quality/logs/playwright-test-inventory.log", + "bytes": 4605, + "sha256": "e06d4c78a08d0f2cc4b7f329be06904d90d35aa1352b61d593725293649e8d02" + }, + { + "path": "docs/quality/logs/pnpm-audit.log", + "bytes": 367, + "sha256": "c9ca5f084a99651b415d489941280a105a13c553bb38b7f8764a6dd77ecd931b" + }, + { + "path": "docs/quality/logs/pnpm-install-frozen.log", + "bytes": 3204, + "sha256": "5a074969195194b6acad18870ebc51784b1b701f24e9ab76ca9177c317b88b39" + }, + { + "path": "docs/quality/logs/standalone-server.log", + "bytes": 114, + "sha256": "8af62068e13751692799c95679ce8588b6cbbf774d6f8a951668ce2fff36b957" + }, + { + "path": "docs/quality/logs/typecheck.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/typecheck.log", + "bytes": 53, + "sha256": "8b3269bf93de41d5b37919b9c9eb1fdf891529124832dddde796d61642ae0a5b" + }, + { + "path": "docs/quality/logs/unit.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/unit.log", + "bytes": 2254, + "sha256": "0bb10fc9568d6e8e8d15a8027966382cfe691d1e5a0991f1789d26854f171f0f" + }, + { + "path": "docs/quality/logs/validate.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/validate.log", + "bytes": 974, + "sha256": "d71250a821c15c3beb71107aa0098fc014d247d1ea4e5127ca43ba81c7232c2d" + }, + { + "path": "docs/quality/MANUAL_QA_RESULTS_v1.0.csv", + "bytes": 2842, + "sha256": "dba020cda7ffbbc6b05f275fb1c479d102e1f00900ddfc910b6a436f54322a08" + }, + { + "path": "docs/quality/PHASE_11_COMMAND_LOG_v1.0.txt", + "bytes": 2779, + "sha256": "e750ffab91024cb562f5919b8229ce7ed7c0753bc62e96956e7e7275df330cae" + }, + { + "path": "docs/quality/PHASE_11_FILE_CHANGES_v1.0.txt", + "bytes": 3003, + "sha256": "8ac89bb910a600664d799605b51d08b6bc1b99887e36c880b70f9862b684b09c" + }, + { + "path": "docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.json", + "bytes": 1169, + "sha256": "f61ba0cf4eb87f5d4f3b7343c5b0b1c9ce242b28ac673dd9c22a88fdd49f3d47" + }, + { + "path": "docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.md", + "bytes": 2235, + "sha256": "e8eac6f793b461586119e219caa89979b87f3d3ea0254f8fa4602777b2cb7f7d" + }, + { + "path": "docs/quality/PHASE_12_COMMAND_LOG_v1.0.txt", + "bytes": 2261, + "sha256": "9e8d7eeb7d671bbef13b5b48876d095f44558780badb6a3f2dcecd1034ccabba" + }, + { + "path": "docs/quality/PHASE_12_FILE_CHANGES_v1.0.txt", + "bytes": 6129, + "sha256": "46120beed9a87cd0a8272dc3c3b81e41b10cdc150877344ce3658ba370efebdd" + }, + { + "path": "docs/quality/PHASE_12_HTTP_ROUTE_RESULTS_v1.0.json", + "bytes": 999, + "sha256": "502e79659692e8c9c8a97fd1495cefa67250d746db2f4be4d9aa5f1c693042cb" + }, + { + "path": "docs/quality/PHASE_12_MANUAL_QA_RESULTS_v1.0.csv", + "bytes": 3628, + "sha256": "e1a2e78e7e323fe3a2b2e0d1f4f2733234dee6b079393158fd39dcb1261f8902" + }, + { + "path": "docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.json", + "bytes": 4743, + "sha256": "66c771151857321f5de310f3f1d9670ec01f91acb12d209b3e4414530995d3f6" + }, + { + "path": "docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.md", + "bytes": 4050, + "sha256": "581f82dd3a3935914c28a849de0677699662fbf883a17f84d2a8e6ac554c0296" + }, + { + "path": "docs/quality/PHASE_12_VISUAL_REGRESSION_RESULTS_v1.0.json", + "bytes": 517, + "sha256": "d4ffcc9b730a57d3d6a46d4f617cb40b9c0fe5489189dfda7e8e2c2c521bf6d8" + }, + { + "path": "docs/quality/VALIDATION_RESULTS_v1.0.json", + "bytes": 1397, + "sha256": "9b663f7667620496bcbd872e3fc06c725adfb7dbbf6d7bfe8848896f400105d7" + }, + { + "path": "docs/quality/VALIDATION_RESULTS_v1.0.md", + "bytes": 4623, + "sha256": "47d44ee6095cb0bc68fe23148c98403d39309edbb4dd6acdf4a696019e9f0065" + }, + { + "path": "docs/quality/VISUAL_REGRESSION_RESULTS_v1.0.json", + "bytes": 659, + "sha256": "2e94e41c1bdae854d8b1b1db8f62027e896783ece58df0108287c181c7e8caa5" + }, + { + "path": "docs/TOKEN_IMPLEMENTATION_v1.0.md", + "bytes": 2281, + "sha256": "fe6cb88b5689f989cd325a961f2d28cde6f20bea31d2cf572d2a5706c2d7fed7" + }, + { + "path": "eslint.config.mjs", + "bytes": 1031, + "sha256": "14ef56a9899d4c5440c6fe71e713f321b1e1db3de2041b6ad13cd8f798a5225d" + }, + { + "path": "next-env.d.ts", + "bytes": 247, + "sha256": "7b550dda9686c16f36a17bf9051d5dbf31e98555b30d114ac49fc49a1e712651" + }, + { + "path": "next.config.ts", + "bytes": 198, + "sha256": "cd5d6988c4b5ba3b924c236876af7df12edf1f6df71d654ed67500ad450a48eb" + }, + { + "path": "package.json", + "bytes": 2690, + "sha256": "af0438d8c82af55f5fc4f8b371843238bf9d87d6897b2190a98be572ccf486eb" + }, + { + "path": "PHASE_10_PACKAGE_MANIFEST_v1.0.json", + "bytes": 25522, + "sha256": "5a6e185cba91cf3801480ef83f07ed392cd2a85f1f717bb2c4b341235613269c" + }, + { + "path": "PHASE_11_PACKAGE_MANIFEST_v1.0.json", + "bytes": 35023, + "sha256": "060cf87e54f52d00928722188166a24e20949b91c3237e5ac148bdf660b66aaf" + }, + { + "path": "playwright.config.ts", + "bytes": 1718, + "sha256": "93607aeb3be8faa2273b5bad2199f2a6963703fdca15d0160bf711ca9ede082b" + }, + { + "path": "pnpm-lock.yaml", + "bytes": 168864, + "sha256": "c8b40337671246d5a691a4c2c322f6ed184c6b7f99c10095519cf768eb1ace3d" + }, + { + "path": "pnpm-workspace.yaml", + "bytes": 338, + "sha256": "568eba518a28bcd58534a51483092d0a27919aefaec2446e6dd5c6d6ddd80160" + }, + { + "path": "prettier.config.mjs", + "bytes": 164, + "sha256": "2d5316ad27ef10ead128dd2ee82e11b79f067fcf25ea6d504624966739260335" + }, + { + "path": "public/.gitkeep", + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "path": "README.md", + "bytes": 3594, + "sha256": "b6d7741218a92d9019fd2e882b8b5c7e67cca98f66659672d251c8723675207d" + }, + { + "path": "scripts/generate-phase10-manifest.mjs", + "bytes": 1800, + "sha256": "6917fd46f99aacf9de7c89f058380facbf4c8c4adf0baaafb0bf7d1333497808" + }, + { + "path": "scripts/generate-phase11-manifest.mjs", + "bytes": 1800, + "sha256": "4f659193f9741a6c4d0b1bfc8153b426952ce7a9a895b8229bc8fe82530d832b" + }, + { + "path": "scripts/generate-phase12-manifest.mjs", + "bytes": 1771, + "sha256": "2be2e9d9089fc37041ecba9196ca6f2eaed818b7572c470fea4d4c2a4ea4ecd4" + }, + { + "path": "scripts/lib.mjs", + "bytes": 1446, + "sha256": "81c8af9b271572e92ade805dd317dc8738647efe8e89cb37a7c9d1873b5d5edc" + }, + { + "path": "scripts/prepare-standalone.mjs", + "bytes": 813, + "sha256": "f1c1398022048160d71ae14bfa53dd2e431dd2f5aca8f39571de159259af535b" + }, + { + "path": "scripts/run-checks.mjs", + "bytes": 600, + "sha256": "aa1d0192134b288c86ffe68b314b2e379d7865d2e8d5ad0d1f7b29c8e744c7ee" + }, + { + "path": "scripts/run-validations.mjs", + "bytes": 573, + "sha256": "3349f717ec3f0b952607144ab93311f1bf7c7b8dffd3c16c89ad54475583a21b" + }, + { + "path": "scripts/validate-css-logical.mjs", + "bytes": 943, + "sha256": "d47f0346ba94621442c5dc700b53a0219ade3dda7485b4c7f49fb384738c424c" + }, + { + "path": "scripts/validate-locales.mjs", + "bytes": 1875, + "sha256": "dfaf3f34079ea571b17dd2d71d0abf47b48be924818b39c5df93495188b95f43" + }, + { + "path": "scripts/validate-metadata.mjs", + "bytes": 1268, + "sha256": "78127c2c0387e38914388f1a6292ed7a408d672739f8ef5a51e3919fdd2addb0" + }, + { + "path": "scripts/validate-phase10-manifest.mjs", + "bytes": 1192, + "sha256": "29386f182d08ee9096e51a01ea115ae145023724f3d8527fc3ac550152f34d20" + }, + { + "path": "scripts/validate-phase11-foundation.mjs", + "bytes": 2898, + "sha256": "6ada4344545ae50710d9207e0de636c1a8452e6a6bbe3815d51f82ae66667b0d" + }, + { + "path": "scripts/validate-phase11-manifest.mjs", + "bytes": 2950, + "sha256": "977c184291541ad5c6926f8075f96e093dd8957ffc6fe722cc4481a7c079aab7" + }, + { + "path": "scripts/validate-phase12-components.mjs", + "bytes": 3533, + "sha256": "5f07dfdba17bc909cda2fcb0bb52dfac689d1bb9ee4daed5a5640545f48fd01a" + }, + { + "path": "scripts/validate-phase12-manifest.mjs", + "bytes": 2545, + "sha256": "8968feb1e9a0aa6fae696e18fbc1d73dd34881ff4bfe80cfd5f8114a16667ac8" + }, + { + "path": "scripts/validate-phase9-contract.mjs", + "bytes": 1424, + "sha256": "5fce16d33bf6cf7d95136b89f62fd595f109c5d003d54652998dfe3e5b866d6e" + }, + { + "path": "scripts/validate-prohibited-content.mjs", + "bytes": 1068, + "sha256": "3dd645162ad8cd95a28395840fba47a11e2b34e744c7cebdd61a0a9ed3003872" + }, + { + "path": "scripts/validate-routes.mjs", + "bytes": 1611, + "sha256": "d495d43cdfc9505c951b1ed4f7c717d5369b2a637ca31b0b87aae118295c9568" + }, + { + "path": "scripts/validate-runtime-dependencies.mjs", + "bytes": 2188, + "sha256": "f4c43bcaf8fdc78ece6698bcfcdd95413d7a28c1e991f352d74441d0dbbda17f" + }, + { + "path": "scripts/validate-tokens.mjs", + "bytes": 1682, + "sha256": "a508dbee00fe1f991d4f09c2072719e508eb9e14f3ab7d474ba67ca826f45557" + }, + { + "path": "src/app/[locale]/[slug]/page.tsx", + "bytes": 2222, + "sha256": "1f0a103dc658ba88003f5203e3842ec13dc5bdc2bc10695510968043f9ea4dfd" + }, + { + "path": "src/app/[locale]/component-lab/ComponentLabInteractive.tsx", + "bytes": 3620, + "sha256": "87a236be050916440bce01f0c4c5ec9ef31f33a64eff706dbd8ff53febb9868b" + }, + { + "path": "src/app/[locale]/component-lab/page.module.css", + "bytes": 618, + "sha256": "5aa5740b49a0b17da98bb9041e95e9680ae2bfc6de28244b6ddc1d36bdc30372" + }, + { + "path": "src/app/[locale]/component-lab/page.tsx", + "bytes": 2960, + "sha256": "ef7007fbcedfeb3dd96e16ff657b43ed9cac72cd5792dea067d68a61b011c60c" + }, + { + "path": "src/app/[locale]/error.tsx", + "bytes": 693, + "sha256": "129089239ad9e7e5fb941607803ef5dded6df716d3d913b355db015901cea2b5" + }, + { + "path": "src/app/[locale]/layout.tsx", + "bytes": 2363, + "sha256": "3b118c2c9b1f50cd16083af87fa144517f39ffc6676f8db2c5301de4fa831d8d" + }, + { + "path": "src/app/[locale]/loading.tsx", + "bytes": 146, + "sha256": "54cff43832c7ad9d05b82cddb5e2262ec11589a937a54b3c5a2c0da3da6c46b5" + }, + { + "path": "src/app/[locale]/not-found.tsx", + "bytes": 150, + "sha256": "ddb7a1c6f57acebb313117af5c5312398b39a6b698f7347b8fed69c4816e9c00" + }, + { + "path": "src/app/[locale]/page.module.css", + "bytes": 1496, + "sha256": "2b639fd3aaba8171143139914f4dda014e7642d6b6f3bef017b1932b290955c5" + }, + { + "path": "src/app/[locale]/page.tsx", + "bytes": 2742, + "sha256": "f0aeeb12927b1bc326d039d6a96102f0db91109c81ff37756554acb8ab26f3c6" + }, + { + "path": "src/app/robots.ts", + "bytes": 397, + "sha256": "6c1e263671da52c65da390bcbf38b2a11ec9c580a0072295cad11028e082900f" + }, + { + "path": "src/components/actions/ActionLink.module.css", + "bytes": 1250, + "sha256": "7aa5f13eb3a26877c3301056b4e05e30ef9433513bdfdbf2cde544708d7fa7c0" + }, + { + "path": "src/components/actions/ActionLink.tsx", + "bytes": 1963, + "sha256": "5c239401c7c16a7ed42818e664b8f8b6d1929f1d1d2ad26defd832a88372c9cc" + }, + { + "path": "src/components/actions/Button.module.css", + "bytes": 3018, + "sha256": "667e7b647fdec7030cda77a06d5f4509fc1ed941e2b68c65a6e656161708d4a2" + }, + { + "path": "src/components/actions/Button.tsx", + "bytes": 2720, + "sha256": "27933a21d5566700b9cb2dc99f68a53e05f965cae829191f0fe83d75679fc89c" + }, + { + "path": "src/components/app-shell/BrandLink.tsx", + "bytes": 684, + "sha256": "54c482a2e5be262941b943cf2ed123b61dbd4199993d225ec5d22be530b375bb" + }, + { + "path": "src/components/app-shell/Controls.module.css", + "bytes": 743, + "sha256": "fde735d74c28c3131a4c2c6b91146fd844e4af1af351d481033b32e2a8ec1a8c" + }, + { + "path": "src/components/app-shell/DisabledAction.tsx", + "bytes": 682, + "sha256": "4c8327532ccd967895c9ea03477b136eef7f47b169e04ecc728e3af80a152073" + }, + { + "path": "src/components/app-shell/HeaderNavigation.tsx", + "bytes": 1634, + "sha256": "ebfd217810ca31dbafd64ceeaaf8de45a89c6e2aa1d4806a66f2f25dd55e0188" + }, + { + "path": "src/components/app-shell/LocaleSelector.tsx", + "bytes": 1330, + "sha256": "bfcda377c8177aab6e2f5e17fc761dd77009e0310fd281f7dbc07a72f88c162d" + }, + { + "path": "src/components/app-shell/LocalizedLoading.tsx", + "bytes": 503, + "sha256": "b362aa5b94495c599c7cc22e0a3cfa04a29229b6c7f74dde71202f5027a831a5" + }, + { + "path": "src/components/app-shell/LocalizedNotFound.tsx", + "bytes": 794, + "sha256": "3b7a9c001bd3e9818c7bda6f25bc29c9df816d4ced1486542be2b31ccdc476e9" + }, + { + "path": "src/components/app-shell/MobileNavigation.tsx", + "bytes": 4006, + "sha256": "36fb3ec9295a25c55d3075cad06f501fc0159fe08dbd71d54b2622e62af13a6a" + }, + { + "path": "src/components/app-shell/SiteFooter.module.css", + "bytes": 2260, + "sha256": "491af5e5b3137180ffec3833ff2d9e6bfe1d47cf7615a886034e1ff12b89cceb" + }, + { + "path": "src/components/app-shell/SiteFooter.tsx", + "bytes": 4726, + "sha256": "595a6e92ea6a9368d5a2b5c22285f8f3438f47a9d50917875675c13c5f1c64a6" + }, + { + "path": "src/components/app-shell/SiteHeader.module.css", + "bytes": 5120, + "sha256": "587e511e7825b133c964bd9a873c642d9d89152462ba8b6c09e328e24167c21c" + }, + { + "path": "src/components/app-shell/SiteHeader.tsx", + "bytes": 2339, + "sha256": "7a50b6ad74a4a77fe9bb1eb0fdf514862432b0a49603fcb89917750a7b23dc02" + }, + { + "path": "src/components/app-shell/StateShell.module.css", + "bytes": 2014, + "sha256": "acdf7af0cd11250c411dd44291e36cc5053a195a07d3849c2ca9050f6524cf40" + }, + { + "path": "src/components/app-shell/StateShell.tsx", + "bytes": 1378, + "sha256": "633c5d35f024d6c1c7a7b5f2bc128d13ef35a25ac07820c7428dc871d5c01f50" + }, + { + "path": "src/components/app-shell/ThemeController.tsx", + "bytes": 1017, + "sha256": "e3e646ff02c7480a191d4700971ba03b947ddff769687af1f3769e11cd740ce9" + }, + { + "path": "src/components/app-shell/ThemeSelector.tsx", + "bytes": 2319, + "sha256": "04bb79e8b99006786e669ccae0a8d1a845efafceebe6b5d0ab43380a190d1b6f" + }, + { + "path": "src/components/controls/Accordion.module.css", + "bytes": 809, + "sha256": "5a0bf706ab23537146dfa6a03e76753d22987a6df2cab0ddc9a60094f7865ba6" + }, + { + "path": "src/components/controls/Accordion.tsx", + "bytes": 880, + "sha256": "0c26c34d4b7ed1f343101f5a7897806e4a42301181070074a3489668cd425ca3" + }, + { + "path": "src/components/controls/Pagination.module.css", + "bytes": 605, + "sha256": "cb6d2109fd8706e16090e38c0154380c7272c40b723899600d93bd7d44d4af47" + }, + { + "path": "src/components/controls/Pagination.tsx", + "bytes": 1423, + "sha256": "7ea4663bdb23f16c57d29d3503684bed127d7f0f09f68e10e061c3ec8f9255c4" + }, + { + "path": "src/components/controls/SegmentedControl.module.css", + "bytes": 742, + "sha256": "b03cd7de287c4bc182917391461023b103c298bc249b082eebeaaeda12dca041" + }, + { + "path": "src/components/controls/SegmentedControl.tsx", + "bytes": 977, + "sha256": "6fd779b2a0d7f2a8f9a376f595144b92f42b41bc4f520768c104be90085baaf6" + }, + { + "path": "src/components/controls/Tabs.module.css", + "bytes": 688, + "sha256": "2b09531d587bd42d8a45cb78b68ae3581f2ec4979a1d749781311a6a81dbc5b7" + }, + { + "path": "src/components/controls/Tabs.tsx", + "bytes": 3706, + "sha256": "a978deffdbb453dc3f15a149476fbcedc2a857c9e39d1677aa3dfc13423f42da" + }, + { + "path": "src/components/feedback/Alert.module.css", + "bytes": 701, + "sha256": "42437211c46949b798d0544e96983457d34ad17af5a251528a5000a393a7fd11" + }, + { + "path": "src/components/feedback/Alert.tsx", + "bytes": 1185, + "sha256": "743f79b9b1aec74db9d86655bd60d660e5ff8a2b9a2b446f744aa68a9aa401f1" + }, + { + "path": "src/components/feedback/Loading.module.css", + "bytes": 782, + "sha256": "2f8be2f2f54e1b1dae4307012ebc8d7e1b516f99241b99bcc0385632a5583717" + }, + { + "path": "src/components/feedback/Loading.tsx", + "bytes": 1046, + "sha256": "bf766131b06eff6f4bebd03a24839037a2583975256d535462d79b72f1f1214e" + }, + { + "path": "src/components/feedback/Progress.module.css", + "bytes": 298, + "sha256": "a959f3d0f793a16bd913edfbec2c744d037715fb8108dbd7d9f0a4aea2e57f27" + }, + { + "path": "src/components/feedback/Progress.tsx", + "bytes": 969, + "sha256": "a2ec6d0993ec49146170ecf655f23bbcdce7f944dc6b6ae4189676671e77bd08" + }, + { + "path": "src/components/feedback/StateMessage.module.css", + "bytes": 343, + "sha256": "90a4e7a10b9d39eeacd2b127c1c80d0550d3b364cc566667a59ccd6b2d6a436b" + }, + { + "path": "src/components/feedback/StateMessage.tsx", + "bytes": 729, + "sha256": "2f327960e793cefbf8bd501ef7948764390485708217d8f1934eb08c23260f5a" + }, + { + "path": "src/components/forms/ChoiceControls.module.css", + "bytes": 1780, + "sha256": "2ba09892007180658bcbe8621261f1508034398af16929df379684fcdb2850b9" + }, + { + "path": "src/components/forms/ChoiceControls.tsx", + "bytes": 1763, + "sha256": "ddee24498db928491fe82b4db2fa559a5c8b8867bf8d8d7ff1cbfa090218da4d" + }, + { + "path": "src/components/forms/ErrorSummary.module.css", + "bytes": 482, + "sha256": "581e9b4db50083165ec0d9f5e5ccc04d9d5c63696f387389f5a154e039873a87" + }, + { + "path": "src/components/forms/ErrorSummary.tsx", + "bytes": 801, + "sha256": "e5e876e863a894506d717e15953aee906bb54903d6f79df0d09a88e9f0f8108d" + }, + { + "path": "src/components/forms/FormField.module.css", + "bytes": 749, + "sha256": "7bb3eca2e81143d98fb6d6aa4da6cb15f6886ed8ad1885cc5ba83bd10155bdfd" + }, + { + "path": "src/components/forms/FormField.tsx", + "bytes": 1583, + "sha256": "a0ce843fbdfb3eb4ac5104877a0926dd49798ab8d22b09a8a1478c4090e8db45" + }, + { + "path": "src/components/forms/TextInput.module.css", + "bytes": 942, + "sha256": "ebb94b50515bd443c97353b42b8414f1f8848c64e4ffeb1d0e10f517f6857a2b" + }, + { + "path": "src/components/forms/TextInput.tsx", + "bytes": 2439, + "sha256": "e092ea0f8c83f7a0f8a39402240b220e837aa4a1808ffb7d1e6e4946482d44e2" + }, + { + "path": "src/components/foundation/AccessibleIcon.tsx", + "bytes": 352, + "sha256": "cc68b314b3a704037460272f12a05e4185bfbcc08be62bf0facd0d1efa5a5f5c" + }, + { + "path": "src/components/foundation/BidiText.module.css", + "bytes": 35, + "sha256": "0d9480f398007b7e1395f25afd4ba982c6a5dcf299f796ee96fdc1302e5f8b06" + }, + { + "path": "src/components/foundation/BidiText.tsx", + "bytes": 581, + "sha256": "2ed6cb4a821ec1c345b532f51808045490ebaca935bfe93c4bde5fec9292d1f3" + }, + { + "path": "src/components/foundation/client-hooks.ts", + "bytes": 2387, + "sha256": "d4bd6fd5efdd4560d2e356447b24944ffb9ba8f96f57b82b63617923ec457e61" + }, + { + "path": "src/components/foundation/Icon.module.css", + "bytes": 371, + "sha256": "33b3daa50a01cfeb683ea1fa92831efb8d7fd08a7e150370027b88c99118cf4d" + }, + { + "path": "src/components/foundation/Icon.tsx", + "bytes": 3549, + "sha256": "65d3f672bb32bd84745d9f9afd1d1f006debf244aba9e4147c89b3346a4a8764" + }, + { + "path": "src/components/foundation/LiveRegion.module.css", + "bytes": 184, + "sha256": "f5793a73b271c20d10b389245651d7c79fae6417c29e55701e381c0025d20df0" + }, + { + "path": "src/components/foundation/LiveRegion.tsx", + "bytes": 403, + "sha256": "d64aad4af939e2696b955a0632b2869533409698ae3dffede57a18a776e64acf" + }, + { + "path": "src/components/foundation/StatusBadge.module.css", + "bytes": 799, + "sha256": "1f46642795f813e177956bbb25973238275b98b5febb311bb8e7f18597bb2fdb" + }, + { + "path": "src/components/foundation/StatusBadge.tsx", + "bytes": 677, + "sha256": "57eb1b5fdc93f40a3ce5599a4691e76a5976ec8a76d451e8c5008a68262a9706" + }, + { + "path": "src/components/foundation/VisuallyHidden.tsx", + "bytes": 409, + "sha256": "babb1e41cb3ee8691da2653446f8ea38ecce94bcf90645f797cd23f08152213d" + }, + { + "path": "src/components/layout/LayoutPrimitives.module.css", + "bytes": 1106, + "sha256": "4463342699789f2bc38703a7178b62138f10a255555347b692855ea07536dbcc" + }, + { + "path": "src/components/layout/LayoutPrimitives.tsx", + "bytes": 2161, + "sha256": "e3eceb28bcaec129f0324558fd2a13fbfe413615c16943cc691a2a993089de33" + }, + { + "path": "src/components/marketing/Comparison.module.css", + "bytes": 571, + "sha256": "60624d31af0a9fb00f7ebe7bb705d7e6287911133ccd993e6b192ba45da94aec" + }, + { + "path": "src/components/marketing/Comparison.tsx", + "bytes": 1540, + "sha256": "d61e9fbec9780b9252dc5653b3915291fa9c5fc9f58284664a53aa11718cc366" + }, + { + "path": "src/components/marketing/CTA.module.css", + "bytes": 695, + "sha256": "15f1bfe8ac1ce9af110c48985ac572b3369bfca946a02f9392b2adeed8a6eb14" + }, + { + "path": "src/components/marketing/CTA.tsx", + "bytes": 1817, + "sha256": "d201fb5f56f89f16f8958612991b6f674892363e44caafa6452436f65009565a" + }, + { + "path": "src/components/marketing/Evidence.module.css", + "bytes": 412, + "sha256": "a77743583735f99b9b30368987428585ef31f2aabd9c786529657036b82a21f3" + }, + { + "path": "src/components/marketing/Evidence.tsx", + "bytes": 2248, + "sha256": "9fd018f402ef8dc9c130d6a432f6874d74949bf06e2e4947fea62b41d86cec9c" + }, + { + "path": "src/components/marketing/FeatureCard.module.css", + "bytes": 348, + "sha256": "57c384aca1b2526e928463041164d522e69a69d065be274f6429464beb87136f" + }, + { + "path": "src/components/marketing/FeatureCard.tsx", + "bytes": 1444, + "sha256": "9c4bb352e1c4fffaa5566b2b5b190a2305b5935752205dee8b395a25ec9ba206" + }, + { + "path": "src/components/marketing/ProductPreview.module.css", + "bytes": 1272, + "sha256": "4901558b80324028252db79ff79ad7502d55554ca42d42b3b3e6ff4e4462a7dc" + }, + { + "path": "src/components/marketing/ProductPreview.tsx", + "bytes": 2056, + "sha256": "d122e209b4c96dc54829385845bc07fdd37bcd2db3f052352696f85fd05cdb39" + }, + { + "path": "src/components/marketing/SectionHeader.module.css", + "bytes": 216, + "sha256": "6f99ef1f489c765738189363fa8cce40b768db43be0645ac9532e670dd7fd31f" + }, + { + "path": "src/components/marketing/SectionHeader.tsx", + "bytes": 835, + "sha256": "8b9ab5d01fe69b25bd16574105feb74b9e70758df5a9daef32da5d29250760e9" + }, + { + "path": "src/components/marketing/SectionPatterns.module.css", + "bytes": 849, + "sha256": "3f27c9f58bb61032f3432b58fc83c20e619322e573a8460b36113b0116560027" + }, + { + "path": "src/components/marketing/SectionPatterns.tsx", + "bytes": 1004, + "sha256": "0ae2ee1c2a340db787e239a4222b9dd23eb8a688ff711497890570acd8b5eadf" + }, + { + "path": "src/components/marketing/Workflow.module.css", + "bytes": 967, + "sha256": "545620b59d472a2c696183a9e9827f3e7ed8682f462664eee1b6887313a60d56" + }, + { + "path": "src/components/marketing/Workflow.tsx", + "bytes": 1407, + "sha256": "2d64639b356b9f14e3250bff7489b78ee32eceb3e7c628cde5b8f5c68bfa8dce" + }, + { + "path": "src/components/media/MediaFrame.module.css", + "bytes": 634, + "sha256": "c59c885869c8f432c8047f926810b55a185d5f46e1b908a03ef12bc7ed8bf2b7" + }, + { + "path": "src/components/media/MediaFrame.tsx", + "bytes": 1266, + "sha256": "8ef160e29c45690e7dccc3abfd63126425b62cc56673c47a57e01daa00464bf3" + }, + { + "path": "src/components/navigation/Breadcrumbs.module.css", + "bytes": 314, + "sha256": "c981af1d7501fed7832714dfa480f6627928477ff954937c8849f0a9be280aca" + }, + { + "path": "src/components/navigation/Breadcrumbs.tsx", + "bytes": 1175, + "sha256": "359f1e615f25fc3e94c173409fc1946ff95a6fdb9209d86973c3ae96f20c014f" + }, + { + "path": "src/components/navigation/FooterLinkGroup.module.css", + "bytes": 181, + "sha256": "b2622a0cf021181427f219e5aa76a89fdb821240092725bae98282a70aedeb44" + }, + { + "path": "src/components/navigation/FooterLinkGroup.tsx", + "bytes": 775, + "sha256": "9363f1038f6a33840351a51d51374f02c6c1ef32a19cce009c166b141e3d3461" + }, + { + "path": "src/components/navigation/SectionNavigation.module.css", + "bytes": 409, + "sha256": "da941d8adf08ae0826651f3e801965025f4d958b982f3b22a2aa29315b204086" + }, + { + "path": "src/components/navigation/SectionNavigation.tsx", + "bytes": 759, + "sha256": "e86a7d478baa53d315685e79a62b2e8a50d8bbf87d8201f13ae6347844b5f847" + }, + { + "path": "src/components/overlays/Dialog.module.css", + "bytes": 1464, + "sha256": "d1d8402dd4cf4a2777d66d6d08a4859db3b841156c331a5784dd00428ed2ecc4" + }, + { + "path": "src/components/overlays/Dialog.tsx", + "bytes": 2721, + "sha256": "1e52fc4d7a96ee892b7b9c31e8d504831a468bce2b9df17ee576431146f49bf4" + }, + { + "path": "src/components/overlays/DropdownMenu.module.css", + "bytes": 899, + "sha256": "d0f6cab314861fca4f0db886dd9a8981361274503df1aaf123409731302ecdd2" + }, + { + "path": "src/components/overlays/DropdownMenu.tsx", + "bytes": 2776, + "sha256": "db44d077ddb5a05457f1a60cc33383e3fab4ecb6cf0729cef55b21e4dabb58e6" + }, + { + "path": "src/components/overlays/Tooltip.module.css", + "bytes": 1103, + "sha256": "650d232057f795a046e8a7d04109ddaffe10dbbe71ce8796661bc63bb2edf931" + }, + { + "path": "src/components/overlays/Tooltip.tsx", + "bytes": 470, + "sha256": "839d3d08ecc8712eed9f84b3d69cb7e0f43fe450c0454015b85c6d83045115e0" + }, + { + "path": "src/components/surfaces/Callout.module.css", + "bytes": 374, + "sha256": "2f8c824f873308c30bb4612360b30a8807f4718c5820da5068cda35a17809783" + }, + { + "path": "src/components/surfaces/Callout.tsx", + "bytes": 496, + "sha256": "6eff5ca0fa0471ec35463de3e6a632c390ce68685e6dc10f8ea7ba36cb52cec4" + }, + { + "path": "src/components/surfaces/Card.module.css", + "bytes": 977, + "sha256": "014884cdeb170b200f30176e71ac35a01d491048e37c12901063d31fb9ed04d1" + }, + { + "path": "src/components/surfaces/Card.tsx", + "bytes": 1034, + "sha256": "76f6e68536848df8955031f352bee4787d10f191bb486d483438559c2babb4ee" + }, + { + "path": "src/components/typography/Typography.module.css", + "bytes": 1393, + "sha256": "bc1e060c8cdaaf977b787dc1a9a11d08eca8ff3100945d47ca82180e828a47b6" + }, + { + "path": "src/components/typography/Typography.tsx", + "bytes": 1676, + "sha256": "80ec8b42765b90b6558486557cdd677e528f9507fa3bfd205b91cfb52422842c" + }, + { + "path": "src/content/development/component-lab.ts", + "bytes": 14891, + "sha256": "0d90fb8aaac23cd12664ac98d7277d3b32eaf19d19db65ff308c46d5c89cd9b3" + }, + { + "path": "src/content/locales/ar/homepage.json", + "bytes": 17425, + "sha256": "6f0cba2a159531a55b72f345f760344b44bd670e3cd29685712a9215de5b1721" + }, + { + "path": "src/content/locales/ar/shell.json", + "bytes": 4917, + "sha256": "48360fff06aabe1079a7149fc420a3667d25dd2ae67ec38c60f8b02e4a13bb2d" + }, + { + "path": "src/content/locales/en/homepage.json", + "bytes": 12775, + "sha256": "c55d2883811bafd7262792169ebc19700e4a39721f9fe63a2baf096593140f8b" + }, + { + "path": "src/content/locales/en/shell.json", + "bytes": 3682, + "sha256": "359f2ca2d531eab3a7d07f98d78c7f17989e7dc6581c353816979efb1d0734ea" + }, + { + "path": "src/content/locales/fr/homepage.json", + "bytes": 14570, + "sha256": "3d1e4143ff05d562bc8a86ff216840f7cb15168c27b982ae90a5e58bb73ecc6e" + }, + { + "path": "src/content/locales/fr/shell.json", + "bytes": 4271, + "sha256": "24624347f923a5d166c7c19ee79e6a7fa4e083be994ce5ea48bae588f95e92af" + }, + { + "path": "src/contracts/phase9/analytics-contract.ts", + "bytes": 918, + "sha256": "d79b32503a5f8346816c647b8a7f45a62468b96f4fc9525d6d5147b5d2f2ec45" + }, + { + "path": "src/contracts/phase9/analytics-event-spec.csv", + "bytes": 1713, + "sha256": "1282ebca5b031f6267f8139033db437e30b62ac391d25823c8a4783b64151008" + }, + { + "path": "src/contracts/phase9/component-contracts.ts", + "bytes": 3041, + "sha256": "45fb0222d99308b2f28014572316b13c2d7308bc16b1bd02f63b6e2257148399" + }, + { + "path": "src/contracts/phase9/demo-form-contract.ts", + "bytes": 699, + "sha256": "073cf70224f93312d177f77abd7987704205628209e30c44824ae45f929ee59e" + }, + { + "path": "src/contracts/phase9/design-tokens.json", + "bytes": 3771, + "sha256": "470d7bc9d4a466cce4e51f0fdc21fe199ec5b0d4007f5063704c523ce1b9ef0c" + }, + { + "path": "src/contracts/phase9/performance-budgets.json", + "bytes": 815, + "sha256": "e1679ce45d8a1225c46c085c7533d3230a41279c32d0812de5c5f05cb55eefa8" + }, + { + "path": "src/contracts/phase9/route-manifest.json", + "bytes": 1433, + "sha256": "e08ac94ba1f3899bb02dfa934695f530d1089f9f03b0fadaa0feabd466ad8ec4" + }, + { + "path": "src/contracts/phase9/visual-regression-scenarios.json", + "bytes": 1209, + "sha256": "27d961c33c32775485475f7037b8d3bbd13f634b65fe2f59d6eea898860edf5f" + }, + { + "path": "src/lib/components/classNames.ts", + "bytes": 135, + "sha256": "9ec04c6ee51488fbcfebcace04c9e1ea9de3fda7cbc69e233b0bce353ad77824" + }, + { + "path": "src/lib/localization/client-messages.ts", + "bytes": 499, + "sha256": "402d73487e9c57e7f68b2b91b77de8cae27027bac56ac344f310eacd0bb41bd3" + }, + { + "path": "src/lib/localization/client.ts", + "bytes": 593, + "sha256": "bc1ae4b418151cd7b0816b655bf09a4f640ac09540016468e32376594001eb04" + }, + { + "path": "src/lib/localization/config.ts", + "bytes": 4758, + "sha256": "5658aebdfbb912e86b20cef052f6f2784ce64ea89c82fa3d2c05a3a32ec03ed8" + }, + { + "path": "src/lib/localization/format.ts", + "bytes": 2327, + "sha256": "a8f9fbe9bdb5838a910e86897ed13ef9bbfdca6e86514e466bc6a212c236bbfc" + }, + { + "path": "src/lib/localization/messages.ts", + "bytes": 878, + "sha256": "9307df65a80b08e7e1ea7c4e16358fc5fcbde299a00810076bcb36d0a13f9ced" + }, + { + "path": "src/lib/localization/site-origin.ts", + "bytes": 771, + "sha256": "40400ce29fc4adbd9c4490b456968e41fc7596d77ac5bea1c65179e0e4e760ff" + }, + { + "path": "src/lib/metadata/build-metadata.ts", + "bytes": 1322, + "sha256": "3496f11871e635ea6622746de07d74de63a09e648bae9ade02f7c75f042cde7e" + }, + { + "path": "src/lib/security/csp.ts", + "bytes": 830, + "sha256": "f9244e061cc397fbe8720a055e5415b6df34e6c74d0c439ae8d25054d1239c5e" + }, + { + "path": "src/lib/theme/bootstrap-script.ts", + "bytes": 755, + "sha256": "ad1ac642ca61e133f41a5e5b3c062f1b23046f24a58565c6baaacf8c9b261f12" + }, + { + "path": "src/lib/theme/client.ts", + "bytes": 1368, + "sha256": "8bdad550d093755a6f1a20f8b5b59b9d19e0dbd78dbf24c3f4eda5a6dec5811f" + }, + { + "path": "src/lib/theme/config.ts", + "bytes": 821, + "sha256": "c04cd00ce7838fc964d5bdbfaa4c2380f7cd774a9d754987946c97ee8849e60c" + }, + { + "path": "src/proxy.ts", + "bytes": 2625, + "sha256": "522ad1c3650646e652099d61b403075000b4d6e12272df381f5653dbd4745dea" + }, + { + "path": "src/styles/component-tokens.css", + "bytes": 5898, + "sha256": "70665f8912d1e45cbcd1a2674a5cb547395391dae053d0951da157ad88d7de51" + }, + { + "path": "src/styles/globals.css", + "bytes": 2472, + "sha256": "15c39da4ef19e6127bd7f40db21a98d7d2599463af1a13bbd2c3ce786a7ef385" + }, + { + "path": "src/styles/tokens.css", + "bytes": 3553, + "sha256": "99912762e078bfc78b4878fc46b8c7d03d90c073e9c236942a58d83f6585a1b9" + }, + { + "path": "tests/a11y/component-system.a11y.spec.ts", + "bytes": 422, + "sha256": "6324716ef093a4c61601721f36ef652fc40db10f8e93af67ba01ab880d266285" + }, + { + "path": "tests/a11y/shell.a11y.spec.ts", + "bytes": 781, + "sha256": "9f6299337a822d8e4f6783cbfbb3e5da02e42bcca99d8e4519d7f0193072b205" + }, + { + "path": "tests/browser/component-system.spec.ts", + "bytes": 1714, + "sha256": "09bd3833504f68a55952a69299601dbacb3aa3f9e42c3abf9ee4103ac5b0fd32" + }, + { + "path": "tests/browser/navigation.spec.ts", + "bytes": 1120, + "sha256": "7b4aa8bcb7b5c2f09fe82f6c4a5405673e69d45fb5f0833cbe37ee1d237c4c7a" + }, + { + "path": "tests/browser/no-javascript.spec.ts", + "bytes": 568, + "sha256": "a57739c1d0c7c45960129256218a9e95b87ac80a17fc7dee8bd4c95295280fbc" + }, + { + "path": "tests/browser/responsive.spec.ts", + "bytes": 865, + "sha256": "1730baaf20abfe6c47b514a2290f083e28fedd639bc9663e79cddc3f8330eb97" + }, + { + "path": "tests/browser/shell.spec.ts", + "bytes": 2425, + "sha256": "bdd0ce3d9f5e53ff485c45a3f9442e28fb6157d08cb0eccf02268351e18202e6" + }, + { + "path": "tests/browser/text-expansion.spec.ts", + "bytes": 712, + "sha256": "27459e2864eb747d839966b2cb66f4f7527175c953deae9893116a6aa0cf9540" + }, + { + "path": "tests/browser/theme-csp.spec.ts", + "bytes": 2362, + "sha256": "7f9824a86fe70143ff380e82e51076b88a0e466af399ef8a5de4b88c5483d646" + }, + { + "path": "tests/fixtures/component-system/component-matrix.json", + "bytes": 453, + "sha256": "baf694a484a6d769bd9c534e030cf873852612fb60dfe82dc854ea893e92a5a6" + }, + { + "path": "tests/fixtures/foundation-matrix.json", + "bytes": 571, + "sha256": "b5487f1c3970b3413549c7b7500dfc4fb4541cf312ff86b570fa1de56d163ab3" + }, + { + "path": "tests/fixtures/README.md", + "bytes": 495, + "sha256": "e3dba7bdd085bbb1fa43a6b33a94e66641b4437cd01bcfaaaf9c329eee93d3ec" + }, + { + "path": "tests/setup.ts", + "bytes": 43, + "sha256": "91a3c8962a0edcb956206a501d943fe99e1c78c6d4d8b5c9a948a3362c75978c" + }, + { + "path": "tests/types/component-contracts.test-d.tsx", + "bytes": 432, + "sha256": "3a639ef230284c29901abf6b5cc625a515f94853701a57a84b27ac4168352f98" + }, + { + "path": "tests/unit/components/actions.test.tsx", + "bytes": 1366, + "sha256": "891c69eab0e33883408ad5e07b302b2e59dfde1c6eab449f82f0573e4359a835" + }, + { + "path": "tests/unit/components/controls.test.tsx", + "bytes": 1299, + "sha256": "52b52f6603290d5c060e943966e0ba5ec7572f0a914ad295a781bd0657d08b63" + }, + { + "path": "tests/unit/components/evidence.test.tsx", + "bytes": 1276, + "sha256": "0d45214874c8810a57adfc6f5d3b83f9927fc4c9faa930e66d614b041f7e0305" + }, + { + "path": "tests/unit/components/forms.test.tsx", + "bytes": 1349, + "sha256": "71866e0245af2c6f4c8ef955000db91c796142f68f5235dfe22064d381b453f1" + }, + { + "path": "tests/unit/csp.test.ts", + "bytes": 969, + "sha256": "18e4aa4145976102239e92a9c147cc8f0b8442b1bce37b84888246b137280de9" + }, + { + "path": "tests/unit/format.test.ts", + "bytes": 1488, + "sha256": "e7bc5eb89fa3017739180208a1dcfb3f03f3cb3077997dfc7e6e03faa68a9ad1" + }, + { + "path": "tests/unit/localization.test.ts", + "bytes": 2155, + "sha256": "b2e65d904e9ee8018a837ba0c275287d98b44341b9bca65abdb754c09f897511" + }, + { + "path": "tests/unit/theme.test.ts", + "bytes": 734, + "sha256": "45f25fd23f69af3df199473053c47fe219c88fb36a58cffac20a125bdbd47433" + }, + { + "path": "tests/visual/component-system.visual.spec.ts", + "bytes": 799, + "sha256": "60a3ca791efaacf0ca1b38209edfdfe95105740e25228f781ddf771134b82e18" + }, + { + "path": "tests/visual/README.md", + "bytes": 525, + "sha256": "27327d51bda7fc0725a73f6ebb06db1cfa84abd3508985edbb0723da66d18667" + }, + { + "path": "tests/visual/shell.visual.spec.ts", + "bytes": 2273, + "sha256": "07bd6dd398cbab81176ea19741eb8737859bcacaa313a8c17308cd47f736ea5b" + }, + { + "path": "tsconfig.json", + "bytes": 1064, + "sha256": "58d04022fb12a505bcce6fb4d13e60f705641ac5d25d86cdc5c7a4188329e87c" + }, + { + "path": "vitest.config.ts", + "bytes": 699, + "sha256": "c2ac8f10ad2894df28a93e3d2bba2c213f24b9a044db25307078648e010dc3d5" + } + ] +} diff --git a/PHASE_13_PACKAGE_MANIFEST_v1.0.json b/PHASE_13_PACKAGE_MANIFEST_v1.0.json new file mode 100644 index 0000000..c7ba6e8 --- /dev/null +++ b/PHASE_13_PACKAGE_MANIFEST_v1.0.json @@ -0,0 +1,1810 @@ +{ + "schema_version": "1.0", + "project": "RentalDriveGo", + "phase": 13, + "generated_at": "2026-06-25", + "excludes": [ + ".git", + ".next", + "node_modules", + "coverage", + "playwright-report", + "test-results", + "PHASE_13_PACKAGE_MANIFEST_v1.0.json", + "package-lock.json", + "tsconfig.tsbuildinfo" + ], + "file_count": 358, + "files": [ + { + "path": ".dockerignore", + "bytes": 97, + "sha256": "d78b037a836881c2d63f074d525b8027b2ecb06fefe3af4d5356327ec01dc5e1" + }, + { + "path": ".editorconfig", + "bytes": 188, + "sha256": "a6b98ea7cb6d61ed8d430dd0dffa46c87012b5cf859d4ce7207898954951fdcd" + }, + { + "path": ".env.example", + "bytes": 221, + "sha256": "8b9baf40c7a324b56c2b0876f761070a995328843a0f56d7bf97bfeafd06b297" + }, + { + "path": ".github/dependabot.yml", + "bytes": 416, + "sha256": "0a9bdd1890c8fcb78f61f91071df45fecbdcfbbd48441f7da0dba266ba168d82" + }, + { + "path": ".github/workflows/ci.yml", + "bytes": 1739, + "sha256": "c3d1671011688d7ebc4be9f38265e82b290b1aefc9ddd237c1d82fafd3e765f4" + }, + { + "path": ".gitignore", + "bytes": 135, + "sha256": "01c7cded7467134f023106b85684e3ce5df721149fc3ff4af5e02ef79541bb14" + }, + { + "path": ".node-version", + "bytes": 8, + "sha256": "98182b41c9ce3357797985cf12dc3b0124490ef88bc918a905373e7688e6aec9" + }, + { + "path": ".npmrc", + "bytes": 146, + "sha256": "e696a3cc1b84316377f18da909b079072ce02383d16c8fed410f8cabbb9ac054" + }, + { + "path": ".nvmrc", + "bytes": 8, + "sha256": "98182b41c9ce3357797985cf12dc3b0124490ef88bc918a905373e7688e6aec9" + }, + { + "path": ".prettierignore", + "bytes": 129, + "sha256": "272622f9ebbe7cc23717e19053be7c49a6fc63353cad9be57f107cd96b96a142" + }, + { + "path": "contracts/phase9/09_DEVELOPER_HANDOFF_v1.0.md", + "bytes": 8091, + "sha256": "e82d486f1e566d1bf0263f1baa7dd8035ae62da5c36bb6bfa417e61331ec8d51" + }, + { + "path": "contracts/phase9/annotated/ANNOTATION_INDEX_v1.0.md", + "bytes": 685, + "sha256": "a2e87dfdb138409604cac4cc5f52375cce97940da7363f7778af30490699decd" + }, + { + "path": "contracts/phase9/annotated/demo-dialog-en-light_v1.0.png", + "bytes": 51457, + "sha256": "d91bf102100af48feac31478770f8bfdded994ac8b47f60845e4465c50462394" + }, + { + "path": "contracts/phase9/annotated/desktop-en-light_v1.0.png", + "bytes": 144908, + "sha256": "a4151a788317aa9bf8f7262f09f645ebdb54d4a3e1254ab5703ae37e8d3cec16" + }, + { + "path": "contracts/phase9/annotated/mobile-ar-dark_v1.0.png", + "bytes": 75193, + "sha256": "6adcaf68b48bacbf105b670e71edda078a60aa26b732831bd194e1cb9da11556" + }, + { + "path": "contracts/phase9/annotated/mobile-drawer-ar-dark_v1.0.png", + "bytes": 28321, + "sha256": "bc0c14447fb6e80ce904ffcb13c237b51eaa92723702191139bee59b0f7ebdeb" + }, + { + "path": "contracts/phase9/annotated/SCREEN_ANNOTATIONS_v1.0.csv", + "bytes": 1457, + "sha256": "d7b8120926a545f472b62a436b87d2a9d20320a4d95fcf90aa96162c50e8a6da" + }, + { + "path": "contracts/phase9/annotated/tablet-fr-light_v1.0.png", + "bytes": 102305, + "sha256": "dd526fe6859e470ea4c67b4c1ef511cfe0e11126561f86bcff07e57378084347" + }, + { + "path": "contracts/phase9/annotated/tour-dialog-fr-dark_v1.0.png", + "bytes": 94445, + "sha256": "2dd7b24f6505f16a565ac1b5490499ccdae91d0257de608c97c54b7d5b6c2c78" + }, + { + "path": "contracts/phase9/assets/ASSET_MANIFEST_v1.0.csv", + "bytes": 1049, + "sha256": "dd77547327096b4c4084ec8b9311aaff719e378a91f16c2b3ea39832d1bc7b3a" + }, + { + "path": "contracts/phase9/assets/ASSET_USAGE_RULES_v1.0.md", + "bytes": 747, + "sha256": "46821e8e6588a62eba860e4d228b2910a05aa60124610966bdc524a86921f658" + }, + { + "path": "contracts/phase9/assets/brand-mark_v1.0.svg", + "bytes": 443, + "sha256": "bcb3a3fb8037aec69d92da06f0d60fab969547b979a0112f12e6a5c2ab8efdaa" + }, + { + "path": "contracts/phase9/assets/logo-horizontal_v1.0.svg", + "bytes": 576, + "sha256": "04be1c45e1b6e85586efc6dbd36bf3e1e9275fa138a36b93cf6532bbd7409b02" + }, + { + "path": "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "bytes": 9800, + "sha256": "84b455fe725bff11b6ab54bb13373b1aa52991b062a36fad07db47a940187a53" + }, + { + "path": "contracts/phase9/components/COMPONENT_STATE_MATRIX_v1.0.csv", + "bytes": 4283, + "sha256": "c85f96f6d5e020a27c2bd44427a2c3aed3f3cad8657d88a22fc2de9ecd3f6cda" + }, + { + "path": "contracts/phase9/components/CONTENT_CONSTRAINTS_v1.0.csv", + "bytes": 1147, + "sha256": "f4d32b7775f856ff4aac775791566427e3cc340f39cd3f9845d8a3271167228b" + }, + { + "path": "contracts/phase9/components/RESPONSIVE_BEHAVIOR_MATRIX_v1.0.csv", + "bytes": 1416, + "sha256": "0e0e262c0388c37e41f5ab7f3e80835b8edb09e00a9264e81d92953743893353" + }, + { + "path": "contracts/phase9/components/RTL_THEME_MATRIX_v1.0.csv", + "bytes": 4048, + "sha256": "b47f4b3b4e50f1fed6b1b69523a05d61952773e95a966288bfba85dd414edb15" + }, + { + "path": "contracts/phase9/DECISION_LOG_v9.0.md", + "bytes": 38775, + "sha256": "85569a7418f8cad57d094ee9ec1d83b7727b5ab91a405cbda26de0271a8d76a1" + }, + { + "path": "contracts/phase9/DEFINITION_OF_DONE_v1.0.md", + "bytes": 3234, + "sha256": "dfe53a550b7853f015901b83adb960ffb26ab08fa6d7f9f8f8a3386adc705179" + }, + { + "path": "contracts/phase9/implementation/component-contracts_v1.0.ts", + "bytes": 2844, + "sha256": "177dd2420b804290cf1296e43f41a7e759c8859b3253073fbdc523a81f6f94c0" + }, + { + "path": "contracts/phase9/implementation/hreflang-generator_v1.0.ts", + "bytes": 751, + "sha256": "ab919a36a5d08a28c38ae51b4ddd0d84cef5d3ec3bed13649ebd26c3fb80ac8a" + }, + { + "path": "contracts/phase9/implementation/localization-config_v1.0.ts", + "bytes": 772, + "sha256": "bd8ca09f121bfe516ece817948a81d58136e9205fbd2c05dad2ce87f2d7a1782" + }, + { + "path": "contracts/phase9/implementation/TECHNOLOGY_PROFILE_v1.0.md", + "bytes": 1953, + "sha256": "a59504c81bdbb6396eb21e68518ca84862ac89c6c65744de710e9ae273e47c7b" + }, + { + "path": "contracts/phase9/implementation/theme-config_v1.0.ts", + "bytes": 725, + "sha256": "f56d37da4129d5830ba9ebd77b18cd6084a144e8514bfd8a8152387ecf76607c" + }, + { + "path": "contracts/phase9/interaction/ANALYTICS_EVENT_SPEC_v1.0.csv", + "bytes": 1713, + "sha256": "1282ebca5b031f6267f8139033db437e30b62ac391d25823c8a4783b64151008" + }, + { + "path": "contracts/phase9/interaction/analytics-contract_v1.0.ts", + "bytes": 832, + "sha256": "2716eb69cc98032005e068ab7bdc265a4c896a8e1a1bed682c7fdd4f45368123" + }, + { + "path": "contracts/phase9/interaction/demo-form-contract_v1.0.ts", + "bytes": 632, + "sha256": "194db77f7cfca417dbe35e6f2c2ea94cdd02806b83b1d0f1993fe509d8c10154" + }, + { + "path": "contracts/phase9/interaction/INTERACTION_NOTES_v1.0.md", + "bytes": 2332, + "sha256": "0456815622cbb072f1a7594e6b47f52e572e2570280c3a618876246e1b43d2a7" + }, + { + "path": "contracts/phase9/interaction/theme-bootstrap_v1.0.js", + "bytes": 753, + "sha256": "7b89a849bdcd72e1049714ebf76f0c0decb39e44261480f0cb08bb7dfe734e4a" + }, + { + "path": "contracts/phase9/localization/locales/ar/homepage.json", + "bytes": 18615, + "sha256": "fe08aabd60203dbdebc718117f5e497b52a453a8a6fb671fe0bca28651bf0d47" + }, + { + "path": "contracts/phase9/localization/locales/en/homepage.json", + "bytes": 13869, + "sha256": "a5ed956c7f07fad016ca39b40b770c25e8beeae2799ff0fece82dbf087f18e51" + }, + { + "path": "contracts/phase9/localization/locales/fr/homepage.json", + "bytes": 15512, + "sha256": "24079356bd47431ffeb66b7eb2981e108c03080205861b1bb42514b03b945a0a" + }, + { + "path": "contracts/phase9/localization/LOCALIZATION_IMPLEMENTATION_v1.0.md", + "bytes": 2062, + "sha256": "87a494d7ef7ed9f5012ed1699edf90e38995aa89a0efc3800db854e1d57e1024" + }, + { + "path": "contracts/phase9/localization/ROUTE_MANIFEST_v1.0.json", + "bytes": 1573, + "sha256": "fa29b8d31da1f36f87d216a1228fd1bbe1cde337636950b40b0024a10efaf49a" + }, + { + "path": "contracts/phase9/localization/TRANSLATION_KEY_INVENTORY_v1.0.csv", + "bytes": 10599, + "sha256": "01289dc9eb94d546ae717b881b2aed4dfc63b38df38e7767054800122bbb46c2" + }, + { + "path": "contracts/phase9/OPEN_ISSUE_REGISTER_v1.0.csv", + "bytes": 3519, + "sha256": "b8778b3dc7d1e47446584cac046d490a9932c3dfdfa03750716f29852694a214" + }, + { + "path": "contracts/phase9/OPEN_QUESTIONS_v1.0.md", + "bytes": 1085, + "sha256": "82a2abd71830fa4023d346f3b42b138de9e1bbdff74a827d770e6b660d89bd0e" + }, + { + "path": "contracts/phase9/PACKAGE_MANIFEST_v1.0.json", + "bytes": 10649, + "sha256": "1a143f086f40f83414460bd4519e86bd3a34617079e3cfef4c5736375460a24e" + }, + { + "path": "contracts/phase9/PHASE_9_HANDOFF_v1.0.md", + "bytes": 939, + "sha256": "90530b4e70d1fd64d5d934429c009431902639c0570e7944cf050e6d67eb73a3" + }, + { + "path": "contracts/phase9/qa/ACCESSIBILITY_CHECKLIST_v1.0.csv", + "bytes": 1498, + "sha256": "0d9c108e0c02b78aaf11badf6b5f5125cac2b03876cfddf82bd2e97230fdd28b" + }, + { + "path": "contracts/phase9/qa/BROWSER_SUPPORT_MATRIX_v1.0.csv", + "bytes": 986, + "sha256": "5ffb43732fea90530b1b088fb68172b9fc7b2c2683198448734a21cf39c234d1" + }, + { + "path": "contracts/phase9/qa/PERFORMANCE_BUDGETS_v1.0.json", + "bytes": 815, + "sha256": "e1679ce45d8a1225c46c085c7533d3230a41279c32d0812de5c5f05cb55eefa8" + }, + { + "path": "contracts/phase9/qa/PLAYWRIGHT_ACCEPTANCE_SPEC_v1.0.md", + "bytes": 800, + "sha256": "b16384a861d06eb76db5a836868d9a6e03cf72a6a896209279330e19a8d1a785" + }, + { + "path": "contracts/phase9/qa/QA_MATRIX_v1.0.csv", + "bytes": 3557, + "sha256": "6b14b92ce20a9d706de7d6d4cf9f0bb450ecceed27673ed62ae01e145d2143f8" + }, + { + "path": "contracts/phase9/qa/test-ids_v1.0.csv", + "bytes": 598, + "sha256": "6201007ae98632654a2684a0b09ce95d85d9870e0f29774687df0a9876048202" + }, + { + "path": "contracts/phase9/qa/validate-phase9-package_v1.0.mjs", + "bytes": 2534, + "sha256": "631892318cf95c0530a605e5bf08def9b06c93af79b555205f3aeb8a2bcd87ed" + }, + { + "path": "contracts/phase9/qa/visual-regression-scenarios_v1.0.json", + "bytes": 1401, + "sha256": "08a04f676cbb93e73b4c6bc112a55ebf287cb97be3dd3176ab80161e6de743c2" + }, + { + "path": "contracts/phase9/README_v1.0.md", + "bytes": 1258, + "sha256": "ef0010b98ba641c4db453d875171a0d1dad4cb17e991ad23698acde8ac4783ae" + }, + { + "path": "contracts/phase9/reference/FINDINGS_REPORT_v1.0.md", + "bytes": 3062, + "sha256": "ba34afd535856d0eaa8ed7e174c23a7b5f0eae87344c8fcee5daafe00c068ce4" + }, + { + "path": "contracts/phase9/reference/PHASE_8_HANDOFF_v1.0.md", + "bytes": 1117, + "sha256": "2e51ed6645fcc99f30cd4aa9da11ac59e5c2e331c384bfbd758739ad6f42c788" + }, + { + "path": "contracts/phase9/reference/PRIORITIZED_REVISIONS_v1.0.csv", + "bytes": 1071, + "sha256": "65b17813756a2d01c8a9df9faa049b170dca197f243b62a44e070d69f8959df5" + }, + { + "path": "contracts/phase9/reference/SUCCESS_METRICS_v1.0.csv", + "bytes": 1552, + "sha256": "e7b734564735ab65dcaf84ab8374ba163472cca48db1257c4c626415a779ecbe" + }, + { + "path": "contracts/phase9/reference/VALIDATION_RESULTS_v1.0.md", + "bytes": 2068, + "sha256": "3cb17f099569e5bdf4bcd731fe7f687d1636f0e82623c205e07df2cdc2b7d2f2" + }, + { + "path": "contracts/phase9/SOURCE_TRACEABILITY_v1.0.csv", + "bytes": 765, + "sha256": "76dc8677ad0d50263301fd5242bc0649c23bb01d3bbd099bdc8a7e2c04fc2d46" + }, + { + "path": "contracts/phase9/tokens/design-tokens_v1.0.json", + "bytes": 3771, + "sha256": "470d7bc9d4a466cce4e51f0fdc21fe199ec5b0d4007f5063704c523ce1b9ef0c" + }, + { + "path": "contracts/phase9/tokens/semantic-tokens_v1.0.css", + "bytes": 3553, + "sha256": "99912762e078bfc78b4878fc46b8c7d03d90c073e9c236942a58d83f6585a1b9" + }, + { + "path": "contracts/phase9/tokens/TOKEN_USAGE_RULES_v1.0.md", + "bytes": 1222, + "sha256": "b9f7d9b0a9c0595e6f6df2a53e0bcf4acfb47a56abfc6c590a6281c15b04a7b2" + }, + { + "path": "contracts/phase9/tokens/tokens_v1.0.ts", + "bytes": 442, + "sha256": "ec265270251f8dd01d9166aeca3fcec9be2b5e534d825c9058fb6ed3f51e3224" + }, + { + "path": "contracts/phase9/validation/CONTENT_AND_STRUCTURE_VALIDATION_v1.0.json", + "bytes": 189, + "sha256": "e055ef15c2de2191a3465d85ed54f4cf6bd9e1cde4d5d2bba787e14873027b73" + }, + { + "path": "contracts/phase9/validation/STATIC_VALIDATION_RESULTS_v1.0.json", + "bytes": 56, + "sha256": "b60367adf55cf4c61b705d11131b7adebc0aae6ff53732c8272ec9cf2bc95dd3" + }, + { + "path": "contracts/phase9/validation/VALIDATION_RESULTS_v1.0.md", + "bytes": 1179, + "sha256": "6f9df81e75d7149d3826ce215143c21784f39b154660fcefc5325ac114ac70b2" + }, + { + "path": "CONTRIBUTING.md", + "bytes": 1333, + "sha256": "861bf32c35fc615f060dc6e4c3191ed336281fa73946e9049bd7f21713a2df0d" + }, + { + "path": "Dockerfile", + "bytes": 1033, + "sha256": "5e586fd24911d9635ac45d36b9dcba24a44c8eb161b61df7d931f1103e0d70f2" + }, + { + "path": "docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md", + "bytes": 8931, + "sha256": "e2933f3ff3bd9c3066027e20049805fbc2e1ce720534998882f110024afba375" + }, + { + "path": "docs/architecture/ADR-0002_PHASE_11_FOUNDATIONS.md", + "bytes": 4154, + "sha256": "2f04e81f0fac6439fd94a4620c8fa88f062ea7c32ae83c0b26a6b488255e651d" + }, + { + "path": "docs/architecture/ADR-0003_PHASE_12_COMPONENT_SYSTEM.md", + "bytes": 1918, + "sha256": "7ba7bed100e43614b5904d6a20161c55ce99460dbf5e35376cd80b02df9a12eb" + }, + { + "path": "docs/BRAND_MIGRATION_v1.0.md", + "bytes": 1322, + "sha256": "b1fb78b8a0c50b629c8f3af36ec841aa2126739008069a80021b18f8219a3d1c" + }, + { + "path": "docs/DECISION_LOG_v12.0.md", + "bytes": 2835, + "sha256": "c69af78a6af60ba743b057c0c8b50691f7d826923d91c204179fc0683487a0af" + }, + { + "path": "docs/DECISION_LOG_v13.0.md", + "bytes": 2411, + "sha256": "4d5747f12e7b1446ff944540d724957e859264ba0c29b95cba84013591478fdc" + }, + { + "path": "docs/DEPENDENCY_MANIFEST_v1.0.md", + "bytes": 4109, + "sha256": "0dfdaf10352a56b1468ad35436dd873a16d12171e3ea14eac2268359ec02823a" + }, + { + "path": "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv", + "bytes": 5347, + "sha256": "4300820e10088d76f6407ee358a8cc1a3cab89fe6554f658fd770469c8c6c77d" + }, + { + "path": "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv", + "bytes": 6721, + "sha256": "8569e669ddf280d82ebb68526191315aecb108163cb34e4ad1e32a810888cb93" + }, + { + "path": "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.2.csv", + "bytes": 8902, + "sha256": "24725fbb71279b0e6bfdfb05a8d48d01ec132b863fb311eb8d012d9b2151f3d1" + }, + { + "path": "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.3.csv", + "bytes": 10248, + "sha256": "67b3a47100f6404ec1473f4979917b5202169df0b5610f10ff0cb75861b9cc21" + }, + { + "path": "docs/PHASE_10_HANDOFF_v1.0.md", + "bytes": 3370, + "sha256": "8cf52ee1b49cabbf0678da222413b0186ed982fb0c8cfc805482ca18eb1fefc7" + }, + { + "path": "docs/PHASE_10_IMPLEMENTATION_REPORT_v1.0.md", + "bytes": 6805, + "sha256": "6a2e5da443bf15351a0e88e5c92117c8f7c780509d51f2e44c4a148a26a6d4e2" + }, + { + "path": "docs/PHASE_11_IMPLEMENTATION_REPORT_v1.0.md", + "bytes": 13394, + "sha256": "79c1a01be6d5188db29d0bb4a3d2d30b18a5c25b5fa367c7d878309fb5e4dfbb" + }, + { + "path": "docs/PHASE_12_HANDOFF_v1.0.md", + "bytes": 7671, + "sha256": "04000f05533c3accf2409e7810e95ca3188338e33ddae98914ee30e059a09c25" + }, + { + "path": "docs/PHASE_12_IMPLEMENTATION_REPORT_v1.0.md", + "bytes": 12420, + "sha256": "b52db7413ef0365f9ae917133ac4449bf22a95760b25c8bef2fca4f64f3f6040" + }, + { + "path": "docs/PHASE_13_HANDOFF_v1.0.md", + "bytes": 11204, + "sha256": "f82e319eb0d11c861a7d77c4abdc3bcb48e966cb8cfa610389d7807bbaeedb0a" + }, + { + "path": "docs/PHASE_13_IMPLEMENTATION_REPORT_v1.0.md", + "bytes": 8099, + "sha256": "3a7ba99ebf1f22f433e854adb48529575daf1c357aa3271c10fbec152c91479f" + }, + { + "path": "docs/phase12/ACCESSIBILITY_BEHAVIOR_MATRIX_v1.0.csv", + "bytes": 10934, + "sha256": "bf23d29033b091f0556f7a5c07ffc86e31484d82c6fd01a80ffcc33c5daedb0c" + }, + { + "path": "docs/phase12/BUNDLE_IMPACT_REPORT_v1.0.md", + "bytes": 1704, + "sha256": "795ab11fc56780f57c8bba78821106cd5ea00dd02e9aac63c3ddc8865af7f453" + }, + { + "path": "docs/phase12/COMPONENT_CATALOG_v1.0.md", + "bytes": 26256, + "sha256": "93c3d22539c7489166119a8126712995d81fefade081cd06488f3898fa7d519c" + }, + { + "path": "docs/phase12/COMPONENT_INVENTORY_v1.0.json", + "bytes": 42210, + "sha256": "b64cff5d50f7777e6384e6ca19e49a38430925b4a19a53543d35e4452f42d112" + }, + { + "path": "docs/phase12/COMPONENT_SPECIFICATION_TRACEABILITY_v1.0.csv", + "bytes": 11328, + "sha256": "1d352fd6ce9bc3dae7e135725c1deb2ebd44faf679658e8eeb8622266ee08b58" + }, + { + "path": "docs/phase12/DEFINITION_OF_DONE_STATUS_v1.0.md", + "bytes": 1581, + "sha256": "692e3847c7e120939a2ee16dbadd9e6908decaf7f04fa9187e1063f5337dd016" + }, + { + "path": "docs/phase12/DEPENDENCY_CHANGE_REPORT_v1.0.md", + "bytes": 1273, + "sha256": "7c668afb6d310a56fa94d3b88a20cdde5b0594b7005857c915a27edb40aaba0e" + }, + { + "path": "docs/phase12/RESPONSIVE_VALIDATION_MATRIX_v1.0.csv", + "bytes": 16762, + "sha256": "9542e345b81d123e67b12167afc67b946667729cf35a3ce469756627b5368c4d" + }, + { + "path": "docs/phase12/RTL_BEHAVIOR_MATRIX_UPDATE_v1.0.csv", + "bytes": 17557, + "sha256": "c172ed56ff3513bb986894d6fd5814b05391ffcdc432ba3282005e7b8e7c8953" + }, + { + "path": "docs/phase12/STORY_AND_FIXTURE_INVENTORY_v1.0.csv", + "bytes": 565, + "sha256": "f1b3f012c7319e3eacf5b625ada085856dab9fe4392302cc2eb67d79042b5d64" + }, + { + "path": "docs/phase12/TEST_COVERAGE_REPORT_v1.0.csv", + "bytes": 983, + "sha256": "fa174206dec0855a7a9ce328981132ad2114dca73a8511aba8dfd2e953ac9535" + }, + { + "path": "docs/phase12/VARIANT_INVENTORY_v1.0.csv", + "bytes": 17312, + "sha256": "58b988f565cf4e92175bcbd14b0c242b6785d24b5f695e1c12a2a53cb18d0bd1" + }, + { + "path": "docs/phase13/COMPONENT_VARIANT_UPDATE_v1.0.md", + "bytes": 550, + "sha256": "48c1efca62cca59af1d041b811cd15e3ff123cebff22ac905a3a2ca4fab8164a" + }, + { + "path": "docs/phase13/HOMEPAGE_CONTENT_MODEL_v1.0.md", + "bytes": 2290, + "sha256": "d20dd8d92bdd0e73589cc6907c7863d6e6b023d6716aba69cab88d5b97d019fd" + }, + { + "path": "docs/phase13/HOMEPAGE_SECTION_MATRIX_v1.0.csv", + "bytes": 2239, + "sha256": "4fd5ad3074b5217c735ab0c8c02da5690032b50ae5a432776488104313bb3d95" + }, + { + "path": "docs/quality/logs/build-initial.log", + "bytes": 719, + "sha256": "9245b913520a4477ec638d0cdce23f2079c575bdc4a989d0fe68b9d437a5e3b3" + }, + { + "path": "docs/quality/logs/build-missing-site-origin.exit", + "bytes": 2, + "sha256": "4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865" + }, + { + "path": "docs/quality/logs/build-missing-site-origin.log", + "bytes": 922, + "sha256": "b2bff4cccbc95305d2f9304982446920ca76ecfbb6addc9fbff2d95a1538c1f5" + }, + { + "path": "docs/quality/logs/build.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/build.log", + "bytes": 719, + "sha256": "dd0cee291d02930e6ba19eb4a24ab40d03111c67c2b0dadddcf9de6b07caaa7c" + }, + { + "path": "docs/quality/logs/file-diff-summary.log", + "bytes": 5005, + "sha256": "fbcbd30011449146fddd37ee1436880cb0847febaadacccfcfbc18fc707a957f" + }, + { + "path": "docs/quality/logs/format-check.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/format-check.log", + "bytes": 128, + "sha256": "35faa5623e1ca69a144301db1bcd12a99642c93e392c00f27f0e373494758bdc" + }, + { + "path": "docs/quality/logs/format-write.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/format-write.log", + "bytes": 13943, + "sha256": "98740297fc6e5972e6da3d76ac01cdfccc56b5babdbc4ffa74ca96b2584128c7" + }, + { + "path": "docs/quality/logs/lint.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/lint.log", + "bytes": 61, + "sha256": "60d1821dc1b8a730153d1b48f9c84e86346955bb7638b724d0d3c321faa5c3f1" + }, + { + "path": "docs/quality/logs/next-typegen.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/next-typegen.log", + "bytes": 59, + "sha256": "adba4af9194e10e47dda75ff0fd0f8c2b756474896d0eba5612799c527ff372a" + }, + { + "path": "docs/quality/logs/npm-install-fallback.log", + "bytes": 284, + "sha256": "e19919345ade861c8cd863d631f57f11c3453e7cc7385a09af24f268875eabd7" + }, + { + "path": "docs/quality/logs/playwright-browser-a11y.log", + "bytes": 61590, + "sha256": "18073dbbf92df28ad060b108985fe0e16e7e6c8ae67ff73bc041cd6024ba6339" + }, + { + "path": "docs/quality/logs/playwright-test-inventory.log", + "bytes": 4605, + "sha256": "e06d4c78a08d0f2cc4b7f329be06904d90d35aa1352b61d593725293649e8d02" + }, + { + "path": "docs/quality/logs/pnpm-audit.log", + "bytes": 367, + "sha256": "c9ca5f084a99651b415d489941280a105a13c553bb38b7f8764a6dd77ecd931b" + }, + { + "path": "docs/quality/logs/pnpm-install-frozen.log", + "bytes": 3204, + "sha256": "5a074969195194b6acad18870ebc51784b1b701f24e9ab76ca9177c317b88b39" + }, + { + "path": "docs/quality/logs/standalone-server.log", + "bytes": 114, + "sha256": "8af62068e13751692799c95679ce8588b6cbbf774d6f8a951668ce2fff36b957" + }, + { + "path": "docs/quality/logs/typecheck.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/typecheck.log", + "bytes": 53, + "sha256": "8b3269bf93de41d5b37919b9c9eb1fdf891529124832dddde796d61642ae0a5b" + }, + { + "path": "docs/quality/logs/unit.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/unit.log", + "bytes": 2254, + "sha256": "0bb10fc9568d6e8e8d15a8027966382cfe691d1e5a0991f1789d26854f171f0f" + }, + { + "path": "docs/quality/logs/validate.exit", + "bytes": 2, + "sha256": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa" + }, + { + "path": "docs/quality/logs/validate.log", + "bytes": 974, + "sha256": "d71250a821c15c3beb71107aa0098fc014d247d1ea4e5127ca43ba81c7232c2d" + }, + { + "path": "docs/quality/MANUAL_QA_RESULTS_v1.0.csv", + "bytes": 2842, + "sha256": "dba020cda7ffbbc6b05f275fb1c479d102e1f00900ddfc910b6a436f54322a08" + }, + { + "path": "docs/quality/PHASE_11_COMMAND_LOG_v1.0.txt", + "bytes": 2779, + "sha256": "e750ffab91024cb562f5919b8229ce7ed7c0753bc62e96956e7e7275df330cae" + }, + { + "path": "docs/quality/PHASE_11_FILE_CHANGES_v1.0.txt", + "bytes": 3003, + "sha256": "8ac89bb910a600664d799605b51d08b6bc1b99887e36c880b70f9862b684b09c" + }, + { + "path": "docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.json", + "bytes": 1169, + "sha256": "f61ba0cf4eb87f5d4f3b7343c5b0b1c9ce242b28ac673dd9c22a88fdd49f3d47" + }, + { + "path": "docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.md", + "bytes": 2235, + "sha256": "e8eac6f793b461586119e219caa89979b87f3d3ea0254f8fa4602777b2cb7f7d" + }, + { + "path": "docs/quality/PHASE_12_COMMAND_LOG_v1.0.txt", + "bytes": 2261, + "sha256": "9e8d7eeb7d671bbef13b5b48876d095f44558780badb6a3f2dcecd1034ccabba" + }, + { + "path": "docs/quality/PHASE_12_FILE_CHANGES_v1.0.txt", + "bytes": 6129, + "sha256": "46120beed9a87cd0a8272dc3c3b81e41b10cdc150877344ce3658ba370efebdd" + }, + { + "path": "docs/quality/PHASE_12_HTTP_ROUTE_RESULTS_v1.0.json", + "bytes": 999, + "sha256": "502e79659692e8c9c8a97fd1495cefa67250d746db2f4be4d9aa5f1c693042cb" + }, + { + "path": "docs/quality/PHASE_12_MANUAL_QA_RESULTS_v1.0.csv", + "bytes": 3628, + "sha256": "e1a2e78e7e323fe3a2b2e0d1f4f2733234dee6b079393158fd39dcb1261f8902" + }, + { + "path": "docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.json", + "bytes": 4743, + "sha256": "66c771151857321f5de310f3f1d9670ec01f91acb12d209b3e4414530995d3f6" + }, + { + "path": "docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.md", + "bytes": 4050, + "sha256": "581f82dd3a3935914c28a849de0677699662fbf883a17f84d2a8e6ac554c0296" + }, + { + "path": "docs/quality/PHASE_12_VISUAL_REGRESSION_RESULTS_v1.0.json", + "bytes": 517, + "sha256": "d4ffcc9b730a57d3d6a46d4f617cb40b9c0fe5489189dfda7e8e2c2c521bf6d8" + }, + { + "path": "docs/quality/PHASE_13_COMMAND_LOG_v1.0.txt", + "bytes": 1225, + "sha256": "4f8a2074c0ccc3b16e3d1656688d52ea0fe6fc3b9bd125d23b00b1b682b8533a" + }, + { + "path": "docs/quality/PHASE_13_FILE_CHANGES_v1.0.txt", + "bytes": 1051, + "sha256": "95e446fe77e3412f02f236f6c6891df11ab76857aa77b4497a82f2c64e0b34cb" + }, + { + "path": "docs/quality/PHASE_13_HTTP_ROUTE_RESULTS_v1.0.json", + "bytes": 553, + "sha256": "6ab331a76652ad7b7183d4ead068fb9e5af13c10e361148a36c207f619c235c4" + }, + { + "path": "docs/quality/PHASE_13_MANUAL_QA_RESULTS_v1.0.csv", + "bytes": 1571, + "sha256": "5cffba29bff2974118bc17ca9bc9ceb94cc1b5504d1a04a92ad43a67b04dbe47" + }, + { + "path": "docs/quality/PHASE_13_VALIDATION_RESULTS_v1.0.json", + "bytes": 2964, + "sha256": "bde83fe8e06a47fcf235821c055f9fa12f72c5cdd472d04e35f1f9b99738fe23" + }, + { + "path": "docs/quality/PHASE_13_VALIDATION_RESULTS_v1.0.md", + "bytes": 4094, + "sha256": "457a045db7fa620029f94929f2fd86e7d1549a787b53949a50b08b4f039182a6" + }, + { + "path": "docs/quality/VALIDATION_RESULTS_v1.0.json", + "bytes": 1397, + "sha256": "9b663f7667620496bcbd872e3fc06c725adfb7dbbf6d7bfe8848896f400105d7" + }, + { + "path": "docs/quality/VALIDATION_RESULTS_v1.0.md", + "bytes": 4623, + "sha256": "47d44ee6095cb0bc68fe23148c98403d39309edbb4dd6acdf4a696019e9f0065" + }, + { + "path": "docs/quality/VISUAL_REGRESSION_RESULTS_v1.0.json", + "bytes": 659, + "sha256": "2e94e41c1bdae854d8b1b1db8f62027e896783ece58df0108287c181c7e8caa5" + }, + { + "path": "docs/TOKEN_IMPLEMENTATION_v1.0.md", + "bytes": 2281, + "sha256": "fe6cb88b5689f989cd325a961f2d28cde6f20bea31d2cf572d2a5706c2d7fed7" + }, + { + "path": "eslint.config.mjs", + "bytes": 1031, + "sha256": "14ef56a9899d4c5440c6fe71e713f321b1e1db3de2041b6ad13cd8f798a5225d" + }, + { + "path": "next-env.d.ts", + "bytes": 247, + "sha256": "7b550dda9686c16f36a17bf9051d5dbf31e98555b30d114ac49fc49a1e712651" + }, + { + "path": "next.config.ts", + "bytes": 198, + "sha256": "cd5d6988c4b5ba3b924c236876af7df12edf1f6df71d654ed67500ad450a48eb" + }, + { + "path": "package.json", + "bytes": 2753, + "sha256": "45e08255f3a2e95401af988a1d4b0f13bbb573a80f9c952cbacf437128f369d6" + }, + { + "path": "PHASE_10_PACKAGE_MANIFEST_v1.0.json", + "bytes": 25522, + "sha256": "5a6e185cba91cf3801480ef83f07ed392cd2a85f1f717bb2c4b341235613269c" + }, + { + "path": "PHASE_11_PACKAGE_MANIFEST_v1.0.json", + "bytes": 35023, + "sha256": "060cf87e54f52d00928722188166a24e20949b91c3237e5ac148bdf660b66aaf" + }, + { + "path": "PHASE_12_PACKAGE_MANIFEST_v1.0.json", + "bytes": 58828, + "sha256": "1eb7d488f70fd147f0e34d5ffcb2f40e05d6e6094629c9fb2374f42cb4651906" + }, + { + "path": "playwright.config.ts", + "bytes": 1718, + "sha256": "93607aeb3be8faa2273b5bad2199f2a6963703fdca15d0160bf711ca9ede082b" + }, + { + "path": "pnpm-lock.yaml", + "bytes": 168864, + "sha256": "c8b40337671246d5a691a4c2c322f6ed184c6b7f99c10095519cf768eb1ace3d" + }, + { + "path": "pnpm-workspace.yaml", + "bytes": 338, + "sha256": "568eba518a28bcd58534a51483092d0a27919aefaec2446e6dd5c6d6ddd80160" + }, + { + "path": "prettier.config.mjs", + "bytes": 164, + "sha256": "2d5316ad27ef10ead128dd2ee82e11b79f067fcf25ea6d504624966739260335" + }, + { + "path": "public/.gitkeep", + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "path": "README.md", + "bytes": 3594, + "sha256": "b6d7741218a92d9019fd2e882b8b5c7e67cca98f66659672d251c8723675207d" + }, + { + "path": "scripts/generate-phase10-manifest.mjs", + "bytes": 1800, + "sha256": "6917fd46f99aacf9de7c89f058380facbf4c8c4adf0baaafb0bf7d1333497808" + }, + { + "path": "scripts/generate-phase11-manifest.mjs", + "bytes": 1800, + "sha256": "4f659193f9741a6c4d0b1bfc8153b426952ce7a9a895b8229bc8fe82530d832b" + }, + { + "path": "scripts/generate-phase12-manifest.mjs", + "bytes": 1771, + "sha256": "2be2e9d9089fc37041ecba9196ca6f2eaed818b7572c470fea4d4c2a4ea4ecd4" + }, + { + "path": "scripts/generate-phase13-manifest.mjs", + "bytes": 1801, + "sha256": "43e242d20eee8fd4a06747c340187e43a87fcd1da7f99c2c295ece7d62c9a710" + }, + { + "path": "scripts/lib.mjs", + "bytes": 1446, + "sha256": "81c8af9b271572e92ade805dd317dc8738647efe8e89cb37a7c9d1873b5d5edc" + }, + { + "path": "scripts/prepare-standalone.mjs", + "bytes": 813, + "sha256": "f1c1398022048160d71ae14bfa53dd2e431dd2f5aca8f39571de159259af535b" + }, + { + "path": "scripts/run-checks.mjs", + "bytes": 600, + "sha256": "aa1d0192134b288c86ffe68b314b2e379d7865d2e8d5ad0d1f7b29c8e744c7ee" + }, + { + "path": "scripts/run-validations.mjs", + "bytes": 608, + "sha256": "3edb3bcb7512f080465831e3c0cbfc48493d7f37b7d1866107f2aa8c7b9d0532" + }, + { + "path": "scripts/validate-css-logical.mjs", + "bytes": 943, + "sha256": "d47f0346ba94621442c5dc700b53a0219ade3dda7485b4c7f49fb384738c424c" + }, + { + "path": "scripts/validate-locales.mjs", + "bytes": 1875, + "sha256": "dfaf3f34079ea571b17dd2d71d0abf47b48be924818b39c5df93495188b95f43" + }, + { + "path": "scripts/validate-metadata.mjs", + "bytes": 1268, + "sha256": "78127c2c0387e38914388f1a6292ed7a408d672739f8ef5a51e3919fdd2addb0" + }, + { + "path": "scripts/validate-phase10-manifest.mjs", + "bytes": 1192, + "sha256": "29386f182d08ee9096e51a01ea115ae145023724f3d8527fc3ac550152f34d20" + }, + { + "path": "scripts/validate-phase11-foundation.mjs", + "bytes": 2898, + "sha256": "6ada4344545ae50710d9207e0de636c1a8452e6a6bbe3815d51f82ae66667b0d" + }, + { + "path": "scripts/validate-phase11-manifest.mjs", + "bytes": 2950, + "sha256": "977c184291541ad5c6926f8075f96e093dd8957ffc6fe722cc4481a7c079aab7" + }, + { + "path": "scripts/validate-phase12-components.mjs", + "bytes": 3533, + "sha256": "5f07dfdba17bc909cda2fcb0bb52dfac689d1bb9ee4daed5a5640545f48fd01a" + }, + { + "path": "scripts/validate-phase12-manifest.mjs", + "bytes": 2545, + "sha256": "8968feb1e9a0aa6fae696e18fbc1d73dd34881ff4bfe80cfd5f8114a16667ac8" + }, + { + "path": "scripts/validate-phase13-homepage.mjs", + "bytes": 2514, + "sha256": "5a8e8cfb5f1512d02a08a6c8d7952436700b1fd9ebc9d6384ae3191a4eda353c" + }, + { + "path": "scripts/validate-phase13-manifest.mjs", + "bytes": 2576, + "sha256": "407e334829c01206c92ad80fcb9347f8288e48e46455de19a50a26cc9f87ed1f" + }, + { + "path": "scripts/validate-phase9-contract.mjs", + "bytes": 1424, + "sha256": "5fce16d33bf6cf7d95136b89f62fd595f109c5d003d54652998dfe3e5b866d6e" + }, + { + "path": "scripts/validate-prohibited-content.mjs", + "bytes": 1068, + "sha256": "3dd645162ad8cd95a28395840fba47a11e2b34e744c7cebdd61a0a9ed3003872" + }, + { + "path": "scripts/validate-routes.mjs", + "bytes": 1611, + "sha256": "d495d43cdfc9505c951b1ed4f7c717d5369b2a637ca31b0b87aae118295c9568" + }, + { + "path": "scripts/validate-runtime-dependencies.mjs", + "bytes": 2188, + "sha256": "f4c43bcaf8fdc78ece6698bcfcdd95413d7a28c1e991f352d74441d0dbbda17f" + }, + { + "path": "scripts/validate-tokens.mjs", + "bytes": 1682, + "sha256": "a508dbee00fe1f991d4f09c2072719e508eb9e14f3ab7d474ba67ca826f45557" + }, + { + "path": "src/app/[locale]/[slug]/page.tsx", + "bytes": 2222, + "sha256": "1f0a103dc658ba88003f5203e3842ec13dc5bdc2bc10695510968043f9ea4dfd" + }, + { + "path": "src/app/[locale]/component-lab/ComponentLabInteractive.tsx", + "bytes": 3620, + "sha256": "87a236be050916440bce01f0c4c5ec9ef31f33a64eff706dbd8ff53febb9868b" + }, + { + "path": "src/app/[locale]/component-lab/page.module.css", + "bytes": 618, + "sha256": "5aa5740b49a0b17da98bb9041e95e9680ae2bfc6de28244b6ddc1d36bdc30372" + }, + { + "path": "src/app/[locale]/component-lab/page.tsx", + "bytes": 2960, + "sha256": "ef7007fbcedfeb3dd96e16ff657b43ed9cac72cd5792dea067d68a61b011c60c" + }, + { + "path": "src/app/[locale]/error.tsx", + "bytes": 693, + "sha256": "129089239ad9e7e5fb941607803ef5dded6df716d3d913b355db015901cea2b5" + }, + { + "path": "src/app/[locale]/layout.tsx", + "bytes": 2363, + "sha256": "3b118c2c9b1f50cd16083af87fa144517f39ffc6676f8db2c5301de4fa831d8d" + }, + { + "path": "src/app/[locale]/loading.tsx", + "bytes": 146, + "sha256": "54cff43832c7ad9d05b82cddb5e2262ec11589a937a54b3c5a2c0da3da6c46b5" + }, + { + "path": "src/app/[locale]/not-found.tsx", + "bytes": 150, + "sha256": "ddb7a1c6f57acebb313117af5c5312398b39a6b698f7347b8fed69c4816e9c00" + }, + { + "path": "src/app/[locale]/page.module.css", + "bytes": 3805, + "sha256": "ae5a4800050ffb7c4afae1b427a2a8c1900baa825064b7cbc96ac6316a68319d" + }, + { + "path": "src/app/[locale]/page.tsx", + "bytes": 11892, + "sha256": "ddbc2b1a001b393f9f36f3a9490fdb63574329cf8d5a07e400f281aa98366e00" + }, + { + "path": "src/app/robots.ts", + "bytes": 397, + "sha256": "6c1e263671da52c65da390bcbf38b2a11ec9c580a0072295cad11028e082900f" + }, + { + "path": "src/components/actions/ActionLink.module.css", + "bytes": 1250, + "sha256": "7aa5f13eb3a26877c3301056b4e05e30ef9433513bdfdbf2cde544708d7fa7c0" + }, + { + "path": "src/components/actions/ActionLink.tsx", + "bytes": 1963, + "sha256": "5c239401c7c16a7ed42818e664b8f8b6d1929f1d1d2ad26defd832a88372c9cc" + }, + { + "path": "src/components/actions/Button.module.css", + "bytes": 3018, + "sha256": "667e7b647fdec7030cda77a06d5f4509fc1ed941e2b68c65a6e656161708d4a2" + }, + { + "path": "src/components/actions/Button.tsx", + "bytes": 2720, + "sha256": "27933a21d5566700b9cb2dc99f68a53e05f965cae829191f0fe83d75679fc89c" + }, + { + "path": "src/components/app-shell/BrandLink.tsx", + "bytes": 684, + "sha256": "54c482a2e5be262941b943cf2ed123b61dbd4199993d225ec5d22be530b375bb" + }, + { + "path": "src/components/app-shell/Controls.module.css", + "bytes": 743, + "sha256": "fde735d74c28c3131a4c2c6b91146fd844e4af1af351d481033b32e2a8ec1a8c" + }, + { + "path": "src/components/app-shell/DisabledAction.tsx", + "bytes": 682, + "sha256": "4c8327532ccd967895c9ea03477b136eef7f47b169e04ecc728e3af80a152073" + }, + { + "path": "src/components/app-shell/HeaderNavigation.tsx", + "bytes": 1634, + "sha256": "ebfd217810ca31dbafd64ceeaaf8de45a89c6e2aa1d4806a66f2f25dd55e0188" + }, + { + "path": "src/components/app-shell/LocaleSelector.tsx", + "bytes": 1330, + "sha256": "bfcda377c8177aab6e2f5e17fc761dd77009e0310fd281f7dbc07a72f88c162d" + }, + { + "path": "src/components/app-shell/LocalizedLoading.tsx", + "bytes": 503, + "sha256": "b362aa5b94495c599c7cc22e0a3cfa04a29229b6c7f74dde71202f5027a831a5" + }, + { + "path": "src/components/app-shell/LocalizedNotFound.tsx", + "bytes": 794, + "sha256": "3b7a9c001bd3e9818c7bda6f25bc29c9df816d4ced1486542be2b31ccdc476e9" + }, + { + "path": "src/components/app-shell/MobileNavigation.tsx", + "bytes": 4006, + "sha256": "36fb3ec9295a25c55d3075cad06f501fc0159fe08dbd71d54b2622e62af13a6a" + }, + { + "path": "src/components/app-shell/SiteFooter.module.css", + "bytes": 2260, + "sha256": "491af5e5b3137180ffec3833ff2d9e6bfe1d47cf7615a886034e1ff12b89cceb" + }, + { + "path": "src/components/app-shell/SiteFooter.tsx", + "bytes": 4726, + "sha256": "595a6e92ea6a9368d5a2b5c22285f8f3438f47a9d50917875675c13c5f1c64a6" + }, + { + "path": "src/components/app-shell/SiteHeader.module.css", + "bytes": 5120, + "sha256": "587e511e7825b133c964bd9a873c642d9d89152462ba8b6c09e328e24167c21c" + }, + { + "path": "src/components/app-shell/SiteHeader.tsx", + "bytes": 2339, + "sha256": "7a50b6ad74a4a77fe9bb1eb0fdf514862432b0a49603fcb89917750a7b23dc02" + }, + { + "path": "src/components/app-shell/StateShell.module.css", + "bytes": 2014, + "sha256": "acdf7af0cd11250c411dd44291e36cc5053a195a07d3849c2ca9050f6524cf40" + }, + { + "path": "src/components/app-shell/StateShell.tsx", + "bytes": 1378, + "sha256": "633c5d35f024d6c1c7a7b5f2bc128d13ef35a25ac07820c7428dc871d5c01f50" + }, + { + "path": "src/components/app-shell/ThemeController.tsx", + "bytes": 1017, + "sha256": "e3e646ff02c7480a191d4700971ba03b947ddff769687af1f3769e11cd740ce9" + }, + { + "path": "src/components/app-shell/ThemeSelector.tsx", + "bytes": 2319, + "sha256": "04bb79e8b99006786e669ccae0a8d1a845efafceebe6b5d0ab43380a190d1b6f" + }, + { + "path": "src/components/controls/Accordion.module.css", + "bytes": 809, + "sha256": "5a0bf706ab23537146dfa6a03e76753d22987a6df2cab0ddc9a60094f7865ba6" + }, + { + "path": "src/components/controls/Accordion.tsx", + "bytes": 880, + "sha256": "0c26c34d4b7ed1f343101f5a7897806e4a42301181070074a3489668cd425ca3" + }, + { + "path": "src/components/controls/Pagination.module.css", + "bytes": 605, + "sha256": "cb6d2109fd8706e16090e38c0154380c7272c40b723899600d93bd7d44d4af47" + }, + { + "path": "src/components/controls/Pagination.tsx", + "bytes": 1423, + "sha256": "7ea4663bdb23f16c57d29d3503684bed127d7f0f09f68e10e061c3ec8f9255c4" + }, + { + "path": "src/components/controls/SegmentedControl.module.css", + "bytes": 742, + "sha256": "b03cd7de287c4bc182917391461023b103c298bc249b082eebeaaeda12dca041" + }, + { + "path": "src/components/controls/SegmentedControl.tsx", + "bytes": 977, + "sha256": "6fd779b2a0d7f2a8f9a376f595144b92f42b41bc4f520768c104be90085baaf6" + }, + { + "path": "src/components/controls/Tabs.module.css", + "bytes": 688, + "sha256": "2b09531d587bd42d8a45cb78b68ae3581f2ec4979a1d749781311a6a81dbc5b7" + }, + { + "path": "src/components/controls/Tabs.tsx", + "bytes": 3706, + "sha256": "a978deffdbb453dc3f15a149476fbcedc2a857c9e39d1677aa3dfc13423f42da" + }, + { + "path": "src/components/feedback/Alert.module.css", + "bytes": 701, + "sha256": "42437211c46949b798d0544e96983457d34ad17af5a251528a5000a393a7fd11" + }, + { + "path": "src/components/feedback/Alert.tsx", + "bytes": 1185, + "sha256": "743f79b9b1aec74db9d86655bd60d660e5ff8a2b9a2b446f744aa68a9aa401f1" + }, + { + "path": "src/components/feedback/Loading.module.css", + "bytes": 782, + "sha256": "2f8be2f2f54e1b1dae4307012ebc8d7e1b516f99241b99bcc0385632a5583717" + }, + { + "path": "src/components/feedback/Loading.tsx", + "bytes": 1046, + "sha256": "bf766131b06eff6f4bebd03a24839037a2583975256d535462d79b72f1f1214e" + }, + { + "path": "src/components/feedback/Progress.module.css", + "bytes": 298, + "sha256": "a959f3d0f793a16bd913edfbec2c744d037715fb8108dbd7d9f0a4aea2e57f27" + }, + { + "path": "src/components/feedback/Progress.tsx", + "bytes": 969, + "sha256": "a2ec6d0993ec49146170ecf655f23bbcdce7f944dc6b6ae4189676671e77bd08" + }, + { + "path": "src/components/feedback/StateMessage.module.css", + "bytes": 343, + "sha256": "90a4e7a10b9d39eeacd2b127c1c80d0550d3b364cc566667a59ccd6b2d6a436b" + }, + { + "path": "src/components/feedback/StateMessage.tsx", + "bytes": 729, + "sha256": "2f327960e793cefbf8bd501ef7948764390485708217d8f1934eb08c23260f5a" + }, + { + "path": "src/components/forms/ChoiceControls.module.css", + "bytes": 1780, + "sha256": "2ba09892007180658bcbe8621261f1508034398af16929df379684fcdb2850b9" + }, + { + "path": "src/components/forms/ChoiceControls.tsx", + "bytes": 1763, + "sha256": "ddee24498db928491fe82b4db2fa559a5c8b8867bf8d8d7ff1cbfa090218da4d" + }, + { + "path": "src/components/forms/ErrorSummary.module.css", + "bytes": 482, + "sha256": "581e9b4db50083165ec0d9f5e5ccc04d9d5c63696f387389f5a154e039873a87" + }, + { + "path": "src/components/forms/ErrorSummary.tsx", + "bytes": 801, + "sha256": "e5e876e863a894506d717e15953aee906bb54903d6f79df0d09a88e9f0f8108d" + }, + { + "path": "src/components/forms/FormField.module.css", + "bytes": 749, + "sha256": "7bb3eca2e81143d98fb6d6aa4da6cb15f6886ed8ad1885cc5ba83bd10155bdfd" + }, + { + "path": "src/components/forms/FormField.tsx", + "bytes": 1583, + "sha256": "a0ce843fbdfb3eb4ac5104877a0926dd49798ab8d22b09a8a1478c4090e8db45" + }, + { + "path": "src/components/forms/TextInput.module.css", + "bytes": 942, + "sha256": "ebb94b50515bd443c97353b42b8414f1f8848c64e4ffeb1d0e10f517f6857a2b" + }, + { + "path": "src/components/forms/TextInput.tsx", + "bytes": 2439, + "sha256": "e092ea0f8c83f7a0f8a39402240b220e837aa4a1808ffb7d1e6e4946482d44e2" + }, + { + "path": "src/components/foundation/AccessibleIcon.tsx", + "bytes": 352, + "sha256": "cc68b314b3a704037460272f12a05e4185bfbcc08be62bf0facd0d1efa5a5f5c" + }, + { + "path": "src/components/foundation/BidiText.module.css", + "bytes": 35, + "sha256": "0d9480f398007b7e1395f25afd4ba982c6a5dcf299f796ee96fdc1302e5f8b06" + }, + { + "path": "src/components/foundation/BidiText.tsx", + "bytes": 581, + "sha256": "2ed6cb4a821ec1c345b532f51808045490ebaca935bfe93c4bde5fec9292d1f3" + }, + { + "path": "src/components/foundation/client-hooks.ts", + "bytes": 2387, + "sha256": "d4bd6fd5efdd4560d2e356447b24944ffb9ba8f96f57b82b63617923ec457e61" + }, + { + "path": "src/components/foundation/Icon.module.css", + "bytes": 371, + "sha256": "33b3daa50a01cfeb683ea1fa92831efb8d7fd08a7e150370027b88c99118cf4d" + }, + { + "path": "src/components/foundation/Icon.tsx", + "bytes": 3549, + "sha256": "65d3f672bb32bd84745d9f9afd1d1f006debf244aba9e4147c89b3346a4a8764" + }, + { + "path": "src/components/foundation/LiveRegion.module.css", + "bytes": 184, + "sha256": "f5793a73b271c20d10b389245651d7c79fae6417c29e55701e381c0025d20df0" + }, + { + "path": "src/components/foundation/LiveRegion.tsx", + "bytes": 403, + "sha256": "d64aad4af939e2696b955a0632b2869533409698ae3dffede57a18a776e64acf" + }, + { + "path": "src/components/foundation/StatusBadge.module.css", + "bytes": 799, + "sha256": "1f46642795f813e177956bbb25973238275b98b5febb311bb8e7f18597bb2fdb" + }, + { + "path": "src/components/foundation/StatusBadge.tsx", + "bytes": 677, + "sha256": "57eb1b5fdc93f40a3ce5599a4691e76a5976ec8a76d451e8c5008a68262a9706" + }, + { + "path": "src/components/foundation/VisuallyHidden.tsx", + "bytes": 409, + "sha256": "babb1e41cb3ee8691da2653446f8ea38ecce94bcf90645f797cd23f08152213d" + }, + { + "path": "src/components/layout/LayoutPrimitives.module.css", + "bytes": 1106, + "sha256": "4463342699789f2bc38703a7178b62138f10a255555347b692855ea07536dbcc" + }, + { + "path": "src/components/layout/LayoutPrimitives.tsx", + "bytes": 2161, + "sha256": "e3eceb28bcaec129f0324558fd2a13fbfe413615c16943cc691a2a993089de33" + }, + { + "path": "src/components/marketing/Comparison.module.css", + "bytes": 571, + "sha256": "60624d31af0a9fb00f7ebe7bb705d7e6287911133ccd993e6b192ba45da94aec" + }, + { + "path": "src/components/marketing/Comparison.tsx", + "bytes": 1540, + "sha256": "d61e9fbec9780b9252dc5653b3915291fa9c5fc9f58284664a53aa11718cc366" + }, + { + "path": "src/components/marketing/CTA.module.css", + "bytes": 695, + "sha256": "15f1bfe8ac1ce9af110c48985ac572b3369bfca946a02f9392b2adeed8a6eb14" + }, + { + "path": "src/components/marketing/CTA.tsx", + "bytes": 1817, + "sha256": "d201fb5f56f89f16f8958612991b6f674892363e44caafa6452436f65009565a" + }, + { + "path": "src/components/marketing/Evidence.module.css", + "bytes": 412, + "sha256": "a77743583735f99b9b30368987428585ef31f2aabd9c786529657036b82a21f3" + }, + { + "path": "src/components/marketing/Evidence.tsx", + "bytes": 2248, + "sha256": "9fd018f402ef8dc9c130d6a432f6874d74949bf06e2e4947fea62b41d86cec9c" + }, + { + "path": "src/components/marketing/FeatureCard.module.css", + "bytes": 348, + "sha256": "57c384aca1b2526e928463041164d522e69a69d065be274f6429464beb87136f" + }, + { + "path": "src/components/marketing/FeatureCard.tsx", + "bytes": 1444, + "sha256": "9c4bb352e1c4fffaa5566b2b5b190a2305b5935752205dee8b395a25ec9ba206" + }, + { + "path": "src/components/marketing/ProductPreview.module.css", + "bytes": 1272, + "sha256": "4901558b80324028252db79ff79ad7502d55554ca42d42b3b3e6ff4e4462a7dc" + }, + { + "path": "src/components/marketing/ProductPreview.tsx", + "bytes": 2137, + "sha256": "00dbcf972d8414cc79538a7552843ac93d28c97dec700d596d4a2571ea7f3c5c" + }, + { + "path": "src/components/marketing/SectionHeader.module.css", + "bytes": 216, + "sha256": "6f99ef1f489c765738189363fa8cce40b768db43be0645ac9532e670dd7fd31f" + }, + { + "path": "src/components/marketing/SectionHeader.tsx", + "bytes": 835, + "sha256": "8b9ab5d01fe69b25bd16574105feb74b9e70758df5a9daef32da5d29250760e9" + }, + { + "path": "src/components/marketing/SectionPatterns.module.css", + "bytes": 849, + "sha256": "3f27c9f58bb61032f3432b58fc83c20e619322e573a8460b36113b0116560027" + }, + { + "path": "src/components/marketing/SectionPatterns.tsx", + "bytes": 1004, + "sha256": "0ae2ee1c2a340db787e239a4222b9dd23eb8a688ff711497890570acd8b5eadf" + }, + { + "path": "src/components/marketing/Workflow.module.css", + "bytes": 967, + "sha256": "545620b59d472a2c696183a9e9827f3e7ed8682f462664eee1b6887313a60d56" + }, + { + "path": "src/components/marketing/Workflow.tsx", + "bytes": 1407, + "sha256": "2d64639b356b9f14e3250bff7489b78ee32eceb3e7c628cde5b8f5c68bfa8dce" + }, + { + "path": "src/components/media/MediaFrame.module.css", + "bytes": 634, + "sha256": "c59c885869c8f432c8047f926810b55a185d5f46e1b908a03ef12bc7ed8bf2b7" + }, + { + "path": "src/components/media/MediaFrame.tsx", + "bytes": 1266, + "sha256": "8ef160e29c45690e7dccc3abfd63126425b62cc56673c47a57e01daa00464bf3" + }, + { + "path": "src/components/navigation/Breadcrumbs.module.css", + "bytes": 314, + "sha256": "c981af1d7501fed7832714dfa480f6627928477ff954937c8849f0a9be280aca" + }, + { + "path": "src/components/navigation/Breadcrumbs.tsx", + "bytes": 1175, + "sha256": "359f1e615f25fc3e94c173409fc1946ff95a6fdb9209d86973c3ae96f20c014f" + }, + { + "path": "src/components/navigation/FooterLinkGroup.module.css", + "bytes": 181, + "sha256": "b2622a0cf021181427f219e5aa76a89fdb821240092725bae98282a70aedeb44" + }, + { + "path": "src/components/navigation/FooterLinkGroup.tsx", + "bytes": 775, + "sha256": "9363f1038f6a33840351a51d51374f02c6c1ef32a19cce009c166b141e3d3461" + }, + { + "path": "src/components/navigation/SectionNavigation.module.css", + "bytes": 409, + "sha256": "da941d8adf08ae0826651f3e801965025f4d958b982f3b22a2aa29315b204086" + }, + { + "path": "src/components/navigation/SectionNavigation.tsx", + "bytes": 759, + "sha256": "e86a7d478baa53d315685e79a62b2e8a50d8bbf87d8201f13ae6347844b5f847" + }, + { + "path": "src/components/overlays/Dialog.module.css", + "bytes": 1464, + "sha256": "d1d8402dd4cf4a2777d66d6d08a4859db3b841156c331a5784dd00428ed2ecc4" + }, + { + "path": "src/components/overlays/Dialog.tsx", + "bytes": 2721, + "sha256": "1e52fc4d7a96ee892b7b9c31e8d504831a468bce2b9df17ee576431146f49bf4" + }, + { + "path": "src/components/overlays/DropdownMenu.module.css", + "bytes": 899, + "sha256": "d0f6cab314861fca4f0db886dd9a8981361274503df1aaf123409731302ecdd2" + }, + { + "path": "src/components/overlays/DropdownMenu.tsx", + "bytes": 2776, + "sha256": "db44d077ddb5a05457f1a60cc33383e3fab4ecb6cf0729cef55b21e4dabb58e6" + }, + { + "path": "src/components/overlays/Tooltip.module.css", + "bytes": 1103, + "sha256": "650d232057f795a046e8a7d04109ddaffe10dbbe71ce8796661bc63bb2edf931" + }, + { + "path": "src/components/overlays/Tooltip.tsx", + "bytes": 470, + "sha256": "839d3d08ecc8712eed9f84b3d69cb7e0f43fe450c0454015b85c6d83045115e0" + }, + { + "path": "src/components/surfaces/Callout.module.css", + "bytes": 374, + "sha256": "2f8c824f873308c30bb4612360b30a8807f4718c5820da5068cda35a17809783" + }, + { + "path": "src/components/surfaces/Callout.tsx", + "bytes": 496, + "sha256": "6eff5ca0fa0471ec35463de3e6a632c390ce68685e6dc10f8ea7ba36cb52cec4" + }, + { + "path": "src/components/surfaces/Card.module.css", + "bytes": 977, + "sha256": "014884cdeb170b200f30176e71ac35a01d491048e37c12901063d31fb9ed04d1" + }, + { + "path": "src/components/surfaces/Card.tsx", + "bytes": 1034, + "sha256": "76f6e68536848df8955031f352bee4787d10f191bb486d483438559c2babb4ee" + }, + { + "path": "src/components/typography/Typography.module.css", + "bytes": 1393, + "sha256": "bc1e060c8cdaaf977b787dc1a9a11d08eca8ff3100945d47ca82180e828a47b6" + }, + { + "path": "src/components/typography/Typography.tsx", + "bytes": 1676, + "sha256": "80ec8b42765b90b6558486557cdd677e528f9507fa3bfd205b91cfb52422842c" + }, + { + "path": "src/content/development/component-lab.ts", + "bytes": 14891, + "sha256": "0d90fb8aaac23cd12664ac98d7277d3b32eaf19d19db65ff308c46d5c89cd9b3" + }, + { + "path": "src/content/homepage-model.ts", + "bytes": 7885, + "sha256": "41b10af10f4b9351e994d22302704c9c118db7b91a896c992fa3e4a6e1870bc8" + }, + { + "path": "src/content/locales/ar/homepage.json", + "bytes": 17425, + "sha256": "6f0cba2a159531a55b72f345f760344b44bd670e3cd29685712a9215de5b1721" + }, + { + "path": "src/content/locales/ar/shell.json", + "bytes": 4917, + "sha256": "48360fff06aabe1079a7149fc420a3667d25dd2ae67ec38c60f8b02e4a13bb2d" + }, + { + "path": "src/content/locales/en/homepage.json", + "bytes": 12775, + "sha256": "c55d2883811bafd7262792169ebc19700e4a39721f9fe63a2baf096593140f8b" + }, + { + "path": "src/content/locales/en/shell.json", + "bytes": 3682, + "sha256": "359f2ca2d531eab3a7d07f98d78c7f17989e7dc6581c353816979efb1d0734ea" + }, + { + "path": "src/content/locales/fr/homepage.json", + "bytes": 14570, + "sha256": "3d1e4143ff05d562bc8a86ff216840f7cb15168c27b982ae90a5e58bb73ecc6e" + }, + { + "path": "src/content/locales/fr/shell.json", + "bytes": 4271, + "sha256": "24624347f923a5d166c7c19ee79e6a7fa4e083be994ce5ea48bae588f95e92af" + }, + { + "path": "src/contracts/phase9/analytics-contract.ts", + "bytes": 918, + "sha256": "d79b32503a5f8346816c647b8a7f45a62468b96f4fc9525d6d5147b5d2f2ec45" + }, + { + "path": "src/contracts/phase9/analytics-event-spec.csv", + "bytes": 1713, + "sha256": "1282ebca5b031f6267f8139033db437e30b62ac391d25823c8a4783b64151008" + }, + { + "path": "src/contracts/phase9/component-contracts.ts", + "bytes": 3041, + "sha256": "45fb0222d99308b2f28014572316b13c2d7308bc16b1bd02f63b6e2257148399" + }, + { + "path": "src/contracts/phase9/demo-form-contract.ts", + "bytes": 699, + "sha256": "073cf70224f93312d177f77abd7987704205628209e30c44824ae45f929ee59e" + }, + { + "path": "src/contracts/phase9/design-tokens.json", + "bytes": 3771, + "sha256": "470d7bc9d4a466cce4e51f0fdc21fe199ec5b0d4007f5063704c523ce1b9ef0c" + }, + { + "path": "src/contracts/phase9/performance-budgets.json", + "bytes": 815, + "sha256": "e1679ce45d8a1225c46c085c7533d3230a41279c32d0812de5c5f05cb55eefa8" + }, + { + "path": "src/contracts/phase9/route-manifest.json", + "bytes": 1433, + "sha256": "e08ac94ba1f3899bb02dfa934695f530d1089f9f03b0fadaa0feabd466ad8ec4" + }, + { + "path": "src/contracts/phase9/visual-regression-scenarios.json", + "bytes": 1209, + "sha256": "27d961c33c32775485475f7037b8d3bbd13f634b65fe2f59d6eea898860edf5f" + }, + { + "path": "src/lib/components/classNames.ts", + "bytes": 135, + "sha256": "9ec04c6ee51488fbcfebcace04c9e1ea9de3fda7cbc69e233b0bce353ad77824" + }, + { + "path": "src/lib/localization/client-messages.ts", + "bytes": 499, + "sha256": "402d73487e9c57e7f68b2b91b77de8cae27027bac56ac344f310eacd0bb41bd3" + }, + { + "path": "src/lib/localization/client.ts", + "bytes": 593, + "sha256": "bc1ae4b418151cd7b0816b655bf09a4f640ac09540016468e32376594001eb04" + }, + { + "path": "src/lib/localization/config.ts", + "bytes": 4758, + "sha256": "5658aebdfbb912e86b20cef052f6f2784ce64ea89c82fa3d2c05a3a32ec03ed8" + }, + { + "path": "src/lib/localization/format.ts", + "bytes": 2327, + "sha256": "a8f9fbe9bdb5838a910e86897ed13ef9bbfdca6e86514e466bc6a212c236bbfc" + }, + { + "path": "src/lib/localization/messages.ts", + "bytes": 878, + "sha256": "9307df65a80b08e7e1ea7c4e16358fc5fcbde299a00810076bcb36d0a13f9ced" + }, + { + "path": "src/lib/localization/site-origin.ts", + "bytes": 771, + "sha256": "40400ce29fc4adbd9c4490b456968e41fc7596d77ac5bea1c65179e0e4e760ff" + }, + { + "path": "src/lib/metadata/build-metadata.ts", + "bytes": 1322, + "sha256": "3496f11871e635ea6622746de07d74de63a09e648bae9ade02f7c75f042cde7e" + }, + { + "path": "src/lib/security/csp.ts", + "bytes": 830, + "sha256": "f9244e061cc397fbe8720a055e5415b6df34e6c74d0c439ae8d25054d1239c5e" + }, + { + "path": "src/lib/theme/bootstrap-script.ts", + "bytes": 755, + "sha256": "ad1ac642ca61e133f41a5e5b3c062f1b23046f24a58565c6baaacf8c9b261f12" + }, + { + "path": "src/lib/theme/client.ts", + "bytes": 1368, + "sha256": "8bdad550d093755a6f1a20f8b5b59b9d19e0dbd78dbf24c3f4eda5a6dec5811f" + }, + { + "path": "src/lib/theme/config.ts", + "bytes": 821, + "sha256": "c04cd00ce7838fc964d5bdbfaa4c2380f7cd774a9d754987946c97ee8849e60c" + }, + { + "path": "src/proxy.ts", + "bytes": 2625, + "sha256": "522ad1c3650646e652099d61b403075000b4d6e12272df381f5653dbd4745dea" + }, + { + "path": "src/styles/component-tokens.css", + "bytes": 5898, + "sha256": "70665f8912d1e45cbcd1a2674a5cb547395391dae053d0951da157ad88d7de51" + }, + { + "path": "src/styles/globals.css", + "bytes": 2472, + "sha256": "15c39da4ef19e6127bd7f40db21a98d7d2599463af1a13bbd2c3ce786a7ef385" + }, + { + "path": "src/styles/tokens.css", + "bytes": 3553, + "sha256": "99912762e078bfc78b4878fc46b8c7d03d90c073e9c236942a58d83f6585a1b9" + }, + { + "path": "tests/a11y/component-system.a11y.spec.ts", + "bytes": 422, + "sha256": "6324716ef093a4c61601721f36ef652fc40db10f8e93af67ba01ab880d266285" + }, + { + "path": "tests/a11y/homepage.a11y.spec.ts", + "bytes": 901, + "sha256": "b096866589cdc74dba4224cc4b8dd2af045ff33c04168d6e3de0a9f8b42152c8" + }, + { + "path": "tests/a11y/shell.a11y.spec.ts", + "bytes": 781, + "sha256": "9f6299337a822d8e4f6783cbfbb3e5da02e42bcca99d8e4519d7f0193072b205" + }, + { + "path": "tests/browser/component-system.spec.ts", + "bytes": 1714, + "sha256": "09bd3833504f68a55952a69299601dbacb3aa3f9e42c3abf9ee4103ac5b0fd32" + }, + { + "path": "tests/browser/homepage.spec.ts", + "bytes": 2097, + "sha256": "4c7dfb24129ad4ed9542e784364e2293fe26473d2073f05bffe6c194f32466e2" + }, + { + "path": "tests/browser/navigation.spec.ts", + "bytes": 1120, + "sha256": "7b4aa8bcb7b5c2f09fe82f6c4a5405673e69d45fb5f0833cbe37ee1d237c4c7a" + }, + { + "path": "tests/browser/no-javascript.spec.ts", + "bytes": 568, + "sha256": "a57739c1d0c7c45960129256218a9e95b87ac80a17fc7dee8bd4c95295280fbc" + }, + { + "path": "tests/browser/responsive.spec.ts", + "bytes": 865, + "sha256": "1730baaf20abfe6c47b514a2290f083e28fedd639bc9663e79cddc3f8330eb97" + }, + { + "path": "tests/browser/shell.spec.ts", + "bytes": 2425, + "sha256": "bdd0ce3d9f5e53ff485c45a3f9442e28fb6157d08cb0eccf02268351e18202e6" + }, + { + "path": "tests/browser/text-expansion.spec.ts", + "bytes": 712, + "sha256": "27459e2864eb747d839966b2cb66f4f7527175c953deae9893116a6aa0cf9540" + }, + { + "path": "tests/browser/theme-csp.spec.ts", + "bytes": 2362, + "sha256": "7f9824a86fe70143ff380e82e51076b88a0e466af399ef8a5de4b88c5483d646" + }, + { + "path": "tests/fixtures/component-system/component-matrix.json", + "bytes": 453, + "sha256": "baf694a484a6d769bd9c534e030cf873852612fb60dfe82dc854ea893e92a5a6" + }, + { + "path": "tests/fixtures/foundation-matrix.json", + "bytes": 571, + "sha256": "b5487f1c3970b3413549c7b7500dfc4fb4541cf312ff86b570fa1de56d163ab3" + }, + { + "path": "tests/fixtures/README.md", + "bytes": 495, + "sha256": "e3dba7bdd085bbb1fa43a6b33a94e66641b4437cd01bcfaaaf9c329eee93d3ec" + }, + { + "path": "tests/setup.ts", + "bytes": 43, + "sha256": "91a3c8962a0edcb956206a501d943fe99e1c78c6d4d8b5c9a948a3362c75978c" + }, + { + "path": "tests/types/component-contracts.test-d.tsx", + "bytes": 432, + "sha256": "3a639ef230284c29901abf6b5cc625a515f94853701a57a84b27ac4168352f98" + }, + { + "path": "tests/unit/components/actions.test.tsx", + "bytes": 1366, + "sha256": "891c69eab0e33883408ad5e07b302b2e59dfde1c6eab449f82f0573e4359a835" + }, + { + "path": "tests/unit/components/controls.test.tsx", + "bytes": 1299, + "sha256": "52b52f6603290d5c060e943966e0ba5ec7572f0a914ad295a781bd0657d08b63" + }, + { + "path": "tests/unit/components/evidence.test.tsx", + "bytes": 1276, + "sha256": "0d45214874c8810a57adfc6f5d3b83f9927fc4c9faa930e66d614b041f7e0305" + }, + { + "path": "tests/unit/components/forms.test.tsx", + "bytes": 1349, + "sha256": "71866e0245af2c6f4c8ef955000db91c796142f68f5235dfe22064d381b453f1" + }, + { + "path": "tests/unit/csp.test.ts", + "bytes": 969, + "sha256": "18e4aa4145976102239e92a9c147cc8f0b8442b1bce37b84888246b137280de9" + }, + { + "path": "tests/unit/format.test.ts", + "bytes": 1488, + "sha256": "e7bc5eb89fa3017739180208a1dcfb3f03f3cb3077997dfc7e6e03faa68a9ad1" + }, + { + "path": "tests/unit/homepage-content.test.ts", + "bytes": 1752, + "sha256": "3755d445f9420d2bd8044a712c2ff4dd16d562d93bbe4f5b76b4d8b838f0f803" + }, + { + "path": "tests/unit/localization.test.ts", + "bytes": 2155, + "sha256": "b2e65d904e9ee8018a837ba0c275287d98b44341b9bca65abdb754c09f897511" + }, + { + "path": "tests/unit/theme.test.ts", + "bytes": 734, + "sha256": "45f25fd23f69af3df199473053c47fe219c88fb36a58cffac20a125bdbd47433" + }, + { + "path": "tests/visual/component-system.visual.spec.ts", + "bytes": 799, + "sha256": "60a3ca791efaacf0ca1b38209edfdfe95105740e25228f781ddf771134b82e18" + }, + { + "path": "tests/visual/homepage.visual.spec.ts", + "bytes": 1336, + "sha256": "fe75876ca2073be31b0c5423b5f329dde0ea19fa065bae514bfb4758544de97f" + }, + { + "path": "tests/visual/README.md", + "bytes": 525, + "sha256": "27327d51bda7fc0725a73f6ebb06db1cfa84abd3508985edbb0723da66d18667" + }, + { + "path": "tests/visual/shell.visual.spec.ts", + "bytes": 2273, + "sha256": "07bd6dd398cbab81176ea19741eb8737859bcacaa313a8c17308cd47f736ea5b" + }, + { + "path": "tsconfig.json", + "bytes": 1064, + "sha256": "58d04022fb12a505bcce6fb4d13e60f705641ac5d25d86cdc5c7a4188329e87c" + }, + { + "path": "vitest.config.ts", + "bytes": 699, + "sha256": "c2ac8f10ad2894df28a93e3d2bba2c213f24b9a044db25307078648e010dc3d5" + } + ] +} diff --git a/README 2.md b/README 2.md new file mode 100644 index 0000000..3b88fda --- /dev/null +++ b/README 2.md @@ -0,0 +1,103 @@ +# RentalDriveGo Web + +Phase 11 production foundation for the multilingual RentalDriveGo marketing website. + +## Implemented scope + +- English, French, and Arabic locale-prefixed routes +- server-rendered `lang` and document-level direction +- immutable Phase 9 tokens plus a documented component-facing token layer +- light, dark, and system themes +- nonce-based CSP-compatible pre-paint theme bootstrap +- CSS-only system-theme fallback +- locale-aware formatters and bidi primitives +- responsive layout primitives +- accessible sticky header and native-dialog mobile navigation +- localized footer +- loading, error, not-found, and pending-destination shells +- localized canonical, reciprocal `hreflang`, Open Graph, and robots foundations +- unit, browser, accessibility, responsive, and visual test definitions + +The complete production homepage, demo form, CRM, analytics, pricing, customer evidence, final legal content, login integration, final logo, and external destinations remain outside this phase or explicitly gated. + +## Runtime + +- Node.js `24.17.0` +- pnpm `11.9.0` +- Next.js `16.2.9` +- React `19.2.7` + +Use the exact versions in `.node-version`, `.nvmrc`, `package.json`, and `pnpm-lock.yaml`. + +## Local setup + +```bash +corepack enable +corepack prepare pnpm@11.9.0 --activate +pnpm install --frozen-lockfile +cp .env.example .env.local +pnpm dev +``` + +Development routes: + +- `/en` +- `/fr` +- `/ar` + +Root `/` redirects using the locale cookie, then `Accept-Language`, then English. + +## Required checks + +```bash +pnpm validate +pnpm validate:package +pnpm format:check +pnpm lint +pnpm typecheck +pnpm test:unit +SITE_ORIGIN=http://127.0.0.1:3000 PUBLIC_RELEASE_APPROVED=false pnpm build +pnpm test:e2e +``` + +Generate reviewed visual baselines only in the pinned browser environment: + +```bash +pnpm test:visual:update --project=chromium +``` + +Do not approve snapshots merely because the pixels repeat reliably. Computers can preserve a mistake with extraordinary discipline. + +## Release safety + +`PUBLIC_RELEASE_APPROVED` defaults to false. While false, pages emit `noindex` and `robots.txt` disallows crawling. + +Do not enable public release until the updated issue register has no blocking release issues. Unapproved login and legal routes render explicit pending shells. Demo and contact actions remain disabled rather than pointing at invented integrations. + +## Documentation + +- Phase 11 report: `docs/PHASE_11_IMPLEMENTATION_REPORT_v1.0.md` +- Phase 12 handoff: `docs/PHASE_12_HANDOFF_v1.0.md` +- Phase 11 architecture: `docs/architecture/ADR-0002_PHASE_11_FOUNDATIONS.md` +- Token implementation: `docs/TOKEN_IMPLEMENTATION_v1.0.md` +- Updated issue register: `docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv` +- Validation evidence: `docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.md` +- Manual QA: `docs/quality/MANUAL_QA_RESULTS_v1.0.csv` +- Visual status: `docs/quality/VISUAL_REGRESSION_RESULTS_v1.0.json` +- Contribution rules: `CONTRIBUTING.md` +- Immutable Phase 9 package: `contracts/phase9` +- Phase 11 package manifest: `PHASE_11_PACKAGE_MANIFEST_v1.0.json` + +## Phase 12 component system + +The repository now contains the reusable RentalDriveGo component system and a guarded component workbench at `/{locale}/component-lab`. Enable it only for development or tests with `COMPONENT_FIXTURES_ENABLED=true`. + +Key records: + +- `docs/PHASE_12_IMPLEMENTATION_REPORT_v1.0.md` +- `docs/PHASE_13_HANDOFF_v1.0.md` +- `docs/phase12/COMPONENT_CATALOG_v1.0.md` +- `docs/phase12/COMPONENT_INVENTORY_v1.0.json` +- `docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.md` + +Formal acceptance remains gated by the cumulative issue register. diff --git a/contracts/phase9/09_DEVELOPER_HANDOFF_v1.0.md b/contracts/phase9/09_DEVELOPER_HANDOFF_v1.0.md new file mode 100644 index 0000000..a3f698a --- /dev/null +++ b/contracts/phase9/09_DEVELOPER_HANDOFF_v1.0.md @@ -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 `` 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 ``; 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 `` 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`. diff --git a/contracts/phase9/DECISION_LOG_v9.0.md b/contracts/phase9/DECISION_LOG_v9.0.md new file mode 100644 index 0000000..29c3869 --- /dev/null +++ b/contracts/phase9/DECISION_LOG_v9.0.md @@ -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 | diff --git a/contracts/phase9/DEFINITION_OF_DONE_v1.0.md b/contracts/phase9/DEFINITION_OF_DONE_v1.0.md new file mode 100644 index 0000000..b4baa00 --- /dev/null +++ b/contracts/phase9/DEFINITION_OF_DONE_v1.0.md @@ -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. diff --git a/contracts/phase9/OPEN_ISSUE_REGISTER_v1.0.csv b/contracts/phase9/OPEN_ISSUE_REGISTER_v1.0.csv new file mode 100644 index 0000000..acf4abe --- /dev/null +++ b/contracts/phase9/OPEN_ISSUE_REGISTER_v1.0.csv @@ -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. diff --git a/contracts/phase9/OPEN_QUESTIONS_v1.0.md b/contracts/phase9/OPEN_QUESTIONS_v1.0.md new file mode 100644 index 0000000..7ba87a4 --- /dev/null +++ b/contracts/phase9/OPEN_QUESTIONS_v1.0.md @@ -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? diff --git a/contracts/phase9/PACKAGE_MANIFEST_v1.0.json b/contracts/phase9/PACKAGE_MANIFEST_v1.0.json new file mode 100644 index 0000000..71e444d --- /dev/null +++ b/contracts/phase9/PACKAGE_MANIFEST_v1.0.json @@ -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" + } + ] +} diff --git a/contracts/phase9/PHASE_9_HANDOFF_v1.0.md b/contracts/phase9/PHASE_9_HANDOFF_v1.0.md new file mode 100644 index 0000000..f331b5b --- /dev/null +++ b/contracts/phase9/PHASE_9_HANDOFF_v1.0.md @@ -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. diff --git a/contracts/phase9/README_v1.0.md b/contracts/phase9/README_v1.0.md new file mode 100644 index 0000000..5bfb001 --- /dev/null +++ b/contracts/phase9/README_v1.0.md @@ -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. diff --git a/contracts/phase9/SOURCE_TRACEABILITY_v1.0.csv b/contracts/phase9/SOURCE_TRACEABILITY_v1.0.csv new file mode 100644 index 0000000..7e1ab87 --- /dev/null +++ b/contracts/phase9/SOURCE_TRACEABILITY_v1.0.csv @@ -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 diff --git a/contracts/phase9/annotated/ANNOTATION_INDEX_v1.0.md b/contracts/phase9/annotated/ANNOTATION_INDEX_v1.0.md new file mode 100644 index 0000000..eb0730d --- /dev/null +++ b/contracts/phase9/annotated/ANNOTATION_INDEX_v1.0.md @@ -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`. diff --git a/contracts/phase9/annotated/SCREEN_ANNOTATIONS_v1.0.csv b/contracts/phase9/annotated/SCREEN_ANNOTATIONS_v1.0.csv new file mode 100644 index 0000000..4c621cd --- /dev/null +++ b/contracts/phase9/annotated/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. diff --git a/contracts/phase9/annotated/demo-dialog-en-light_v1.0.png b/contracts/phase9/annotated/demo-dialog-en-light_v1.0.png new file mode 100644 index 0000000000000000000000000000000000000000..f0bf42f570c37e37b6b95f6347c026d18884eb32 GIT binary patch literal 51457 zcmYgXWk6J4ut!u-LP}a%x&)+CTDm)=8w8|Vq=luso23M#OS+pSm+p|Id)asWzxUzs zVLA8SIp@rob7tl@GxtWQD9K==k)R436d}o6<|AL0LfxkiU0HDtk|Na43_(Y)pd2~b9N%ncYHcN8(5nzH z6ECwPNqaC^`dBEgpR2h4;B)PgFf^E!@cH~YlZ#8?=*ULKm1Xur}Hx zRc)~mLkwJcdQ69kW=Th_Mu}bwf>)QF- zu2?QA5$_-@G0sSnMX=TQ&*I<3XVsm(yUwFU>|Y0|pKu>@FtJg9l`?#bq`G-nZ zUzH7H;QijS9>34dCbIZRwWgCLoY?x`QD4Vn|Jg%uXtbO$fMk39>!SnGh%|n%{elw9 z(%k=Q_Q+yg^(k%E#u)LBgULPqPCj<31(StoMv1VDSPHKfZ-0DcA~d-d@QjmxF^njb zHk2roh;GkD3&S*g$Pvv{eg~`BAVUHLdGfpHcogE(Y`CPcD3+f;2CnaT=mnJON{-=6 z15|UY6!97Cz9dw@VVd`61N|00JAK*1R966s*Gbl7s_VvPtivLCk;_gP2uxubo|5G6 zDU@syzF{#yNuDsn+P{ktqs5I;Q}k_t^7%7sk4UC&tKYdom$aRxBJ?P)BXzi0BrqD= zeV2S{jm$)=f_(2QM4raYbm$(m)w#b=SrP1R@dnZo7^eut`X{o;_cG~feU?ksp)J?2 zM2uJ}PS_IUXR3aBCEjN0@A=hxE(_=C zPrhEm?juddL@FWypL@v)2$&^&(~*@DTF^Vs({m+9sge*hxE`~7fv z|E%~C3eEB-^_n|>Rv4x@~L@mZP5OuyMj!W21mClE@LOO&4j5b8vo|f<< zHIpjS7JZ{t%`PLL)~BNu7o-+P7WlRh;OFH?ZErn_MIR+(`^pS`xz(rz+P@+toN<=^9CleIHy~UFPCZPxC6V+Ol zk$5%X=QX|2W?B>CUK-dE7&snhxS=M*p`K7A6zXIdjFEGqVg6t#$XktLm|P}5;wmOU zixvLMUTI&IK_?_rlSwx3O9Z;~qMu2j2=1%M8OmNvFU#=ojT-1A1v!X{{4A+g9XE&8 zlz7w1&sQgzDw)>knu2gCB?u|E@X4Dg4aBK_I&qd_hs|UTO3hvGY(Z;k0eRo6GBpR( z<%8nK$j`gt<1KXR@v;|vJ6bj8?aXSQzSD+=4}1^`)#U7@2_1-y52s3|3LSX6xlD3b z{4t@<+@tG;Uix!m?eq@C^Wyp6;rf^MvUo|3scqC~+?bC*c5OfV&D0F~cB!@P6 z1I$~FnGCF%O607m(;%D*g_RA-;@0j#-MHD9fyytxeJ6_N6@D?JY_6_AvCcslE$s-C zt{RhWNPHp-Bf#epaw1E4gT~XCXzworlueFaGosLeb4I&cI*^P|=*C&NOhr5qxdrBT z%MSm!u4?BgFeCFxZACn-)+afB;LO*<2VFU_=jjs30uu}UBP2DvYLHdj35hJC{VY9u z)obNwd(?4_)8HH?;Y6V(x}iF>IfC>oJ`AzfS3*?D&#Ze&=qD%^CuF5U7)V-6BaY)Ca6#co9;n2a(&!dPg>r#KpnE$;0D~*a$9ZC5=%9>^dhi z%g5eXs1P?lEjR7mO6y>0_~{?QiOw$=Oq9<#DwjPbn6qkLzUS3)fP&Q0lKkHq+^fcZ zrv+ropbN+&Nn^Rhk}QWr6YSXzilGY`9qyimjxO|1S7f$xuX_HQ;AEvWb>a5*NAGsi z?F)VyPR_bF-f-&mp@KbSatoQH2{O_|E0k#rF_wp^kgE$cbzOvugzsB9t+Myc@tO?8 zA>Wf+{mA6B@(K?j?LOaNgTtIc2FJ`^e56GC8xAPI49Mo@<}X6pF#SmxEu>N=vi^ogoy`FX;O#lV}B&*4!I)Eu(H&(Btbn0Dj*&xgcpw+!l9|LCYOe9qHgN@O7n z25VlBf6Q%+YWFHhb{iY}c}4)ZP%+gsB2u4b!I7e}@$4i#T)a(@-cr;wQ_zK$1!YIM zj1(Jun@d`j>#5ZEN@j?2_;^axg?1>(J}kx|ox5r#-yb4}Z*aN`_}xEyzv}8alJ+^o zCHx}ZA1lgMVQ6F$^#Y@0$Vh1}W2t{ZGKG-W^fKtG)yg^Ea`9f4_`_RRN$$QmtxfjI ze!sy0Rwa_tJ2|;BBtom0PNm)!Kv)!K5t$WqTXkY|_aYlaztc+rIF!}~ERS}IlkMt; zzso#!I_25}#l9jGFan^zFC%i$pOKX`S`nIAbacN2ZIt`tj6DBCHEV_IdJNs&^MWD5 zVyG3|*b#2LR>HK3|8I&VTa9v4>ZzMk@ZfF?v(%7SoA_vt`C5fOE1tT zAq{?USCS*dhBXFu3Nc~QxIC}=@x%_$F{t7T8Q__lMu&HAkBi;qkR%77tDH3CfO0g! z8XVjrTBg>4jlfw!l8evF%lk+>zB0p%$c^_%W#mKJx%91BMATALr_$DXFj!IJYzPB{ zf$>(Rl)vlPONc$s$Hf#(kX6XJc8GJ1-@O}N)ZfDVUkWQb2Qw$*!O3{R)zfoN{&^c? zFTi%p;YFPRN(U@-1}_Q|Gy2@O?87|jrbQ0N#BPfJ`D?KXNoo!bj&4$b28mYL*qDWb zbKEI$f}RUo*+IG?)Z;sz5EgD= zV5sr{P^d6TiszYmr3m#X1`&s=Vu_8?6AWIV1xNndn7^un7>QY?o)nmHlL(#bgoBbl z%*_7~v$Y+{FgZpq^OqnY!U;4{7F=xLW}^EpqXEjWFo?1mf5#P_gKn=o9OE1dkcQ)s ztQJb9s)+EI|0|Q3O-9yi&KVJpEb8Z+AIvaDiI{nfcIMjT9AvA_C$O!;Eksw?lLQxE z&DP;&tQk-kzDTDEr6m}^`8Uv)0_3+=Pg)|vS3BBSY0_yn_Tn!{?=Y@9BYl+7r<* zPxIbE9SZ4dhd2`7R${c}`Fh1+`lR9qlT%Fix@q!xGH+=a`*6m3)5KDOE)xdq7Z1XA zc!E$U0YOz3H?_*wIN{dFQB#L*Xu_DRdEq0xL;D#Y?&-|`j(a!_ItfO@vGe(^=;sNg zi9gr6wcoaOolg3Q$FKEkexZ1<;{5`-iqF{D2M z0g<)Ey_c(Uhlko69=g>=Y4Fdo;6upvZ-p`iswBq3G_+6?&Yeh8C)xMwH7pTQzQR<- z?>9*gqH0~fo4IY=&eU?RFpB&P-}a$@&0^rm)?v)JYi*t=?*8NTxgps|(K|YidlSY7 zWO0D&T+L1Kos9bgH6=-NBcqSkFFvz0YjavehGQ|B0;6t|l7{yd`^E(#()33XnG4e* zG192{xw&{adRC`n_36!kK2I9EweD{zq~)4@N3inGtOna2wHHk2ZhmxQgzw@*;}c|# za1!?B{!Ml{^hTlRwS7(28149Zml-I^$cp~k0ol9j zXAkF`H#(Dd9{s~fK95u!hE*ypOKIUDkJXKC!f}5ftMApTZevrklPK+(UI~nk%VDvz zG4)WSsH{)PGI?R5FqP6rY3`CA_26>!et89GQ{bFxrco?D(lHaK8_HLZSpw%D%gNOb& zJ%+7~fJZJSZ_(5CdLu{e%FH`bt#NNc(5jM=7Yh%cz)Wwf@w|M%6Qw?0aE0u=OMeF8 zh8nf4vHm%X50yGnSyh7+uhcvueD}?7Vj!UTVSFBrA9qMv|6x~D@1UxK4`(s$HHj8S z=G5}=@Ox%Hr`FgHW=De5;1jUNVg_Kop{@kB;k^`a_wI$B*^eb=7#LCJ_9mG|ph z7&QBLjlOQ$)M_H46LjrXKPx+ZQA`;otk0+J3@AV^aD9bjy0VOyEUqG&?tDy}28dsu z(=;Z)gE^HZoOyU|_XiN01+y5$<@DxCtMaP5Nr#txKN}OsZx(t_3mQIo_{25;Kro57 z!1PS*<9(O6U7(iwO((5-NtyFC5RDcOaY8Aqm8+1x#6t-AV&%=?ALE;;?_VJ?au z!Xh9q?9?ZKT3mz+9L(PV_~>CRByTT{qxn_??rgK@inT;6#y83F@$5g_i%hn|G_3T^ zs5hJE%#N9ARG&%qq8M7)eq+xQxBiXhml<^K$S}x%!8{+`{d=433m|>;>wfI1Up$si z%uqzep|u&4Cn=4(6m?8kJA*{Ok#C}$WXWTE#9*IRX$=!S^Hf*bPBVf>`I}0>!5(=s zs#WsZ#~K5z*kSYL~_+$Uo4d( zGC{-)aU)BkSwClA&`okYqYT@)S-hkYARTH%)<~UTbA~&ejRP5n)ID zk^KR8%k;2B&WC3iNm7X{kgqd#27RZO@Wg_~1phvL0k{bacl)qehL%%FTC&QWzrdU+i4ad!_FM72Jva2S zFUF0%wXH$l zFE_=ZpOrA=?!vCAG(eu=I>b1{q^C`nJ<&SU)Z`LQjl0mdydOAAez@?QjDs6(-rwLmj_u4 z$)`!^mP@iY^?ht=LUjJtj^wsEToo%NC{=q*3Z^RCUtdyYz{%$=_}L84Xs35?PjIi< zjje)D=as-62^=~T8NR9hmKS+CeBYw!+j7VY31K7K(DT#E?awPL?^r`56BCO^2hFb} zN7uD1oy^QLCi==zSX}3#>tX9=g(4x#DMa;tul?B3qvCYaUNI%&;Y>xe4oN1`Ss+#s zpWd5??=O&zAze~_uxs;sSc)fZuRN0iP}^={zfB>gO|iKBFni@@xRkHWcj{Kz7?Kc{ zD``q2s`LPcqwdM2!r}}OUX;7z;J4Ir3hHd4B=VB=LYJaUyd&;ac9N10RrF_GvsDeM zaSgSO6@Ir3XdcN;aPHo@>C_2s#Miw6vgWL|M{9fA(D?8-P}%p?g04aJuXDnmmQuL+ zBJ9w>yI}28E!(C8oGHM_so$uD?@Pp+{^>sL2nfmYidB%@pxAz9qDI|9k=pTSeLQli zK;3dD^w%%{JA)P9d|f@cnV>GVszSW@pMiM*Yb_?E3BT%{%zSwHK2);kCgD#OaVpZ}OOjkf~2UsnCe4`cGQVHdDa&|^vU7JW9M zTa(-KR~|m9`>hIT--mV4P#ZqbrJoB50G zeOba?1NxbN^)zTr@nqlbM>R5#5dLXGl-8CQ_QP@*pVk#|*_J;_FAe(|BvuyZsB<;j zD{Qq0DoOFjCV_PMLaZO;Vm2plIL-Y0O9Z5?cAK_i_~z(*jg|d|MM9W(9Wk(P)`D{{ zksDGotG4eu^|U4giY8Z#dNJqtU6>=n)4fT_)BbAAC@QmA&2S}QG7-OffJE4>tG@m@ zs^Or--DV@M9Tg(sAbc#f!NDny_h|y9pWfef^EyNjQ7(0rnLw1GnV@q0hte(7yKQKN zHDdn;u{!eh_V_uH81bLlUfi1AS_1(ZHk2T>pi78$9>y!g7!-D zB!aHvYh!*wsuuuyTB3B7)1nBs-Vi+L8u@jL7GqhY^Zp8Xn{9Qkb^pfp>DUJRCq6;{ z-2VPTD^2vmLN*mtpZXmp~Z$ z6E0<}?CZG)UV@Zcn>An9yu(3Y%It79Ebt}am}rBI|Gi+ z$)6993;G=_9LVdfTo-uZ{WO?yMJ1&>^7S-2$xWEJ$Zz{sPZ1aqGlqrvuQUy?X3SM@ z7^>Pu4HMj0tjcgiFs`$ih70|ZLiZV0O8?_ySWri{t5=v=2|FgKsC?e!y&%S~m%T|s zdSRZ2h6V~xWnoh~xNsAo$69{EUey~CE(sRgleLz|rJ<~Pu(pWr=3{J4=e`)qF!P^n zIFr1PW&u_~$Ey+FO!o!qihp^BZ#-~}cif8a-@aRD$j?@Gi^%KRAS<`ktoFT}m8u*Q z%V|RTCc-Mw42v-u+$HkY=O$mC^tx+98%Z9PGptVq9dl01Vws$XN{_5SFM5kF?&Z4sPu55@sMYE&~8=0_PZf*>zT*y{h?_B?;trm!1eczEJGveR@W^IEeBb+{3$2^9$a=$QN1J~Zp3;s++? z-PEBStiv^V^}_W%YDk`y#vVz%`4`0xBW**dnH_E^Hpyi%B-30hq>J0O(G%hrQ-*XS zIvC1ju|VedwWb%iXreh4RmZ3b9NPb_;!h>{nUrL&w2&${@}fS8w7)FtU9F_AtlO`T zqjI8D9t)*N)YN$*&2#K`+X;Jo)<#qFVb8>Xu6kiO;a(l^rh!PaPFE~R1QcVyc6 z#0&y#kWpEdx8_#?j4`9b!|yuaMC1tOzkaGcIMphPjCORtF@Zg^X7?{2>LtX*A$7^{ zbB@cfcC4UZzmQ{jE;Ueu_EN}|M);(Ra~*^9DLh=3a?L2o-GA`E1q#_5O0+$*Hz%4@R zP$W7Y`A?YY!H{3Oq>u)en&+sz*gB-FA2Gp7~%i|{3hfN$!w2v>T--%+tID0LJ4-< z3gd{Kv&fU?IVi(TuQXx8nd&p7K&Qy;xUc(4i<<<6gXW??%-L)hiCPk@jMKsa@zqs2 z%Xt@T6wAtuB+@a2Q>7W`9xFzK2o=TmQg>vBJJ~a+WnD-~4xh@LN5kvb5Hz!d7>i1# z5p%OR1!!U+AQb_Efb&t|W@9N_zL3@`fAoRlwZQNIOoV|aqZ3(IhskozF2xBSUvYy=(qvB9Q|Tx zJKb(pev+jJxv5kw+)vmW%^?o{XX?Klvx7@K#$i|AT>JNadEzF-XO-8h2*X{k3*&+x zOi`a9p+#udg^95x!Ny3wRq%1DJG*7&j%gVEU8Rsh*{xgRc44n-d&qe_7MBYj93u8h zJ_EbYb~E8_QzU)Nw%aPr0h0L9g4a&anoh-w&{keHHlur0V>HE2fZvKXr(A>mm?N)M zd|vA)NkT!lCY=0cVjZ$SUOkug(}9?#JoBN1K;IiV<1r{c|1B1X0ge^-k#>((!gV9o z;b(&K&`G17zVZ`|cc}`im_1c-V#9>8=%83^j%{>H2PSBn9P7SnIo@kVl^!VLa%>?X2LX8V^ z^lZ=Dmbg&-ZI{bBA`z>#a6xLi^1A;GK)~3=r`;^O0b_|e*(U-9--73gYRVOc{FKMCO&Ni zul=|uc;fsZfW zkV|()Mfg*ct1x7a2!5=BU2I{sGy60XTDHPWP1}8!%d#B}II4XHv>IW;dJXRSe@1c_ znr>}1+uE4D-jGes^guqFEuuI)yllhRBv&Tm{dV7rgBp{y(y=!P51UX^n_(kgR4cHh zg^bQSt%>^Yx_lX2riN&`$Q`CDw!%bx@87R$hJKvssrOwYCqubDQ2Rq(mIC&eZ#YVR z%zLtxvrRWkDh8KyDn8ge4hE6f$;v4$HarY&S+Ps3hIYR3PDo8OwK171m(S?G^3&tB z`?FAY zb$o{mYM2G~(SFC1TT&CZyYq2YS-fKZ!24qKxasuI2B%;|iAdg%$%g#_@8!)6F%coq1OmH$=P!Hkg*-0hbW(2^L>1E-dzH z5fl^@@YFtk_vnXZMkDc9ffRTm6`l_|HW^uht7t|mup6OvdXo79h;0Yqh*pBjvKcr(LLtSqyqi5e=iupOS* zueq8-5xZsCt8GUC7gdO4!!RxON6q#yj>es%21Lsjsgnbn17fq1F@DeE%=_N%S;)wr zSP==j&`>FGG1TvL`y`k?rD{c2AfSKVo40zEg!}F$70dY$Pqeqcdhxf8k8UW;qvpe`p(_3TbG|0kwf0Er}~($m>B0=c3zXt_(X=}NLNsmJkJ%YF5AC5c_dUkA_a zKdK0y%gd1a-UqClm4MshKQ(pCyvGK0`;EzphZ`erk-p_F(xdh;LpNLe_R#%gum+w) z=O1sR3!;Xg0lQaA1pdwtA{zW=0}hXkbU<4*Q~Tf)s6SKr^si>;md-n`qAssQa13@? z^&TFK%Rf$oT2@e%l~P4I2StafgCR4ZNR9Nntsje4Y(|LveU&Kd1LEnI@`y1wSb+|9 z*TWZmsh-*r8Kr#8ZQbV0r!o;$&U5@oBGWzOs_lcBo*U=?(Nw0ypGJLVS~NgEr!E-K zk-uj>d{>tRCx!~gsW}LpRxgjIXAExe20!p+!TGV&`u8G)QKw(P< zjv9SA1Ab76zAT6%^TEo_b>9A0%Q$4zKv%(8_WVtQE+yS5>T$4(1#fXtMn6G-n>PrQ zb+(gnuZ(^HM`U?Pr`?Ox`EisMQf4JTZ|^WS+2{=aUiB3l=c;4v*ATF(3Wj3()jL?X z%QeqSr~9WKD|Br~HQ`GAR=o@YOlI#EK+^@jUXIog20<@{!;}njK{0i$MAhn zjZs2>BG!aLsLKz3h<{oph=v*tqlSg%G=CMANWWqmP4BF5t3#<8k7=Hd&5Um`AJd{f zKmVF!X&L$>wA^UPb^pD`~p? z%02y+NioF1#e7Qjn&udf_b|+3{4cPuo*OoxZsDU$&i*R0H9~Fhlf=MNzJHkowc5+v z??qwlF|B^PJxM)DgzvD^@b|QS+Y!L~h5200yMd6X)L#;zTT>H=l$f5p>apMJVcSUo zJlCqzD^hl3+jj6Ap}Qg%@jIj9=`dMI4{NB#eRV52TkO>%va+OEw)R;w&^5*J?UnZo zo;3XQXqH14Q#372R4LUDh&4`ZOx1<~oey}-^B^Dl@;V|E<(`W!+IkHfkx=00BF6+8 z*z%6ixJV@;C4)A!$w^Hp&uId#0NDRB0v6-(r^#!4@Y?xNBkYDu;2`Q_kMAX&;}U*O zY^nEBtKBkpl>e6WW1*F-jN;SZ!69_0JZU2=N5HW(D;hHEED>S7*I@=uTsIs_$k6#U zvDnp_T&dk|?qK2k<%m-=NyP7|WjQcMq_^J{ljon(3*7{GRY@wdw0N6_dC)2Y`P8SS zKdS1@AJP*uy)UW)GIlZNS?(dDvyyDukIm*;-Xs?n0bp<6>*;8~;gw~3Yo7}>*hSmE zo$57y+76X)9y3HZt_Ye~)Q*nm!i$&0L^s;2axV-q$sr!`eul`$0W?{j`#YT(8BOj~mHU4J* zMFTeY*JFoD2x;v1)gSm}kB)3RR*J+$-b@4$PpKkGexW1tux(MuX>n*v3PpU+eQ&xFwn`?nVLG1`S(j+vdAmDS-b42I z_?ODpK93>JE`$gx^qR#Byz9B?Ry$G>7+)ek{pm17*VV?#@%^2&YPh@;6KH&Gh>qc3 zez;AY5A$}PB?`5$F>(L9Jw6y%o&s{v2YjbcYcg8(f}rQwp~F>);d0|_Y965O-~j;X z0G469IXelX=T6j}8?!lbRDU=Zk-5OO`EYIaFQo~@!BD^Z;a_YXw{ClV<3NaI|@jQ4WmTKRF zM$LB-RzX{CP8SPG*k{9>ec$NYl|%7X46__pulC3RTt=BN6e2$Mya&P$QeT9ijxH_g z?1+#FbhgOJjW_H53~4TFPTL)`7UAzMF3n#XC>3=ZVO}fU3!Kn6Ceu*1k=)j*)9fNe ziwdt=KZ*Bg@m9wKHj&?{G$^Q}fAmoCCkeB*usa(p)(0i}WPbjWlYIrt>0fjtflu1i z&)?&|F4wqZNK({K&EUi+AX&mC%sCyB;w+plvTGP0C-=HIuph4F+GEvkKkH;S@>EX{ zl8#zl)B%e|M=P(VXU)ET>Gh83kiIM}BaNV=YL@VK!|0Y0hp{i8gJrP-+~!2`+ybz} zt~r^Szf!S`%crE$)9#$3cg~*l0^WI;ZsEQ{LVC8Z|Icvv)2W`wPw&_qEIByneFUqQ z+nQKD*)4isUG{wV31~gK>kMFr(|N&M4-@z#!Ym;-BGp`f%tU-YuJ(x;cgEVOuiXeu zuufE0&FZI~AM<+UAkq$VMq|7PA-4sMpSR3m>{SbbrK>_TZ_#Fb=r1C+jE{PmYh(-Q z3CjCD`}%h{7!D<_Nes_a5pIk~YyY^->tJgTPF zD!1ql;F~SU_NdPaa&xz@N2{xvaGElkZhIG+UPRkrb@-BHu1Q0DaPbnhG*) zc0@?7;`eCXjZi}QQarGuBy)@>`c^+(HSne>beOG(;z|Th-|IBDCTmA;PPjI~k3i)d z6ONp~+Y!AI_-`S}h&N!-$~|@A^1mBfpC-!*pO*66W}InIN{fH|2%X4myi7R4dX1?q zT7L*zD=96ZC{iOPdZ%~X4degD#80c~C--NB@@hklyIhm)amm-#yPUV(e%Y@u)~(2Y z2?xhvp~Kj$D_Zc)cBAUmi@Qh7*h6prchNJ|8Wk*Kkg(fhVPCneTItV2jL}O0K#cM^ zxB>2;`QhQNe0_pnHnKgKgl4RIwXKBX`ADsDPNy1E67AR0hq+OkUu}rfw8MDScg+TQ zPfr31x->}7kdReg^ZOh~zqa2Qj?VP`<-HYfIPY;*d62bsAPztQ$&Y56udagf^`8U_ zozs;aNwWBeDG*8kd}XGszvYD~D#($4v}|E|9wH@)Ng=B47Ybl|LVpK`bl%7Pwtak3 zz`PumaNUKg*}3X&1?5`J*xIG6>xcj?R~@Wh?tM zJZu}S8wr|Mlqt+~6OZzA3CwRJ15-Xd#AIs0R=DD~e|P=Zo9QmhTM*pe|FT^8X*{W@ zUpdDEwxND?`><@xOj-{!u5wAxS_xA~Zx*9L_~{x7`hJ6inrvByN=Z6{iqg^w=n&UD zLULEOIgWqN{LqjD-j|>&JXGJ-nO`M4v|_n}EI99u)>Ry#uRY2mk-fVPkNp^HA4^dS z&)fWNsXLCuZ8S{uux&~g3btKboaDu$&VDx&(E`S;`PIDFBJm%cb zmUi!5bgt4@skSeTk!@8wHlO!lGrH+d%yQ%mJ#b-wASH zt~eK1#6%KnRRfV2Q4yGbZq0~jk|r4rSUAsG#joP#9lq%No)M5)zT>xH$&NKoBdAU2 z3;X6qLS_O)TNCisa>uUf1a6c#b1Rym2JQf$E?p%nWRR6Snvw0(qQanaHDMnelOe8m zdbItrQ)wKAk^6WEw%tJkGT>tuwH)m&zsb0cTOWB!09bT)Qy~=K7>0Gsz2EBi@?)e1 zc-{SEvY6m*t);EQDH_jbE-js?T=}ueYQUY9)MoVVc5wvRQS*UcP*$?epB#Slo1?k9 zzi_%RXd*7F{NwN)HxZC1chu*%7n^vrt#^o$CImTFUY@xTK0}h@I(f@h{VKBFrE>5S zfT)w0np*kzOV^m!FO*T$l~u8-$(I5yk3*On0dp=1q;8y}@7tHPjU zCNl_~*-|418PsK=Jzj1OkpSz9dj}uHa)8jfMQlg*!V07eP+$qv%Zl}rTEzYVfS&z@ z1w6f)SPYsEfB?k#ECK@7C{>$sJ-u1EXv;RDiYA&ZQEqgXsw^jnK3WlJ+^e=Ay?!SE z_*`pKdyT1?`T*EC-22;PlR^Eij|LEdbG4R?K0QE-NXu*vc(e$Nva5PfE{`W$72#fI2Efg>?ot+l4f^}yPe)IQL=UyP z+6<6AYH1Y!&>w-XaGoiQ5=W8fPU0q}vH`|Va>{w?;He>N-PF;M4Zy^b){Avm3vY#f zd9R2yb=+x=XmJer{YnRoRnbnZ1>PY(B0j64KryerjtzL{_1sQk+VHgaPI^E|0X z2sawb;!gTlCD~)Xlbrb(W9LQ2G2($oIhfrj=I(kLcuf##`yito_hX7B+TzGcZOhAUvq*`F2;SXa+ROe_Z zE<}YC0MX=21(RvHsn$QS{=k*k0KN|fw#$F-Dpn%>_*Z>EvS382kre|PD#ggy83Qyx zE6_;*iRuw(h!JCo_2Nch17$-b3ueGQ0<)GO{rEHqG*otxvHxQ_u@C9r^MBXDw*Q!} zB?ttr|GkW3I{WkzXffbD+b?+cACVS7^!VSjEJ##v;F%aPn%GZU3~cfLn2JLxB>3@v zoyAdrQb%AdQQ&{qN=V`}|Aes5_sN;yzeh-hp=|$(gknel-T(WIAHi2PdQrm?1!j0Q zVH{RmWR>_Ql(R5R*%&1tT%Khp8d5{kK0R#q0BglVyWDD z<#5ShoZUaSYRTnvGx`B)CX!=i;iy**p7&VMJBW}nwjnfn(Vlg8)5%IQM*^3)nJ|DP zEn}rPK^xr`6(WNCv%}VET<7u8Ean@c{lMBR+tTPy@x)was#nA0J)N*eMgK4GoR0KX z`=iKayuS`Cq8GW|WVjudH_o?jUc8{B&bP$0)jaQdU<$w#rXd zYXKX|xXFHcxY5X3jq(8*KQ@~_9Nr~3RE$QH7JIxbQ`p@((Lh;KiO74}rg*?rl`cM3 z6r`Us(TDUes$MriD=@Jk;UaxTaXy3y}XpTD%ZZ?{Klvk>H_TFT+QFF}R zR2n&}z^O*XIcU*z2hu`By-Ml*w!PwFK;cCZgoanR~ z1_8R5aBmDmUx{}gBKlyW_IR<}A63a9GFsV`sMtBnwjf}i4f|B|47Ej}!+&ooY{H1X zs8C=*4}eaZf5Apj`Q@9O4*2@wq<_|%%%-=GJk#Byh01#b(T5u9tPkr$}QfSHZdE*||g+}?201tAU)4Pn6$9UsK4Y){w6-zwPzLO!3dVwQ4!|J8zyg*W2 zrCOKU-|HTYxEHV@fa@i(B%W) zZ{(>HU_4Z*w_3W1-o=!6+FkQdIP7bFU8qLq{aB`LwjEd{c`5MT7gmGLjw}KA17>eN ztiSUd6CHWqAr+g=7we0>CaMNV!_^HD4BV_{JG<~_)oZ7Bk9w>4U`-d}T7Rs0s(L@f z!AK*8qs9^ZSo9ji=0I|FxS-HZSS=f7al-1|BCy+x4lcNyz+aBAKHP`dX%=o<|*8;Vj#toWj)-M8%*FwUlr@4y9 z4IND16EBpLJC>W;Y3TkCI$o93PO;;9%^V z{lx~APp6A^9#&z_65dOeh%eUttu%W_vlWjL)$VltK)6>XI-zUhU?cMQFit!@T3}VB zh;aQIzt*3YM&!)JzVfT2wnY8{rM_y#@At)|uD;#HeSP}?=3lpCXf(hQ{TrB>DGOD; zunhaLpnsVn-dYPcGktMk)rz~0v9Z&wM;02}VcU*=@T%nH$t-lZ`*IFm5>U19G}06V zhTSL5UhZUE*E<0UeH1zm6VYoisg`|Tpw6XTkJvZ#<#m<+5z*kyf`G}!d3^n zB$`4pm#}X5{@_3c(HFsq0cdEy=#AU%9Cyhh)x4u3;^ua-nt zHYejY_RI&6F`I7ZK%;jba9c_;K&QdPShZ6JNMo0b>9gXZmHa%mDy{ao2Co^HyH{lL z4t0ZK_+rz z*f@tQ;xyLK69*G1EG`116Ed+^z2cubu@_CTbd*4$96b@$!rb`Cdm{2=hF~+eXIz(+ zl~u^D`H~f#bQk_)$Z2sNOwW!d@9k~+NFE&XB3DiLj+TRQXJL_)2GxD%>07COU9HZ0 z0q<+?YNfH4zE4(FLR1|5)b~Aw6c4jty`XS|cYlpSend%j3t2UM;M!PnIfQ`Y6XS>B zayU~@cquzBeNda8=FXC%xe6ig{`~dr5fSWA{ zoCiM9fr<9Y4D?>X;$+-y)T;0M4F~XW6BHGHhVKvm4J+=)g+)3tmK~rf8y*0TWQ~nA zqEsnb4p#!6g*xGG4-rd}M>{l_oX_BJ|MHCMo6~$@o|ERu*{(4CPYg@~1&Sd!|Gs|v zrgA5XhzF$Fqokrn7dVp#t5vUYAmxTT133uq(@RbG(kec57_eR%3~#{#ih3U_{;I8J z%hO9<@@%f`WIVk@%|%r<686J+9GK`~@@e@>Ivi{1xZ=S?k5u$;ABx=YjH?=~*rC5H zV4ofF1m9#k=vDVGPzgtr8nL>#|9-H8#01VeHQ`v6*${XBB(qL8)V@m^>zW&0oJtOF zgAOlmAMW3opKanLXiww-Ic7R)GnyVZ!I<8Ddfimw@@n9iYF&Qye-tWpJqne)+_w1I zzNC2~?A>Lt6ZR}U3Q~~YcpRYg*iTA<261kq2BF!3ER3x7Q**W^+U-GEaX~Pek z>>S3;Jo|3j9zAX|%OX^1mG{2eJ#=3^ICbay=Wza(d#OzgRIBp<>-O@w(Z# z$ej%Dwy*iF@1<_`8i!wS$psY*UX8pAsRI-?l3Yn$CSU^cD=lK`uo5-uvd=V^og6OV z;bDd9s&4kL#zX$$8U!eZ%K#4!)?T&E;5GE$LQB za&k&p=gWL2pjd6HjS}{i)nBIpP!2p|GS|cDzumq<+#>8u9*@tp97QGz{APF-cUabC z`8*GS8p`9@#fOulsn+jDO+YcZF#_4wLBNaTv3&hQnt|hc4$pVkgK#Scn{>v6FsU{m zS&=~`e{9dz1M@27VL<#fEN(k`zB^L|oh zu{9_mAp|isC8ZGUyMic$u`XRa!0UQX2P4?j-bC1gdl$AELt7*NV6d+U?3^`#I-dD$ zBTUp`HJ7001N(RJqO@8bTl(AIHhMBuDnjEirZ1UcU(`=Aly+P!J+BX=)%lkL0ehAe zCezW_ScBn>mzSO=jXzOQ5NVP*yfYh$!i+v6z|91NcEVmb-+Ev}Jyz9QxbbLg{abrM z?sEhNZR@`sH%ZCy3zlBwOxR8RYB+=tVA^#euyf+mv#G`~yhv@#EUE-FB*mYBOpqnI zoB5+@Q4ZI3`xx|1BDK39s-h2A29B=~VNE}vM`fDz-52vtZ_zC5ebr`L7aSc(<+&^X z!`#Fp%BF<>pS5kG;T7TVx)vn`e0~5i;(1QaRoRV;2kz(;c@3kAHLc#N%_ ztilP$BjHIWfNg-}?Zi7?6=fEtriSK}CKho?WRcDV`bqrrU%uCzw^8;rvBrFWH;esM znjGz$dR!e%QDl-FLPzDC zwpT`Njvi6c^_@p^OeIX`qPWOLon`8PtDPF}&(D|96-q<;R`;^>ceP))AKBOTD+)zr zSr@w50VS4sD8|a^AfK$O%nMrWBfY^#+bOWBX7+0OAJX0es;X#R8{XI=sH8}XfHcw_ zQqmyZD1t~ycN*X(6)EWu>5y(vQlz^<8tLx%-;L+q?|k=s=iWQUKZaww_Gaz1*IIL~ zIiL4=pZA$FLj%+-ow>SwONV1k00*nLen+w^_a{BEpg6o8{oTDJV-DB<9rneOw7op< zA)@iMA=oXO5E>j&iHr8q4%T~}}C zAJEBF3uAOus7AkeGjIw4Y8#Y}Zqm z-B1ozOo-d{h-EkIS)JYrx1^$Y?79R9cz(z!!I}L<{AK+3(0rIfQ+CX3;`x}?XVpi1 zo71T!d=`7M8C(6%2cNq{@!R6X8b6tdUvVlImH2ebM;e!G;hp*$&4ynbSmO_Gp1pGD zk~6z(0S%FD@gl6mXv&1(iz9{Ty3&oLue%MOWR=M&@N-#|OlPwMH`Y^8a1aJ7=2 z?l<4R$8;}!xXHLsBPyDjDs^&?pimHD^22)~i?I#)vgMOLyNA7Bs0~swQ86tgO{h5k zVJz?A5lB{+KCZhrF~1VBO3|X)qY$TuXYyS=ZlFT7{jQWnQKn1wxXVL!eqKSAG6|zw z0s?tT&2ZaXHz_3hVnekHt`y;Cjh-@5ulh`cK!8>zVQD5~yUHcZAx5rDtso^+lE;2F z^9n!gYgxKwp!EIx=m~#|wqjAZ%$fiq4S>`in)m<}r;I%i)Qo?Wh*ef2rK%eB=@WGX zy~_RcvKvD%TM!X0;B>)!&AGmDDs4nByMeA-M-5RE&;j1!)q6P$5@H+~PW-NTNe}R) zFm~um!_H>-;^JM3GPV~7&4(*FqW5BmhjYJ}y1?|{UEm3!lnd7Wi=$IEnf|q*N+%ze zw6-H{(G`YofMUr6-HV>L9J&|;hk2Wz6LWL&aPG8=sA6tFq{w%}uvDcbw5 zVcxU@9^v!&HT!pNa&gO6O)96WWN^jf&iT&A4VeiQX0`(5J6-pYj5YHSf^nxj$-pkhY%O z)8L@uX5Tz6ax=dx@jg^KNl{QA#W=_qz zG@WUhYV{i#vL#2VTMDV1bSd{#ywSdvT0ZCG9tvm_~lib8}qtG z%Sex;fmM^x?~Sbl7@iE(y}!h1*zIP-n-;T0tX^r(*(@RBS7!Vi&Lm(nr{ytbdpR_4DO+)_&t|K63Qv!54W0Sz z_?7DG^M^QQsypZ|I2*i_l@fRgOzrr`L3gZ#A?hR<&Yf=dFL|{uFiCyITf!=}7&;Eu zdiwBJi!Xrc3++sT(fPj_M?;5yjT7OU_IucY(UOcPejlQdRjM)(>pycB`(j>DOGwe0 z=-5ytb*?Y8x@p}8w5+yi*EKk0RK)19!Au-1xv*&Hc?y^Cvc~G9+B8nYBk$6C2}z8d zBL|b_ukir5n`sX?166XDu@0EjPDI_|hW-eNh~HY#iuqtnwWk*7zSx^q2m?i$V_rNz zcI9a738|ohl-#_YpUa)h(;>9ZDSUE9a+c1uzVrjYjuY=54{YXq42~?bU!#?=4G9l4 zy<>y9TO5x6qH$D11tO^e^%F{;!;Bg}M`Hf15h5+;f)rpF$)w-|21qppAXJ&AyAHo&*h5@WOqO$^lN?$+Y@ zD<;e$x}VX~(tT(3iwqZOD*<2U*W(BHg?a4$GLpl#+ahC8VX?o4hP5K&%k4(eW3s=* z?f}Q(NOr}|rl*hIRb|6Q_nVDt$IUhvx-9nvc3ropBCL7pN_Og#sva{_rY46uek-$S zITL@n0HeZ-Gm(-L`^m<#mSWCy^)W?#%QN2=;9sI=*zl9R@`p4uZ+GpUr1BM;f5+Ts zbldQ|?UmtTU6ZAwvuj1$G`~U0@62QKbfC6!`m$NyVAI*3%&_Ra2*+;@g(bd7Kh2`q zr?TcE;*P0yCUea=)LUe7Cev#fw|r5 zEu~}-?b#e3w|ynr6|4FX%X4~lXR*5nM}c^Jeq-x9Bs+Y>tI324BQjRTTE+`X>Q$V4v*j594)61vt)C8>k?pr4^NFN!k~1$=?VDD0;y3gwDGEuzxq>cChwavY zlUjDZ>x-1uRILW+XWj>4tZXb%H3qIOK7|0TAw=i4TU=a|;j|ob?H*|fx^L39Sa(1%%bPOogXbd5_5K4A~lU@rd@l==Apst?p~#; zeQTB5$w8w={zBsKty?WTLbuj>GbSTj97`GTkEHK$I(6#%g<#&zxS|xCc^^@-C zo)2+%?kheN$a^{b`IN=_y3D{D?Y`tg4i>G`rb`OyO>z~G33n@ziT2^>tCsMyTSjxc znW7opKKdF7}(s6=a+kQBov3x?-Q?4w>6fd zqVVZ$Pd6;Bto=w=oputx_>86EyVZ^5PpOJDC98Z!&rNnQN8^#t2<})^B}Q{bVE(#x z(VfLn`KH??L^UZ|hVX-B0SD`jt{Ybl4f;4xmG+=CAsQ$U?V-cdvB+-gqKO^xin9>1 z9laRpM{S?UMY~#b8*+HO2qSxsyoF2jPxwg{rdv@t7n;*sW{}v}ha8I+>m4uDp?*C@ zh!CBpMas@IEMEV=U#|(L{olC~RNjPw;tB`K>%xffZ-OTe@opEDI-*fVqoF^3cT$vMS z({YOz^u)u*GMbxO(#tHu?=Q72ntRZp`y&`GNzw08gI2~&lxM4~T!z}Nia=38UT>FQ zcne#0euMM|Vl%v7Eu`9>hzn^$DrWmn0KebAe zr5+f-AzD~^EK&0zP^NwZF5U~FBGPzb8JF%G>|NGe*248bHeNvt(yegq{8r26Z+SV& z?al3{mS^t?wf$@jP5+w1gFlx72+`TU|0W6F{oh84;tB&5x8g8}dE}VXZ+GnpomM_O zIwe%4hg|6isO3j?33u0eP@?9K-SV5G;z5i~(Bf>ax>ZP};A zYZV?x)sgxt2Y4^7+4qm3PB z&0ozN;fC#cZdS@?XN*!nigK>Ga+D5LZoej85g_Bi5TFRdxOT z)eP#S_o%8hvp?emJa^=Dt-lJ5`Rx=A_JKZy z@gNEXHDs2su_ixO(3O>xW$K<<&6$0CbG5=@YgKK`r|_i`$V%xGp9P!UInx`fpa??c zU>Q|r@X6Jt&t!BmQ+7Nf`MaCD1m{FYKb{H@_GO+NEG_qawP@mOLuK^sPZtx`%8M+z z($dU6bJ^B{=mS@Jw%z@)fKF`CvQA&BHXpGb9CFy#q(6o2&I>_#PK>>e_Y8d7T% zkVcx}C-y&*<^r8iGx3d%_+LLf)_js(2&jLw zlf>Nk3^hb8Ds_LQP4AvzH>p3W|Gbau_&C#&4H4$H-~2Q5pypah32RpvFI)!=ALXHe zZ}ng}5-IX!>XpFF^gpvS_$ID*LW(1p?QL0PiIKcw{2Gq7XH)#>5QezU>sMTo(B(N#nd=HGW3=2!625;UaHYpNmkf{?q%r3g zJ-m+o;Q;?)=YZt}X<4b3P}-Q~R%=T5?gGBC>lQ{jKdrcH$3Xu$enNdHMxxh;=b*9_ zzH{CC7~Wn=ppcOdBfLAM;|TXG*3dj5BGd<=Vn=JD^4ZK{4>zCcKtJHnMuaNsZvr2_tkBANb7}Nex%jL|D^xV0N#_YBie2hSY-}}E_ z6U?uWrjOxm;g{VF_pRoQ;yoy&Y z+;*vfPf^pB;rW66|AzxhVz%U`V7pfez_-do0XJ_~MYG6iZbUPzu{PY-^rVdk$MgHU1BZ2u`76XSzArGzhNG<83P z*P_vdsp@(q^{Lf=BVcCl6t^j>t(SCtzlG0(U?Ds^>mwjq^cR2AnZ`{liaLi`Im4_t zjhE*8fkg-ws$R@FwRYA`Q3EX>jK|n;COMLF9RWdd4)))A=R{18?7d7~c&goSVx!`G zr>~>hxBJ7k(LzO(UXYfa{EEPhfcyC9bY;T=*8`kze5+9dLG~^+>#o#O6+AA!;E%bp z;&?ATE&Rmal#eq#nq=vClk`rcI`4H{y)Z-96x$N)|0^hz-NYt}orh7BT7ALyoqbiT zebQh9rZAO<=KT^IH7VM=zO;Yxq|y_+tVPgJPa0}0{rjZhqTj!m7yLRdyDT_wb+qA8 zf@qOBLl;}PVc-K}O*J!SCOBn9iG|gUyqs|iJXB>kJik-~Ubj&N*&v0|4)R@83WetJLU zl+}^;rW~9;NM#le)E-crHFcDwI+F3vk?tP|&64uFZN?x8d(+c#@M6Q6RO!M116*!p zvmMVL@?;vo@eh@r9W=2$1KrbA8aTZnbm1L$v)f$)XAeeuTu(coBKNnD6Yh68=XGu` zBw>H{R~)>Rr^X~sXUjz)d^bL)K95c*IUyzCc5qmk8zVEAj^^BMK!dt?#o`N!05b0S z_t60_?)#{n%rm+gkdi0x-~Hf47g#h)W^?P}{5>OV@xkiG>Io=B=B z5OTg?s?ILIRp!#uQ6xdnmn(56cN{8!O#9rCvFcx5e@PLq@}I=_{C@$kqEhWPwad#k zk}sW1wW5OSJ0%SW;y)7H-62KYm+u4Qox`7`FfdKkbEoFdW`2A@;5=`JT0f{+gQ^Nt zeHu*noJ@}r6}fo_%PYcb9G3Jt$Qp5i-$(aU?2(<0cpigv?#>7E$*qIY4E*d-l>#lJ zRGVEfRM|NTM)p{x>&R*y08769ll%C-DkFjZ3g%!aIH8Zj-p zYV+akNe9-GutSn;2F3tNpBE{OP4fCv8&2A4Cy`Le9CKf$T6;_2@sDlY^2S>cm3@n<> z>xnofv` z`l#g+>4!f_0$#5m%ioGe5 ze#yy@|9}LxD8**BYTtN&6p~cXIqq|)$k6n=Hxuu$xwZac7K)EJP z%_WoZv>?-1h8FCuR_7Mv%hqpepdBdTnYfO(*;~SeCrh6RcdZGHdhQn{rDg_(c?*Bf zRjwF@DiG$2qQ4>vY;9>3#NuAHi`mVlkYP0&Zf0_wAk*Gd*rJ(@e{<7=lCJTFdilr` zM~^KXvsd*e>dET=3L~vPq9z~@gnb*jY5JVhtlPMpmdOt@J zHQ8<~u0WK*`R5_|J(jyy@511JjbQ~Kle)$&* zjXVU&CUrQHrb6}ok*AOA&)a$RFTjW~m?|9kqC?vF zYWIriwTctEiN%@Qg>L9vPdbX-4$yiOdEj8Y=#0XbgC%O*xih3p*V$H0W+v@l2r{-U z6;V-4XJ9G{!9Lf7ClY?vEwQH1(q|H*(LHWrKD#NNvIn zLHFoxBj9rFJzI0Z@3dbz4q9=q3*B!Qp7~ob8%K9b3mx9f=~LI8=~k$m zICwm*buM?s{VuGa@}s%&>}&Cvj;THG4GjOh5?0#R+adbQpWQ#O9L|oGH9;#ak$q69 zO8zNXF*HtHQ#1)22*M~lvHE9!EhP|H1uS=-!Bd=B4USr>D4eEb!n z)Lm5kPTUgB0I893Y4vLS=TG-=*JZLOHq9@gYYFnaJeWz!x!MGv)JyTFf^74{{(hWk z|Go?Lw^{U0`1fa2(u1G*#x0#544vEQcs)nq_wdA`hMsYzZ=vkz^$E$$yIVZhub?26 zu($!ayi^DU0uQjR$i14GTnCM1;$*44AteHPty|Fa6C~t^q8<+fTG}Nh z1i)WJg2jJ}yoDn!+;+q!kO$c|pgLSH)OY`e4b^`T?}C`&?LUG76wteJE~owv`l|s^ zpLT+ZJQS(H-kApl5EC%|9Z#i;DNJyRGC($BLSSLN{VSAaMBD?j286IChOqwKe+>Zc z+cRPcW7Pee@e8%14T884p&R;%I*b-KpxEKA$(rUgz$9fQMVkiY_$Vhz1dYkC(!cY{^-KBP2;!C_LEsfX$&!zgEY{HH1j(&g^ zNKpB++QFjm*o^oeKp$EJzKonGj)FM2@6|tAf3)4JDP11u#Pr^Lxk-n7QpVo<%v{eRm&%zXaUtg?uObd;8B~ zRHCHBpo)oWb$_CCnhcvz(7E-gZq^dGK&=kCCQI~5LvF-h-4Yn4e20y-bE;BW&sy87 z+T-zOog4yzS*~>U0;!Af+QyDoM+G;UwyoU+J;#%Zz`UtkV_-atAAsW4om?Q|e*AcD z>}qe}KMf}!tbXCPHtY3;-h)h_HvwW5=bntT)b+JDnl67hc@RK6Sn9C?rN}tJO6fX9 z&y1&Up0udGQUd=llv6=#C{|a_#U`L(jnB&5{tRaW{N{+VyWx+lcInAAh~0g~q1_f! zB1;{D(*;2W>^JagT)=rwKTgmh+JVq%byKdd{}!px08}Ln5M~n=ot>tp+a^tTDrP$$ zlKDsEj=WmcN`|;(Pk_VyJm_@aH!-;WA)~-_ z+sHLyPiT~{NgBFO8L*D}E_PPESMW^}pDqWa*jFE^ERjxnR$$NrW(e59j#M2$ym~T@ z+`bdPzqcl2o2yr9pJ5|4VpgXERQQ{+#ICwnqh$5ez zOLt?SwT=EPM#!uiEZ2|=koZOSexnUFYzMWIj1P9Rmb$AiW9e4dD=09mj^^-S#gRbL2r~ktaFx)L2vue9DnO8`6of zsHjrY`g=-TU40W@Yfv8M7(WKSb>AmiPC>zKeNZzVU!ZIVB&ZN&j!pw(Z5ya`9@V}d zbfQ@7D&xS4t+I{wM@puv;G57B`nTYrQ)uPCSX$pG$Qi31$T6C3*g8$s zG~%Z|dL+NXVe#9{___VT;aKOlpG1zw0;4gDy%~OWFv(6?0rOrx5uL%{c4UIVbAy7JU+B%_pl{{+Xh9Fp01S-tn%ZvOV>^QG90N9 z&KRlv+E=VL%(G)rz;MdX({Y*4ZMe67zhUVq1tCYWWtbnS82hu{1fhs5qK7u7ALO&; zW2)#vn&0oPMNWK9Jhr-{g?nwk_Fg|8#EH8ss4>@SprZ z}wA0+&|DOH0AsV_}bsB5AxYUDduppKbn>^|h=0 zFNL@Btpt`9Ce;>uSQp)^{@^@rjpxWqizZ-6Q!v#UUUB^Z6@tSxMw;RZ>J(9&9vYCb zf#+Pv6R*(x2Q&VQ6mLz{zF&A?%Ji`X4;mjT|EC90)0&oS0cUK1#Lmn+A_{}j_p<%5 z6OmaF8U~tFw6NU9{!Tm|RCC!ob~MRHqY^nn#tMWyrE3vd#(S@yGwW6qIE|lO@f;v& z!UtAB-M(wBZ&Xv+7uk$XmvJowPxo^SZ8FQ(mjh@9*7Ut@=7ZG}XV%{#kpY33=o#w% zhtrQ&eXsT=m|0b-mbyshs=dUVUwr>Thknh;_pTofb(>{S*2nz~`eAhyVw=%0VdMVQ zATpkHne3IpoFeYe@CQ5ZU0}3eL)h%XZU5zSboe)W_wS}Vas=L8|Bx>D%DSzN&IJ-W zGZASQC21F%40b9xI^0dvd^_`>^X)%F^!CvkkBl!UKGl#-kp&pZD2o}p+(vb1KA>KKV!+V%P(1kflAj^taD~k5}_m`^tU?C=fdrf6EfKIdkL8r!IXp$ z8xl2`Dym)h=z=YB34RKNbO|V8uE4C0;FVR}-marKflV*@I(skpKcN*1*ZAJwKbL2f zKKD9D#3;6V26b4P=zoILzeg~I7mm-52`S#!sBbe|As@v+LET?^2#UfBaGAn)F@)hg z1d;l<{}tvkKmp1_jQb(Nx^JCbh|p(-3Gbmdmu=H0uygy`G0aod>F zHRVMG?_RHx<0BH+%v{1yy~!1U?SCmucO~wUM5V8oJ^}n)%@ybF5#_@Szvx&=n$FE6 z^uij>28u_zmJtc-pN$_q5xF-pD6C*W9{zG8(jI=!=&>}g*>X`a;rBx5x5aA9$J=?I zn7_{H&DG|~Ob!jG58WP2?(JOQPV|cZ7!y>7>TI}?(%VMp-odXSZ`9F0`cuPkb&9+* zQHwKt;jT=6V@Lr*X3?Dp0PHmP?e^w1)GdAdQ1O*l{51A0VTN%#_}Na?26W+bGk&05 z|JG$Llulv3kvL!9jYJL7bB5=wtc@la=Akh|4&R}P=21h>xd%^ba zk(W|e!h)}+Z)?HW6yGr#eyt|%wAfD zIU?_TOR@jL?I~1W1e&ZqVH`FR0xpqX`P;F9a^Hq7gsK%)>3aX{_FMS#@93MtgqrW4 z*_<+>ajo*d9CJ^L^tW_gdqHv(#O-uUJYJAH3C<_B1H7KcRnj+FI30#{00TlD|Fi|T zAY!8n%L?MiP$R}5t2+JO8n{d(4G+~$Bgt9fb5G4e)2)HQexH@2ie0jTrSBW8n~f9T zcvy7yS$~dcHV(=}*PSYR3%4zw4ghW_-zDoQIwNqaL_?4Zy`gApyPcgy?HBy_)4xnr>$C6cH(!2y>)iq3Hb`GgEne{!^=?FDe;kdyz{@Gpa-;hHLbofY$} z#?wL1+Mlljmj*lzk2$bt!+xm}IdHCa*67Sq?`ZAme%qdCmA#9#!fQ3!+OYS&>ukEe z;MtJ}+!i>?)aCY2m=SLgarHn5qB&0{uV30Ir(d-pL~&@_%v%zbtzyfhRaE9Ooufv& zL-A!Ix}raCGc6)C=2!M^M41c<*0*XV>CL_IX9v3}@K<25-Kd(~Q*=*Ho(WB_IaLOQ zLld2xwgXY+-nz-F@{A?p&DI)z_hHTz_Vv-(=!~!J`el7N16HXSZEjlIF(of8Jc#@h zBx6{Y)~HFYa;uw-yZ_e6@iiNGJw0)@&xQq%$9Qh)i1K%s%hy?T88OPX))*FJ-w4YJ z*qxZyqguJ<34|DgCU3Qm!Sm^Dqb%eER`~2b$x`bVJxdLHT&30KatuZTbgyTbG*+Vq zxaopos|`UM@}xrUrA9KuFl8Rbpf})AGa0UINzlD2f4ggBU2@)(u{5&F8p^8U@w|G! z+zL}U8~Cp=1Ic(^hVsY@vF#2&IdH3S#a{o_H?(1IwV>a^*&0&<4r6-74rVW%3;~CL z=HnKb(2}URTSa)_;(^M8B(TA4JmD7Rm_N*Rg&H3-)l73sv$0YSi!vSSxv8RM{V9L3 z-b@*y9gaIX$q?}>_|{1^xLbJBa|M3hHj5)7wyozbx2Zxi2@n7DeAP`Or5UQTqoMvBGd6`D|lLF76)sIO`h&}5 zAG8Y)G>*eF@^$s;AlcP*r`849n%s%vj{3ou-3yOKrBf7$pJciix&1^#{4RhQO4{O0G$*$QX$rod0Y}VUh^6W zMo^++^UM>JkSIfYhSf#-N`6$yo4MP&PW$GX#;kUaHpguEL>)wH+x1gmyQ3$xGXYLn zx4ZJ~M^xB86Uaa+WwWBRrrHt{3>gn<-ij5vjX6*Zg9&EgMjdDNXZ4QM!%3WZaA-6& z|CuTgw&rSo2o9+y+Toa|)sMkQtSsgJnsl7*a0xjDcrc_-`wY+EdD#qn(#g@Nu_wdI z-Zz^In;vnr&^YGgr>l|9c~aEvE3m|w9it!?ku$+l?K;+6b;fC_6M;&pePf6={;`?m zEZpp%Sb)2qEhCp6DU{u^KAZ_Ld!?94 zjrC{A*Gw%_R!nC^A})$^+bF+4Z{Q|lgF#nWO9|wZz_-LVP5(oXIGxf8p=xWJEITI_ zHle&2$Z~e9>?xA&ow(laY8ki(@nm!&cw1tNUd)q3nW~6w)2#=Z#;&+v!b8pBm|eG% zUWMWICGVckGdeXZXxSw;JEfgQ-I6sP5wYvOQr_ujqeb;A3H6;`^uDH7w^Y6+UBxO3 zWqvFM1){Ud7RaA{=Yir^xBRDz93A-#Sm2zrqAP0-o?l0MtF3+7(xzH&B1y68_u1~~ z!w@iI(*O=U$uqca8PE+wP~tJl!|$eQnPOsKG#b%7Bl1j*XP!yNc5Slf(Mh?r95X{p zh6i%S-Fb}0U~W}TxoWvWCSvE`&$rnys%+xOr`cty^>TeT!jsl(Fv&d457f3}gKp`=*9 z8a`1(hibeW1HO@=7-Gs#l55q$0jfKw+S1gtle3)*FQc zyN{jigQXNq_cAriunT@F-+3X>MK0`CJ*G`J5wly}WTePg_>&@y0RO^SQk_bdXe9qw zjBgs~?!<88KMsC-l?`eoZyzw5gmT}f33;2q%b@bf92o^B4af0KH&ruMNb1&+NXB17 zZqU9v^#n&BotQXvZ z_r+&BTdC`9)3h7`2NHQDAcpsO`xG#GkX=hWan;g{8pzQDS9;Wu!6cS<`|b~2iG>j2 zWpm`qqqzGgkB?&}_!*;n3-Z|~+}AG|-MW6rEi$W}e4%(rxvm08yTQ_T4plx1Cp+=Y zYbg44`AcmnHvwi=;CIc_lDX5KjHoMUP)3 zW$5W%Z)OMZjhZS1TxIDN)%nAc-^z(ZQy;?hq$VcwL z`n;NORmt`n023KHmvZdjkS{0ARZH+tIK#pN^SN)R14-?6e@na;E*SY)R#}(Z(ntuX)fGSCj@0L6%TdC6JlBueK z%eV|&IZJ^?nu75)i}6DuiBG44PShBR2BYWwku~4#);rX|JF_uh4{StPCgBT5pKn8f{9+7_v!a}-Ki*RrOV?e3nj%uITP<*RnRbEAW^}ud3}~>q6qmuNPF{ zUh4|O8;KTIy4KK=>eHV~37ue>bsr*0ul7d>x-3Y|FY{W7C@|>pdb-%J`B8lncZ}Es z6~y3(mYD)o>w!_FF!`YU@A^pp0s7L403sIQlXA$nA<8f4K1BrqA%dwl0^Tp80+{?O z=YhoE)Xcwst>!P5++#rz?#INLU0>-RJ@{Yi?<&w>$=co=OkJf5bq1_P=!ssI&rBB# zEt$IROn-w@ps}a@(;cdUk|0gF8_2r(Reb5=BJ{FhRlNSc65xfY+zA;bsjN0c82BI8 zMkolO{pjlBC&AbjTraj#0&7(!^-<9;|2c|5W9D-EJQ^Rl%6Tv!VKm z<;D8$f?&`+IEXGKa6HPa(q*>~n#kjJsp1*_h3sH0OrmjaxJ#Pp_c&`8!=0J}WNFeE z=dEJ*sa`nd6LnvB_Y69ZmJ2;bxRJMrV2%UCgb5XBk~F`~2C7(XwA^j3lCRJ_sC!u2 za~WD!UPe;hm_UL^rg7@kI-G;z?q7E5-=to?bKUjQP{D&8Ln9IO6z3_lyVr!5AH+dB zA>3@yXgrZ3u(iH&g`EAIe;B$hEXj*H@Z5#lNf684VI3~Fyk{@`J3oQJG`;8+Ln zk=L$)f3$)XJt|tIvAv6o=qUGNy$f#=RM-@sJiq;qXxI0VJ`-Zn4+(!*Z!;n7w!(%>AExBdhMeYrm!Dooh_Dl61dMNe+vG2orJNLVh zbZ#kw8C_S?2t*bM6|z)^4BCfPlFm2%=kPrKe5!vKAe$p86*08{hwKywd1R!>kB0%_ zp^xuhgz_U-Y0isM7!9=Pf0KT+JaVRnotq(bh>Z?fQmb-zU>3jLoM<$72jQ}zvA!?W)HF?0Ax?K^F~ z=Hb`RuNPe^E_pZc-|)jmKWMz-f_*Vhtff5*^`u5Cbtgm4f2I&4QYY~NcK?n8)8vJj zWE2v9Onm1H7ILqvyZqumGKtQqiAk5qbz6jC2SkJaLw*%h zw+Ss`uWvEFTX-4T&a1sKPT}%hy$u`CCIKgSDXI2SLYC3TxA5-w$UEQYDU5+v~sc3Q?Jw6QHA?%n5XTvNmiEG9@;zb>h zB=FJVgT}4R==5tLHTi!$88`u&gLJXb)HYpRAHZ{}!bq{e`!F>$Fisl)#snmHa(tK= z{zz8a4g1_atvh?}|44V<0yfUAEI|2PLej=Svi@r zW7V(8DfTNuDQ0IZ;#!OILuWcb30N3)r8vLEX8Im6ya)ME4=y(wQ>}8SAfM{fmXJTh zi`Rty;p>&WtD*Q^HUK|#2U1&>b@ySy-vK@ajQcgj3ctLypbc;O(ayVmI>ek$=PhDA z>!Tlx4~18tnnErt{|E#RH8Ad{()403TKms*>HVbrcgYi}9~z87AS?a3xC9Z)@92#L z8*rUeHB|~;Cx-c}rD_GFz)C<&eD-SJaNe}d^(G-1?q)c0+~;vr*}huNz(#GKwuK9Z zeddrUc<6(VL55yNUsjWTOMi6PK1{#j=_)zH-wLeXpU%>8r4N*^L2B~Fi(kl>r&IQD zWZ*d-Bo%H4_}LG`{(_*!%>I%6f}Ud7{&y)TN0)^nATQAe9FIiED~M2*SYe8B5U{ z%L?@B6_mmHsc4pqD$Mnxwb@L2gDvMWOO8c4TAtbYAF_j>omf6(P}vp zL*K?6L9WTU#`<#LHI9zz43n3%o5)lEj|^}>cG+DSd%v%bRwPufL4D5TA(iS`pUF_P z_AdBmLdfTsG2EIe-T@?<%}zQK#iF~cdF8nV^K*FI#+=0^!S~Qty$PKKyKbbEf1%C& z9VtCF37JUCqasvKi>33&MxW#84OIk1w+z~ynad<4RR|=V5 z@N0z{6N1iEnKsifn~3$=FzurcG3iQOkZnd3Qu(&; z27ii58CDGQi#v;c7~{%6n|cobSszXFzbnC^&?>dr$~tI)<+7SixxJd6ODG(;gX@3U zjfCoq;1Cb(0u%MijspK?ua>aoP=12BslYYuG6Azv!gV9Ap0@BOnE&^%`k zNl;BtoXNF@)%Ej-`&>sZY7qD~L+A|H5>24hqP*2(d&Y|kRrjmxJ zpX;$wVJ(e|0PzA4FLbI_(-LQ})W;L|xO)?h4=A9P2{>r1u9ojvKIp()Lw~?|0t{sg z@rq`+J09+@Dnm+^nJE>q-U^KL-g=GNwxQ(LA0pne=bcp$y@+jZAD99C(^rpUoEt!T7`sSYXBgNAi;(+* z1IC<(l)l0TcWj{Te7Jz(jh~u5Y-Mwt>z3I18>~U@KkF?J09QyKQq+ zwsZRnN*2l_aKJ7!)zataY8=l0s2xl|i2cN$dWSlII4vqI^#Laj$>XXLK;* z`?InpA7opMO-(?L1ln(L-PhLkPR@bZ&>`@KJQ0qaX(i95jbWK0;^7)&pxgTP48}eQ z!2$p(wl3v-(;)ybwZ4ASeQNG|>pJKNrpiAq9`*ljjIx?eupHm{5a5v;wbH%Ahho$# z9gaw`z)`}w2PfpynxK=2SngZVvKQACxZ2{M{Rj6$$7QS`rt-Z-7#ej|L`>U(WOK`t zwa`-miq$U53_KRAVs6x<3HxPMviirj;ju$b9H&QVY<7{B;Bw4i@8RL8jP{= zmnx+@KKhAM1YSr3%P;*Z`;O68!=ZRKy~Ehm;l!`9)IzR*QX26iz|8T_FbVLfw#Gr~ zax=RWg7@;Ejt`bGK*#h4I^sv?cSJlp-~%4-h08tT_~frD3qaPrF=keVPv|W&shWE7 zesF)l>J!M(f)v|!&s zfm6PF*4)!(0&5zedr$rHCGj5pSYdVmi*CWxU7=cX56D$M=T+&K8Z*NUHL#Qkw{c@B znZ#M{(f2$!NX7hFE0j~h@&?)**||@=f-It}GqJCG*Dz{e;bXb)PGQ3R162~v6IeE- zkIV6B{7c!50V_-CiNp{jvSXfXu-t8Ue-h^H1Gt7bXc}pG9*0Av%Z?E_E80_aFaYVZ ztmB>x3p5B|#+@v#Jc3=RlG<0a(hgHmDirzbKhw59PPrzVpqd4Q`CJwY6`n1ud6J2V_V6Jpg}?|7tEG0)M0lmAGClI@PmNE zAN|8NKlh+!kVGM-sy0xHE<@ZlMN{i@_E4d}k;%cE4-!=j$Iqh_FxP;5jjy_fjeZ$M z+U4QI*`)+7SgC2bw|EHZS5z^zynkTEs?mh;?U4XI&6{tl3Kr^S_|Q2#q7s4xW^?PPvDaDuf9J80aTxK9E|6d{b@mm#ZZ0F4m>kRbjoe& z);<538I^MWtmQjA>W3vR??mEz=dqd%JY<#F>axGy93UEn7&!)p;uvWOvI1g6Hsg zBQ8_g!{l-Fde%{#IG4JQ!wj-&Hx!>l*_H|&TPv%;j-7N1u1%W#^{259JjE7Bsg1Yq1Mmwp|@nxB|ztp%FQ#U(F>_TF=BwtHPxI z^uZ*9n34N`NX(x|UB)Q>jL9)f>IFKP|A{YB`rPx|HWpXy&3&(9{dcZBBY!!eOBV&6 zTz)`w7V(U#L~1t#M-b0zuy!^c8;1b@xuwyYbNRI>#*TO~J~b5HX=w?DQ-#l(SnN=x zBpdz0m3NrqMuod}{smReJ}PmcO11N5cM^a2sP~G?WUIs~o<3Jrh(moV3)Ppx z;?w5RTKWd0@;8(|{9Zds|Jo@95xSJgT`ld(B!|~wI=uhF7@fR;1r?rYs?p3$n*xAG zloS0!5`KRTzzW;fdWSd92uA-vuMtkAqD*CL9jJ;ILreW$&~Q!oU34{s{ohOc-_yZ2 z5tkB(U!qhl2uAhF(l_|zutj6*q<>!(MaP7G5(#`OapRl=;+fDwfa%(y{SUuGi^K5D z(PW5xTyMr6&QR!8uRz?n+14uzh8hlAaj;-k!w*d8R>z3YqZjMLqs+TKy=74Nygc-E z#dGNnWMKJhx^v-!W9bo>4c=0SO2J}7X~Jyh)4FqIc~Rz&miFXt$g1Rjr9l&4XIya- zG3fR!i0B|5T+r@`MiLI}VO`t5MS9il)xfctITOecAjLwJ$*@DB&g?5msdKQ$;D!$U zSC%S1NzZa4dhtR?3!WHd*xabIAwW@BqR!Wqm=J%+vt9+#^{8cffxO>;C)T$3d}wE6 zm&1H77S^(Z90iZdqTf2x6f=FVafm+z~B|vpw?)fjX!PAp|FjZcQ*pmp<=iM$HfpKV7k(IGvBaxNiw(!^0#)TAcLo3jD!d~0zg4yb(>OGAMnrh_$auQNR*}DF zOKa$dsN-m*^dYZ8P=|=qb3uTy?O&1V<2Lbpp)?XymTFapu;O8XC+XJj&3hA3<6~EY z{=dq;0xZfe>T^sGkWiEc5s+>H0RbHpq#L9~a!ARM8DLOpq`N`7m2Om!4(Vn@I)3B_kHhsqJXWEZwpR>~Bz*f>J@aVq+^)^XD(nhifjUv(j2a z-EawUWjc`x%VlBCi&QGgGhyb(2Bs6h?T>rhfZAXvdr>?d`MINH{ z;lH=Q8BeeZPI(?xd14tr2}4jwveIti6|39xt&m0*;5-3dBEj6x2ymuwB3J~ZCTLsU zZVRKOyhD8f&^Z7BCq1Bm3#bS830b7ck=9IbVX}uCwzQh9;UT->+fb}q9BKUpD0~&2 zLT?7LeJ|WVIdE%&(sVpgouEb@aC={#f)f-`xdEqmh`=%S^=3Dml=U0m$j9RX6hc@^ zQx-z++egkrZ zEwv_;fNM(W7Ehi&080XTdv-LO>{8Y!prj1OJ_^RXUY zB%vRI+%IpfzMAi+aZ`^Cy$=Kx&=rlcu6|AtJ_PiYp?HPuP{W6a)^}Sfg2Q76fkdpN z9SfpKLn{gDY)+{=?q?r$veleIv^+85dshKP-SeaG1jL8ZoqYb&Rx1_K6d&7OaAU#I;T>rQVlkA~Dl&Tg+c{P6&f=x(bD~^rwdy-?-cc%ub^x7S#jT`-}kuQ%2f0{Xduz0w4#0D=*)aj-FLN}k!C zS*P77a?RU9YeIJ3IXAhF;nMEWfV3uW)pvmV5un1$f~XIz0b2t?t5h_W8$e#SEdi^e zBi-^PUX2jHIU)>t7p%d?kEOr+KTLB@ zrEWcVh}5Tf2&%yEFWLE=AejC9K;#4P$#KMVaf+Pf^qdsFLh^gODZLF6I6Z|6v5UI4 z&t`%=D74}Y&1)l~gk#`Xbzq1>{84vWpj;>L>a(XagZTUf`PArSr}@55qPQaZQ&ZFj z?=X_f*Ciu%8wIb6eB0k#7vr@;Lvsy8vNzgyVnO$DmcL{!Q^nGWH{bw05Ex(*j~nGp z6hi5aVcS6wr|tZ?Mi4(kt(I=%AG;kWXCsWE7Pkxa{->f2fEsrrk`#_VO=CE@$42Yt;Y2iH`K0Ej27Rk+-&3?)eWu>wKnuD z)~+|2nlvdc)-E0$s52_gv^Fe8@~Uc*lj3~|h-#FmX+Y7Yex84lH&5KepfADG8MPp{ zxijAxW%eeD_*}f&=9|f{220lhKI13L<#K{esoTFAcFenv_OU|nIr)~czZl7xp~0c% z)ar#%OudkertWz++)nT5dfndY@ZnjTqJpBLwPy1{Rb}ww^PnC5J1Qh_Ok{nmGnG&U zu65wkam`goDpOdHeNN4|dLgkynNind^NY|6$ud%Ca;q_DY$ zMSO)pyJE*&x5@d?$VpzW*VZyL=)<2vkwm!r>FBR(iNCKwydyYwGN!k7EPLZQUT8O` z74=C)l0su2FW00V;0+Rwg=VsOjd07Uv%p2%Kn447hSZx50=9NV`XUat_R1vm5D0kiHLnl4jSZe;twejyuFEh(IbT>&Nv3-P5}lbp$KraA!v6reoqrOWF9gbGhL zR$)rF+#LepGt9;mnNPe*W46w^@+y*9OU6RoS_}!oC3D!=Sqx(mU=<{@!m}E0+^V{= z%r2WhV&`X>nU#T61Y0&->6n#Ch=&4C)AtwGR1+IRM!J(T4gSzPBJ&1&NsEeV;~4}J z|1gGQ=*R5)`dw;QNLhvIi|Jq!2GF8nIw+`0T`#(9z05EM#(uZ0f#_j|1|v zTy2tSJH{25ZnSdjt02ciAUmw!vm&QLaE>cSQtMkz#cZ#_ntEpD>|d^I{bybYsf8*Hn1A%LZl*?trM! zpDrZrIVXIYm$gc0Llq3bpn<6XM&m!8&3{~L*B^lS`_Iqg1w@+}E$@@;7v1y`PWqz0E*bCffjMTRJRo% zzV4NxpLa*{Y~!?WtcA0-9z+@>V}J##_y97pQ&MM#dC2(UyKlGQX~<+Fc4a@Qx)7ly z@Xo1H&vPG9L;4n*#@SW-q`VQ-C+EwMd{#PEic$Oak@T-cYs$X9n;7EcbCOv1m_tKm zZa+JY(7F;aSLO;Vzk=8GO7$ZC#pp5x{BK^}%F7%|LQ%+57dpX3LBSMg^e$9 zht=63NxX1pzuxrXhfE$g?(OL|Svdciv^ybA%GymimsNJfh;(JzPqkrA`z}m6qgXk5 zD?p6O0gYg>Q=?lWUNeeiudZ)#Oi+HXvhOa`1DNN3TV% z+W^HLvjF-?MMWtRb6=vf&oyQZsZ~fb`C%V51EBR+-b!ZoJ`1q5( z5Bln--f9)%5le!727HX~k125k^LX<4)p7Rl3hp6-D2 z7}ic^qw6U?LMxn)P3F4%_O0D(>K8qik5-+}{gmpc$VBZI#4ByI(?CwKcoInpXh+#o ztKnfoBuQ?zRA6Y}5bcHYfK=$k%f#|G$C>T?_c)_*%YU{Ru}a2O2#xuhuJ*Haf)_2k zpyzj?9=P2u6^nin0^;2QgYC)Q04&g8W(O+ATBc6&);Kbas*Ulf2DwkO5@MT^$oH+M zg5`KQfegJom^avsg|FDH&Q8Im(FRZ-x`GbHAg`bj78rtp53>5%mfmPCNjPtbtU2<5 z;~j!@WM?J=4&7t6_n}YUlbdZrT54u{;^v?N^x(3b6jYe;1uv-%UfPBQwUTVg_AdL!rCp$^Myd_voTt@LkKkWfA2M!NcjBHiXL_)bHk; z+Gm-F>7?$ydly`H(@Hb`D6NmQGbL zaZ5D1^;*}9Tv%so9?(d#KYge!*jaFU>h0Tksq=T!c=LX@7>lA~ckknxT$h`ET$^3^ zL;zvay}~BUbJ1}NB^OzM(4rRj4WDd`5QWKd}nI1J!eYHqYMbsJ!OaD@@$&bCj5;Wy*M8UE8`E; zxtn6Gji3Qw4RzCa+s`y5p`YB~QO6{X_>iW?O#6}&XK&2RblqZXcsfl&5D^~kaya`5 zoZ|FXce{pO%Sm~;QkkSv>fby!^uWP0){RZ;N9D$>G;3_}q-66Y6>*p$ zgYIEQCT9Dz@#n^x$0F`tOceg@#!{e;&;M=+_2iO6RR3O84bBO1E5f~8e&Fov+)Ic= z>NCF3rC7d4*wiKYQ5}|Gb4Oesd~`b6`zXxQO|Bs(W=GeR%}FQVfUfrnay87jCI;^A z7GJ984v5={_Udm{UG;gBzhmLaS1CG4%eZVTGjwh2{F9#AseO>R8S2VDKU{2D2+9*W z%v9q3F8|2wiPWi2 zEZ(&XJ6NH)bgGEb)FI!Ub!hE&@`9x#X|!1W~N&yrr=foc}1&Q8iFgvS@b`f7o(w>7d34WQPNa1BK*O}}JpjW@aG zb%I!mpS$+BSLb9=@2Jr~)CNyfH1@vARJ9LjhKX)U&WQE?H;pS`M;^Ea=c-UI>NOR) zMRKIZ_>jt~+_3VRh98-gP>0ss9chqj0X@stqyhrFC|X`J8{)mJtoBrUzB}Qrf9UB- zG2`8vdz;jx?|(`0S#>-^Z`{5`t<}g8LMQpI(}70pfPMgoj+xWY7t?`y0uI{eVnT$; zzxL!Z-LT?214RrUKem9??sn#xC!?i;wx>%JDlu+W?j?NANQWSC<}^N7tK4cBTBBM< zb4BK)SnMEMnvNY;|9l%d+1seG!K%e@m}VIp#|bElwU12`{sGekgRP=4qIsg+*~aB< zz*Sc2y7@E4{#;hb#sGELlsWkvsD3-UY$5_;o5LkO8&31L>Sb>E95u1^uBV&TQs>lE zt|;`J#-!ZMeGI?DfCFAw>ZZ7Dq%?cIbbFsQ-tCncyI+&sKsRsgBbyQT!fvBB`+9nw zmf3KFl>p&>R=2-4Y5%LgoU+qb_d8H((9nu5$qVorB{J{ijVP@T}zmzf%1pBU+z0EMru6K^@sGt48v2|pLahnvHFsF zog?oRS9CLufwiet5S?P&oJ!z(T&E=NL+Wt2`ds1~#ORST39q!Cqmw}^b2l`0kvOH^ zUHi}69hNr~{2~scH5Vi6b0DIEsDa#|$u{9o_E?El;>lRH-A%Bq4QkbW%a?gDv+&1z zdhciSgqki~4u-*+(T%JbR`CD>VAi))koo!VXQB=GGSeTEQ2W8ug4yWKutTZoKRA#wrWG z=yaKQQSoC)jQQ;_rw=+<%3~*h+3LKOBa(vui9);k*2YeEc4AIuf$6HMS}SYzQ#Er$ zjo3HVE08yO9QC5v*_O=ARM`E=Hd^mNF7l-f=}Y`aNVt2H_4ul42Fs(|sVS#o0A?TM zM~7%Z39jUAMXC>CY%gI>JhM2Bxw^dAmArRmx>aBKmhAykA8!vSQ;ny=lnZ=*43Ud$ zjp6~=59Sz{AIVJS4W{HjanrxJ=O1{a`sJFcj7&~uu1X0``Pi6E4~A7fTZo$2^(F1r zcCel?{hBIH#bsPxJCoEho&fH7FX(Tzym3$bc)Gn3Cakid@S^)Fz%?h2i%cuv0^mv4 zA8aSWV}MYQXuk^hhJji`!h?GdNKi=RAfDAiYnT-7z_OWth*rWAKzw9NT7BgwVp@rj zS@`Qk1mB%KrK0L3ydb@pX)Jw^YJ@~P#IpwFKbF;-Hzx=~KL(?y zQ#4bCoG)GMjwOSF{9iTtxPdvc2;tFDY4iaLr15H+XZf?!y2$#eU#3%!OV>vWwp({u8mfQ*p*ce6ar7Cs%kS6ZU zug=Y8ODjaZ_I*p~EnJ$2Zqh1m!0ME$>+b&S=_x9RYtLMH&Da|Adwl|_I97-$Zr)PK z4W$v;53VcKD%F{)*QmcAGd=Sdi$v5+z1D{r>Fn=3L0;TpAb~t{)av^MVtLGg-E#TR zz0p^Ut(cCyt{9Gu*(00UT%~I=CD&*0UM-s&lyR-sHc6D;$~+(CJ^fMW^b4SkwQ0+R z6Ylywa^lNd0lO}AUxA~xekSzuU{+cRO{}%DKbg1UvwQvWS13xXP{XL92fDG+KkbE! z4kzKb6vSWbzMbCDne*0@v@4KjoeP`V_J?i8GhK1T3!8P$ErUQ@D_PA2yR%v`w%Q04 zh>40Vi0p)aXzHzRkZ{<>Vu?4AXM45AD4euPCs&LF$H;E-q7#f?%wpTTnpFIkmmEfk!fR~{$Vj)F&C!;K8F{( z=rb7}cT9jCdH{n!J|C-k{g$#F z{hSZQ->zV?A8n50f*HwA_}!ATs=s)}(nRumG2EuO?i3j4EI#jP=}z|>vQwt2nLz-% zY6H9c(aBheuHD}63ov`0drxuzd;n=T+)>dC^}wxrJ^gK8DT=rGqA?G673GNq3&6hr zU+Ia>zD5pmCz3f|Kp;weXaWg@$xA>b74#@(dcLmNPQ6-Q zuJwrJE|6Aya)4ht5SGt0d^&&o*@19ZEBQZ+8nyS}hFuZQhf|YJ?6^c{ZW~?&N&G=(pf8rh^UK z2Epx_*8P)GpnZ9LJRbts06_gr?a{uylNN;+_9fR#EZ2(@&2d}&BqYJ@;w>MV4$y!I z#>C@c3g~qsf`PO52WKq3gt+hBi4=fh@geO^dd#JF40wryeVS&#gGG%i%XP8?^2qbN zjUsGjv!%aD%IRlwQLrR1xR{u+Pa3oP?X31L z$Crn#_kr~V4QND_#Pgef-sXL0HvH+X<)z}JpQ*IRjiRZCJ-NjmZKi!{KL)whuKwN~ zYmk$ci`k0AB&kc&PP;U_^k6TU^e;GdJaZCOVo++>7~2Fi@!x@Y%I&=uF;!=PrQZ>E zsI=XGltz4RWHWi5#1OYchY%Mi01RE?7?@iHuc>r8m%oZ{Zl{$P-4;`hztDodja=%b znX5i;Q!JbtssyYXzlJ38=*i@kXu-%D;8!YF#PZ%^gfX+URbJgZy{CzS-at$K$z>@7 zCIfZFrswkJc_!<*jqs{Acnd&p>EsLSY5I>~{a2diQhU6#-Qko*&thC=7r zr3F<^xvWTd%vUv6&NGO)$!H|1_`O)b0OeC$`b4{>D=_kC84MG+^q(+7w3cclPz3Y)T7 zLF0wqVw|4o`sJ6__};eu5($Ny>*CL;c7>Lb02*5Y^U^suUEUV0!$Ynn*ExbC*yl_lwuL=Rn|!22BUB)TvO&Wd3$wkX3& z#}icZ7_o%c$#mHWP1556q`1HuU^TE(PV)GU8=B7m4{>P*uK%T_V8Au^ik}iEMJFV{ z{v=)!gpV?A1q}HkMO+zBeXJ^} zMKeeL!GE>3w!zl~cd*ymPfp!drwVu5>`-t9KA9*QqJ;Tr-)6wAdC=Ib-^#>GN|2k+ z>C>x143#It7lxNGxZx6A4DdzWl{&HBTj;me+*MSTGXzJtyIl2&@`EOY3Q>>UqnGxF z4`so*RvCPLFjMA*A~TJL-!s2V0e-Aa@z{2~?>uqR%ckSH5^Tw03D`kYC52;}ZiHTj zg7d-d99nH)fEXl0kFjvVv9oUyr}+Hewhd20CXf3WwPgH?L-s!~YAf~Dh4CuUNNHEoQm@iV=7g?SBw*oskV%7@7Sb39hi+^j=4mSrfWVHJ8 zPDub228 zq`r~@N-MF->l5GX5<>cR%Uh&>6YXMw%PHgOiz_jhDaYk~D9o3m1klmT4VM#zvwfu~ z-$ D6~@^HuNaeb~?Rp2ohcK_J_{YD9?$<$tg6zG`Ig2qqg1n{kt?$yPx=t`;s4@ zMs+fLrg1x8!W4@GZdSHZ?|iq^hE_rRtkP?{B9N)NNH1MAp4XsCSax@O6n)@u+S@rW z2a;}~Jr2_BY$!aRm}HTHOu?LfnlDqv3UHQZ_`U0Lrv7_tlbg{vU$D!Iqq|J&$LP?z z&H30cQYf&p_3*ccB1fR$*eEi2qI&yxs20E=db+y5See)Idjzk<`H(ivi1(bm>A}VJ z8rHjnIvf&D$R2r~kG2ndb2TdTnp>&z{-h6B{N&`wlkTqlNwTLB(}(A^PUulIFfc)h zz3T=wMRbn=i4NdED%ii-a}qmR%Aw;FR+59f#SN^&NapsF3d>8jfmY2mRs zQmWk80`p`#U(&ElQ+e@dP;*n5?MabyT13h$b-pO?eTuYn%bXCJQ8MVpBuEiB&!b`C zWoKif(PT@7`F+#XW@2i>+Oil%|J%S**hAHU@x^hOISAus@~Hu+*M~O$ce{n%;ZfJv}{6jZYjO zeQp2#jmJD0?2?gU)Ai!|1LFo-y=Ubb^Cvd39u(xXZd>CCQdOG+XKl^qBOh~F6lyIZ z;?!a6J{>)pHeS)@+k3u6;y#kx8ZD!3liyGHMMS#m`4Z>PTlqhUSGh}{TGZN7DfiQ2 zFm}GA=7z~STt^&O>U+;i3iy0t2G#K+A`-T3g?96;?K~|?$K_1@#-}D`LmR5+vC;sM z>H|rY%Md!0`mD#nZ9-*GE;6e;cDM}D7R_(JXc!$E>){AtgKqMhS#^I39KOf>On1f` zXnl{(pNokjjllWGNxr0HR7!!sECCZDX4(MoIYi0^VE6qgIzNrBQd>1N+E*_&q$%>eJHIc5DTjL0*{w}fs7j) z8w+ec0U^O-F4u`~)n_<6_3F_|P;I&FcsI~FC@gj>uNJX3I$B4^=y_2AiOmT zJ_m@aY0GCbI&xpoazkJtRaI zb3iA_;*+P_7*tzZo1^qfL+>Pt)ed=^?x`CB+#t#n#@Jds1s7uR@tYZrbz3<~0P_pG zD{J(mZacBMn5aEV|r^6UmPYq#-N~oy#vje||f4mD$H? zNdqm#x3byjpE6ZBT=kpwDMF9Z4KLk^r!Vn(RBY_USn4Oo?f%HhCFZ_FsVcl1{>6qT zMM=9rPUip%6X;$CHyf1rPAch_mqRiqD(($ZYbhvVdYtuUq<%Hl&!EwfWe)*-6kx&G znPgZE=4}FZQ{5ho);H+!LbPT|6bW+b@Oy*?`s`>OK==WEN3}y&g9PKQ+0o7c#z(?U z%Tw4!k+jMvRNJCGzmH+hfipt*tX5o5aJQqR@@C)m|B0*)kvmz`xrcZJ zn@(3=UkV9J-oj2gXae3?XecJW9g70_NVpI>lTUchB92sH_B>tZ>+Cy$fw&=ZcaV-tk05CqZ7Xu-e`;ofS>f7SbdazSv^8i{gcY7&1pE!WDn3TRYgW`OfpEJXM4Rpp?0$YAqwx@IL_y7 zXLR`XSEdi@amxF9dFizx>Bcw_*HGcZ;MEYCVbMj@oczjd2|`nojPWWrki>*|%zk>Z zY57e*k6jqXC>M6XXBOI6SEawbyFpO0IC{1n$F;y<*?;7CAnWJAE1{Lq4p?YnnqhGk zAv?ey&5ksB=^weKrKUK=+$X198v5Ed=w9wa`oHC+U!HG`?0sv&BVhE>t(}FMNFH{> zfcvjYl9yH1zgdJA3*ry~7zY`GVCcFDDg9WarVHo0k*6GWBZU}@+Ca$OwLiW&X(%af zBF6tKGmQ`VPAJb;acvd;FZ>^}_#fdvjTbY$9|6Q$Er;Q``0wBsmvI!A0To-kPtg`M z)F1xAiT(Z`Ilxg^^Y9*8no8~|_i)esn_W)#e7U3oo6_DbDh{V9+$l}XL|k4R&mm!1 zBtK%Wj_j-2z`m|^*Q<4}tH8p|Wzes2=ZLNar?1PQ8gC$w1|lbmwt1$hk2wcVhjP0> z8e<;RFe?+kHa=rQLj7@QhL@3mo;M(KsqTC_m$tY)dO?YFb11@HiF5PxC4IQuf_Isr zFP&1L`kQm!(DXM)B%@FG;%U9M8tdf?1abF&13nv-;fwhD_vnS;9%sI$!#xTX1)kn! zx)$?SAc`q5Nx5T4W6o~vg?DF>3F?HZ2I|&Ob?diIAhlwhudlnoTaGkZh&Mmq*Y?!w?#a@*p6h;?YO45&{Rv0WaIgS1wN$O*enC!C>5b=J~ z^`cDt!Y4<>3b{^NtT;BGcedj)>aV+~RCYMa@#WUD<>ZxA>A z4UfpwxT%7*;7`)wx>o5MQ}a&N8<013)?Q7IR!@G7m!GO*XQP?(HD{J${CbCpAFfJt9d)2wtLz{ygn7HDt!sjfPl$|09Lm^! z|A5qwlMM8Hojf``I$73G-V)Lwt2G@`jSbqqnSPWN&03&%0!S&v&_0>;J%6};X^Jxv zlMIb9{UW3~(Yx9eg1jY{pZ$5ij&Ht^MAbt*(f4Pv3K@vA68z1{J2z7Hl`l+1UU2f4 z;4CCMKH1)(yK)myGVvdRe$1m4CSJ2-k$MyGva`(eUDoMgbEL|n%wk~lNeK}EpIK4# zzdD6lc5*gqoSa*O?Q)9(uES^7uuRIf`~={^Dm6vq7J zqjd1ZuA&CGAm{t%9&idk{;C}OQn0Xrgb?5oFtmU{0ssE@ooB+wka=f$STd4%g2w!>B#FIu|4|66000O z<4*^p+@>p#?}bjls+N|Ca(S5zJ-E`P?HA>o5I_FJ8hDf%JRBXjLqq!}?#Ry}*5X$~ zWse(Ul+>Y6509%fU~n5ez)5KEg(wg1d%(0v@C>n#VsszM{0JOcW-SN3{N7DLLy;Cu zS{lOQ8zT6!k;v$dT0}&k9J?)Oy|u%_nmgM}p|#N2Teis9a`Ie?j+}~Wn>p$Pbiefb z-O7oXjwzM$z-VK{z{E8@^6{(8i!=cXoN+wtMRb}}RJLGZw*)|*s*d|rV^C?LMu?*Q4)Rc{e~yDG`tZyM=}+pU zmMQ$pa9QtTJ+sbar!a0o{%$VXVVyzhAP1^Ac#Pk&7ayKh7(uwggqaZKc3YWE&XZXB1&- zagZ9XgBcpw8dQx(IP8XH)&Gzkolwl`VEy~*p=DG!mlVzOJCVuU+Y8+LKhE(O6q8qm zidF;EGJ7>G*P678jZ((OW5G^*Ci0UBS~?@&$0t<-KdcNVWn5@r&D=>18q8r}PYeFZ zJadKZP?xV|GQkO+(l@sk7{wZvW;K$dH04HjM>96ik%SIYl$;_D{8CdB6VYz(-hh>( z`jZ7DBG1Xr&dz0JX8!dkr=ZvFW2r$CEji^K7dahD_F=(#7scWbS@m^diPRYO)e{|Y zY2A)8uI@5D?!u9^o*qRl3mHES>1=fnT%w{$oj~=^7r@2Vm3rLWWn6@eW^(p}S-Q8e z)LMlj@0^^R+<2T1H)jz0>*aG-AZ*|4(FAZ8CuK#&SIY7p@38io3m6-djEC!4QOuUU zWTKot_^zX?yo}wo`gS{yaZkl@=CS9j82q3HIgY7jr-+@Hz8;noQRlUu1dZCkq~A0P zsY4BfTA$CRfKEeS&BuP)=b9{flqZOFl$4)y1W{J%~)>soL!BSfDug5lwj4gtqq5gxlca>Ds962^Lc<@4L#;QFMYpYZAE27bh@#PDa<~h^>{c&FOWYrG^iXOg zbPcB^{pI0@r^fUByEJJq>;{es#F~@MdGi~1P5kOq-2-WxtS2IBXNBWK-5tJY7!ujE~7(>nr*LUsyT*{lujtLn2@%6wZa}2 zEx(9=?y9G1`s{#+IY?K7G8RGrLFB#=X8ABN5>qOhT_^~A@RnS;;FwCHXIa2U^ zVYfoV_lIw1S-6wLbtbe~9FrNH;& zkX;Fpe5ok)#d}!o4SLxlezD%De@DAyJ?8fMRkNeggR&1IzoK9d0aRh}p_dz5uDQ41x4xUa{S? z<7y-?DVHu<6WwE+?q|drNr7f`OeADzQ4JacFwto zqVniNLKerUUUBSb^B3W%lu$AgIgoZa%t!dAo?5C7ZhzWbHUZA)rvjZf$xX)_$q2oy uwM({lwbHILp$h}m4Q38GQ@xKAbr@{mP literal 0 HcmV?d00001 diff --git a/contracts/phase9/annotated/desktop-en-light_v1.0.png b/contracts/phase9/annotated/desktop-en-light_v1.0.png new file mode 100644 index 0000000000000000000000000000000000000000..a53fe473aba22a77dab913d83337a50a6534543f GIT binary patch literal 144908 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ΜE%U6WsAgB~J+Uk0&ogd6swzm%#lxCW4E)UQXl?m^7x z_75`=94W1Tgpd{$-u!~+_#XfyHyhvz+_o1K8;wBz+mq@y0Rh0CE~!GZ{Qst1A{@6E z0`myvu~lC!d-9hduR1`#hQCBuQ>t&hH$!#6VOjro5sX-Dq6j!5Ay5s91euCH$EiF+ z`a7=9rqMhCLa?WT(lAxJufK&&ZITM!- z+F3}tm-@f<3POw(v~3xW5XNuJbtp7N+(Wtk^(YG2a;ygf$-)j0hQVLyH=RU(4=PQc zi&MQOE`p#ar){jR(K*-C)*x(Y+`{LFfz;Z>G_U$?5*rr7uyb&Qtxn9|G4i zgs34Q5n_+$^Z^s!q_PQ;9sX|CkLt#T0e#|_7YGW|MvD0XkF&oyn>(xi8yRQ$N}F#( z=Sun!0#$OmI@I(jd9t&)`G2q1PG+=h%(RhM5D^sG-#JNwpOeQrn;ZV`^&Wv1--hH1 zHUxyA9XnR?@Lxp*|4ppDy24`!3;GQf0ff}np`Jh{hWNt-P=1WPrKY+a%D>tBKt zh7*T7I8`A}wd*e}3o0{KNSiydZDl#B=f)u{=(x(DzZeWNw5t09P zbz9hG3}vlbT{o79&V|7S;TITCgH3ThexM$aZAh-dB(rkqKtlKY~ypAEzU4 zeLu$XY~&~(n!goz)gU*SgE~o}rGpwYI9jv_2d?6M1;!YO0FZ-e3==DNMCw~6meI;` zrpc+bHTP3BcSprl@xmyduAfp8>y;XG8A;E8??@m0v(I{~M_g<7H%IMMELmlLWG}0N-)#dm}ZBeG$}I4zo5RWU(Qsjf0Pnzc|%>bi6?$dqTUN@h~pS1PjHBuk>w-gc~ETyHK|7s zeX&{Q(V?A;0)Z+H)k1)xlvZ=<;;vW1UdkT`>5Poz#LK(yl_RnI!{nnvF>R7E2F#JV zFrb~EmR_>az?Qgybk-+wRN#YFu{tgdN3PxFInBbR265`enat;if57N`jnQZT{$e2{ z-WGi%k#R|a1HkmNki5X4=HXZ-7f$~?*8*Xozx$1^;xeN7`)mjCzNd>#=bJ4csG;MA z5U9Cb{wCE-T4}YE=g3C;b4v(X(58oph6seI(4d6MojTWyE<2XR10y5LhpcQ_Vscz*AbBWS;Ld85&*Xk`4P*h^T%l!;BOG*uv-{wY<1H*Ld`9jt2u${b2{+$-yhrD?zdKPVU#QBiN2vJxK+)bx4pQPl_ z`@$90|MBTMr90iiGQ3iyd=)B8C(b(NrwCM(bwo7^WDIRvg8p)@0&Nx#|KK3ljD5mU zm7zO?6ky0ss2+%bu=X@@a0nL~;-y5D&Y}YKwY2^SwDZGMO;Gm~ZT@EBz-5igj)NfR z{u2bGrGx2|T)NVSawYyQ#4?M_hlrMG{!PYdku^4dp47q8cUfJ+yOyg1W*x+h1REgf zg!!J1H(}gv*0*oY1VgbryKM8YCvNLRUF#!j`H|&9*2-_q5VfE$qK2h@qp=b3^gKO< zO#KQQQban|E)O$_RL0=BYME+A;(RL++ zuJn{&;0KK-O+_RK6khbf+gkgVRgeC!d8)R)R#qXSWswPJ`?~ zs87?!y?r1F3LuRkow|Y_0k*T=WGvEY#eZ z0t|w=|2E#ZTOlf_wj6U>1w5`f$Nv{kUmX=?_kE9IyojKLAT2|;(v8B1bax8U-5n~@ zCEbjGbayif(%lV`LnF<=!2GVC_x=9XV(|xSW_X@w?mhRMv-jD1Jh?X|Po(&E?x;JJ zEw2oR&sOZCzEloYRUnyr#&cfNUbNrM$<+<kQ5l1W`$+_WkaWZn%{C{xv|=|lc0 z|MqOZHR1zdrblbtcf8XSXiHsP81&9#w~*dMG&X5sX$izzVwSYAixVc8tt@f=&|Qp zb~GJfg+7eR5c1!c3g{0`C*M<1K`uT-b8riXNlRq5ojN*JCCQh0WL;3gUu55D73^2! z{H96#&RZ8UHa$+4EnS^NF6KSizEI;!OQ#Nz1H$!X9#OM88aL>c-GR_fU`1!xQ;{X|0 z)U@>VP`xG@1mRBlyiEaNQKr(K4@7PzO6JP19N)Q@Mql^~8Y^*t35FvxV-*=Na@m{8 z20ew31{f|1oZTJ;63OqJjE`xSEVGN1R>l}b9Io|uyE`%qlJJa(q z#BR}F2HK39iCQO90#9C1k;4!S%^ivOFS!7va-W3c{%r{DklNeCsU~AY$U1{x_)w7UGD$Y2KDjV*G2#G zkaJ&dFDG}o!m$#@GkCTk2_ z&DI4cMW$I%+J>5l!FOVmiv1if<2#Lc%5?XS`Y)iT$NR)A*s4O-*v~QywZ1pqYe^oC zR~PuVU%?nKkPS^zd9)n_g$(xKZz45qiN0EgplPXj)L)m%kXcwDRh`>l@#8LqB1 z`?jT4YG*#Dd#-Xe!T@$V2FT!JoWC(9{4H3!<;#9ni!Ib#CbwfaCrNf+OJhrGH!fih z@JDMxX_C)8PY15ScG=!0ff7>U$wTEz<0v!cA8$`*gb)p+dK{y8Wmjt|YP z9>noU7y3}xW&%zy*T~Wo=c_GNxwIw2C2RQ(1Vz1+rt_B$ z)27M|2Dm!?-DQblYM?Cc1;%uE|E6xuj8M8ap;qHK5aViXFF_s8AUr`~yU{Lil6>2A zajh|RKO4XfRl`T_zbQ4#>l(neX2FKY4EH>aj&O6T`0&8W8nG~cQd1KW(myzRMUMN9 z7u~a^1sHnk8vzU)8%bo(@#*_XO;j5N=lO~>t#1cHC4;V@r+#-b zVh9-DXy^W3w6iS^{X`uDsDi<)2j6xsUo1yR)c%Ar@qKth@a*qFKQ_cF`grH`ubU7MhtQw9??!AcAsRj}?G1vSV~tPwk#ot%run zNVo?&pTizDS9Q+kt;+)G!~f?&bOv&k!@&Z5P(O4a|H$iSjc)JkIO||25Lq!lqs5ng z?~ojeZM)RKj+fEu!@{-e4Qt3}*E@W*j-ZtAQ;<>cJzgCw2`mQV-oyi`m$yfq(TW^K zNsQ${VWIi~5719Zi*HA-6Z@R+1h}!00*REM+G27M_qdQ%{5UX44CCTVifdO)lF0?5 zv>ZO7{bpm|4I-M5hnd7(8Ie@N)9`CV2ac(vA(&?(Wk(q~qh4B22!)6vos zC|h`}gHzTVU6+Vd{q%bzqy|jgriwWmx6Vz1J$2{JGEKyeIy2tr2H6Erkcmx?ZL(Pu zI|glHgRNi60kyTBjz^&qU4vfe-e_2&-|6XwVNwZAb{!j;=DEYoG0)eK1$}aJMUu7m z=KCkNTyCLGdkC19bK?RNHlNLsv(x+NIvgucyiuUIKoF}Eq;R{oEP?QLvl)sI_~xBf zkbL=53@vJptlLS@H+8lcEtujud@{H*%~;8WD+@%@3KSK|3%37OElQPl3DxzjtF%iV zOzNQ|J`kvYTs}}xn9ccv$P^64u9|^q!TjRJWe0M?|SQH;<7gkN4hv|UlkqNfKFp9O2b-V_$+h*-CO z(_7ox-DXX`irZ79U#qC&))jU>jplNxs*aV)Wh0$b*_WoCUQxrL3i|wS*T9$Se!}p( zUf8tXo|i`LFSAb#y}E;p8eCdT|h|FYbr=HrXAPHBw)^1g+o?;F#>3;x}AJ{|)0 ztbp&W3~ySi&q{>knbqHPzwtr{Vl`F3{^+61c=k4px`!YmBhUMU=pg3*3W%Ub-lnQ~ zpmDPsf%#3iaQz@Vzxbq=@BP-LVKOy2uK9WVDA>6YD<36cj*o1j8J+9fEf%ag&jR@nJqgAo8sO6(Q&z zNtfpz|5qCh2AahzvpJZUlICN)Zo81uQ#iES_jb3A&i?o)D0e%7e`W^MfuO1tPx+nm zPo%0+8Yad!NIH+&q?fYoFzJ8g@|9PO6b*5<<0HVN_!#D_z_j)K2Xjib3e$gOvdVM} zorv>k3CP(t4qa5&Q~qn8>|K!JCaPjf3IFGq+c7H4adHH|Fs+0iDNpEJS7$S8#K27*y=H-N=T;< zbC_cut$y-v2YS+wKXG(b>uqz{+nGBUN_a!^fdZGr7mm!PPR4Kl*V|AU;xJP8yAO~+ zQm@a9jn$!o|9vKtLoSh}Vl*97t#3layZx5!E-ey9Ne+^7Zu9?edOF3D(WG4ZUBnsF5*9~=H5Di{Qmnr zjU;2McH-nG*lR>)g62Q-??NcDC8q*G%p;KCP}%x7X_i6atL9Dzc9ynLuaPBw8N7#~ zl%*iYn#jq3M--#B5w7I59r*Eo0p(k|UOw|B7rcJmaJp>%d8gJL(=H^yG5T`BNb78t z0TCS|j6WWVp*;3)8Ty*yS)DHc245FuBurHQ_h2x1noL-~i`Of@IV1z{K1xsZJHZ`U zx^Q;OfA2)*tgni2GkP7sdJ|}y>|^A=YeT7gmn)Y;Q2Fn(4s)Vp(xHpu#2Ux0CH${T z;<6H`2=0czC21kQz(G;D@i_sz_Q=(1yWI}YKBu*G3xnI|W+&Dn|~GQB)mp`!EV)^wX^>!mS( zc@t_OPF#IIfYo&EW%W&AM(-Hj)T1e+M9BN?m}EujyO5&I?3?SCyG2oR$IkB!c6TcP zS>h(Q{H?rZhMxVaCf=6|ytC}n-KRB(GaH*zXFlgBy&2anh2w0@S5UQnc?8PX-0Xe7 zz^5$7c0Dj}U-lC|zNgAbTTAatmt8;4OtM=UD#eN4q+vW6UE_3X5=e(5$v?jM_&dH;4h?tRDPw{lmA%PvjlLG_i+^DRR1F5iFf zSOv&WnACo(RarIcMA+HS``b zXTF2xQ|1mWJxl0jZyLxg%5g)y{b|^K|F|P5s^YdVBNT;e^S#@xc4hFudN#X>G75k^ z4YY&KbEwS#D2NxvnR>@QFT-M^wV94lvhw$RZ0k-j z+w3ar(y*6anw@`h(i#O5{cUhitroACC zO`**4$&!MB&r8X0iP}Y1i4TF^cC@)>Qd5!D%6dxCVrHlsQ8`v>hzx_*AJLni*QX*} z6mwH!npMwF=G*RShh+F3mULsHUmjbwwSw6-`zuH7e0Q{u z`6lnDHgc&j=FzL4CZbK`q40x9zwIOeZ_SB)^|C5Q!AUMH!FHV&@lzQ)u&>O18%eWG zd2J|N&!H4#a@sJ14L_OxU>XNDf9%*VMKMzg>q?#J3HU*V+mQea>7q+Nix*=Eb?Xj% zBg`Jo^h21!`|I%^i3idBI_Gh&-AxZP4UYW9o;&Z#&jlh-nP|2qPw#9F4%c2DWJ*30 zl)JUQGoEr&+Hw^ujm9`OP=$$UWEhuNvI$>spCRnbO09Re(k#cOdcd*_&?Qma zHp;ZltiIB6v3+0g{$bmnbg_L{PvCX-{50=ZQ!9|iMq%O!uzm-nj#6sMKX~C%I_s=C zgbpmIL>h<;vDEs*s9TnZ!k;S^S+z!=OKm**Nv|%JaybOZ$HB8YPTTA2SA!H8N>8i7 zoRM^BRJGa$W>n8TWs}b#A-p%kLw(5-P%?%&o@=@nFPMdxkYSkE-U)2#=O~>T3Jm!yzgs zO5;u^MFL}(G!fqDl=L}R#1I|cb~6WA0t!l5q%o_*^=3VIuxHKRSRqdJ8*C(Y2?Wf8 zP7xslI;o7;t@94Neusm!n`dPtxN;{{o+4xCL)8dcD#31wLlje8Ax%zR@W%2 z0Ry8iXCVgaSE}6C;)-=QDjPerpR$6JTSWDkN$xe&*6Mi={JKjl+%qPgK9TCcqHq#~ z-pFZ7|BOh4Q~ccdEM(gj#tpGj*I%9tatBX!^<-i>Scj<*0j2*Zv_~mva3PT(rd2@G zFgPQV4lANBagxBut~3Y#?Y1^PHjRQr`5|A^t6l;3TWI_bVnm;#)-MpGX|stY;TP(T z8_!@NI%?zghTZQ+KP4*~eg3g!!$+2R+)0)|OAB$IKP=U3A+HT(>hMo3VE%g*XCWbOinlGg1*T=<@ zRD-Or${+h_%a0J669Z2A8(~A8GW{F6Ttudq@BBDk#V{V0Omsz%B``jUB>tO0ybe>I z=#2q*PCOzaCwV3CfhpB9?%zFxQifNioaO#x#*=k*ZK!5ZU6zemD4pyJeV)F}-uxc{ z^>L}{xVZBqR`rt z*mCcDd6dvFmho>A9tyMTdpOCa;JZd{1;&P+_Slp6Pl5 zUw%F6So=cMwa|wvb6;|vejeQLTLYJDDUD6AOWCWj)W8zMI17~xBl3?|kWpD7-RCmZ z=~Nc-Ff`38l#&V3nk{|`0oQ^0nJE5B4W2)fBBa}8~tnY*4z)edeljiM|poihc1zK&6XR$3P-0cnB*OS%#I+?iUGy-M4qU38f zp@!qIVLhn6$I!CVt54E*hD4>A)Tp^!Aqrv&SW(aLN2h!C#-mk37&V_^7RKkDbGz3} zG@(WHd6ihRmsyQKPpCiNO-f*kT{@Nq!fV7R$K z>|=&g-nLFK`lpUw&OH4#W_F+WUf{1sVu4si%)Zzn6@fdanro`cm=)0a?xQ=&8?T_f3QNVw6v3YIS4PEOZE$J zjIQnI^?fp#W0X`=q+GMwJ$LuBAHuO)$THr4e?9TP~ zSv)PJg|T!@%MZI}qRcXO5jDBSb6WQ$&A~w%YO%qXM%9b}D{rumMve0XqFm^G=8~Q7=)_k70eqEF;rJ=Wu;ekDX&Ky1Q95 zF-Zr3VtVn1wr~74k0}ISp1RI(U28oZJ^oNB{_2Q}PVPG1ZCPWcBdYt9#8G)$haqB- zi~M$aa$r=2<)z?!uZlHDwKK*kj>)S%c|>M?h1M>NrpCQf04>)Si-2F(635cC#Wl8d zZ>=HX*p`dqphLzyFneR+#e9`Hf@XGs3ePgH7wM8MUgl zS8S?RJUoK%8G+#kN}k8j1BrvGZM{#%yJQ$+r`)CmIHxP^RfTDYFfcxaY_b6csDpws zn}#?itkW2814_?I6#ktyT=9_?bplna^%tsT6(=d9cOS#nj=CejLTB3g>mTrXv22Af zA`YP|hC5K4`hW#p?*wPx(q?AeJR^gL*y($}Pt$mv;@HM`@1xW9kSts<^L*K^AotP1 zlz+>zrbj-9`qR6N4dI#&*5w2GaLzS{%E>nYU+De`EpWxbBm`)lMN>A9s|F{#^3^mK zD&ignDUB}U5PsPG*=*JlEvV9VhT)1huK*!(0vBp!6f(=*kXTY;CmSqj*Mg_V) zVg5P`94(nFnDRaHZ_@2+U%>gWIeDf8ZdYluuj~=KY%R;jb0&;$o0lZB(w5qg%6P21 z1CN0v0GOu}KCOR&FMDrxl{Jf>jYi0TanngF?}1>Dm+&)oarMg23qJ9EGBT?*y1yTS z+CJ69O)Px&hE)j{e6~S?&eTUGObqU~CgQ1TGEs>^8&!vQ*@FisO?P*#dU1yUk=Zgu zT-W)gs_!3e>o<+Rd;iB7-5{cTgpHBP!lt@KoM`f`qq_cO!3z;CppM{;jVVG=X6T{f zmH3n)q+J{b{2R~;Ztziq@2U||pJ8CQb`B3HtYQn3%gsDH%p&NznhR=bso-x@W9AuA zf8(5Bf5xOXixb>8Y|O0v^j~%a_ykhvenR@A>hzMwv(L_AQf+wqXXhAWI2gCR$TvzC zl>XN{+L2Dl|3PG=!CX=sLxM;nK?r^KALeAu{WVfQU}e&U%@2cMPW^%nC*`-T&79?~E;V2X3j8#? z*i3%cUyg{7+bhI)OO*1}>_eWR(XJipBDt%IcQRZ?N>d+}Q{;sqGb=2W`y0PQ0Tj>} zN_K=h`HjaDce=yG>bG<>&Wq;VkaO_Rp02rLpqHGmuu30A()FDT*5;FezD|{{_G@<7 zAj0$XYGBiTNpNj68x|^id2+Z2V0Fy`Mc;$t(#ZJ>^F)&ZO+m1TRG3J%PbwI=BF<{* z@R`K8bOX(US7D+PME|h~iEJtM1BB3h5hpmemmZU`p2rlOI20qhlL6sa)S@wlh6}Au zCCWE*1Ai#>=ghm1UH9Q-JL=nKIsITCaU5g-?M$oXJS6eqyyYm2a#?V(QeSq~r-XGd z`f!=_a>dB$(i_I0>7Q}N72JVzloxM@XrLN5s>{Xjcx?5eL-@&uP=@raE&kL3sGE5( zGFq-@VhWTp;fCex_Amqae~udc4qlH-o+VGQqsfFyegqDs3Py#XFhA?MQ8qZvXSP06 zd`v2U-0R$ha(`3gGb4W}lvcW%t zogEzX)6wCzAbYJdGQ79Y&gZ0Ce0EBRxmipKFI?}lO%blFw#=o_8{Ngl^w0uHp7Pp$ zVwdd^9Yw{Yke#WbwhNe8@q~3!pW^uVc&q=}m+(C`i?79_!50Ck zq}65Iv~&z}@F-W>2>q88ZiUB4C}7Gs@r6$LNb76HV(uYhvkVUW!9Bdukx#85Jv}4u zSJIiFE?buZ(Wz`AR&}T6p5-|?ttKn1$l`N=;)6YAfWA`WK;cUsrGvav*`2}g$v z$jR$)+e$&TDbrTO*FXd{^5rr+k*?aJWro+ND>0 zHd5?vxE>sl-X<)hd#1?M=y7t?MxYr_qN*EC^R%cWNNpRmnZ5J=>yv&uj%kl5Uo|{A zrxf%&Tp0&K&jjY|1Ti_S6nH!(hVu&p@gcVh4FMsSmfPOAnJ==1}STay%pL?ERSB{QbA-V%=a^(7CCko1@zcNZ$D`v1VL@R>xtn7ap7C zvKwOYp96su=3TyDafqdk?!o6bCwpBuySO{^t@^uWP!l^dD~ms^2RDnsithVjiJ6&r z#IOQw@83bT-e6y<56gDfJ)xSZ*6p71FV{XjNv4Ln02$zsKT?n#5uYl+!&%lux4KTR zBrXOuPgwEU%>kZVlMOxCjJ?i@Aii{G=@i$sO707K$Uu6TwDM;A6VfhHQd)dYGDGZ^ zyg31RCrQV4x9&j5_qOljH>JPIj`XU&0U>keq>})Wg6K4R)`NdzmJ$52gATtp$o4wb zon!}4donb9>4&vb`-VMP?{jTdU{xQA`YicRxBx2GRYWpAK=^fgciky*$VGCTI@kd$ zOv2^*Y502Blc)!XDZTk%reV7>)Wl@<`_+~RB?j=ctmjspXFK&d(`wqtzpsO9i$9&*8om6 zInvRF8y%NWTJ$j>cZ?v+tMIA3S_871AA(gD15Vm+kT0Zk9x5 zrD$V&wq`WTmv7ouIp}$kxqMgmwg~|F!D(=6b~LlF9FLT!_pvAXC_ENh#PznwM+vfK zVXxb4#sli_-=S*Ei#6xb)HmKQEfq3{onscwtP{b5L<9ZYE1*O@*K#QGMj?%V6(;g7 zbZfMFTH+dEbHl=S$VEdix*g89N)R_hG1q6a#g5tKe~dFSwaHVUx^}|=2SfpS`rLsG zUJc$3SKaeA&x=q`->qMPKug-WF+C4ww~K+6lHctBm7x2CoeGGLS?a;3sx|FH3jk$E zU3k%7Zv_zB4#m8pLaa23_YhP*>l3*^1!O@04(lE_wmRr$pv6ghnYNvIvXn#Y>z{hH zx9Mn0d5B7w&!Hb?$e!aVvN)+3GH7x=INs-acx$)Vl7&Lu-2DtRI|dbH`FLK{)z5$c3CY5QeueAW!%hd_`JS ziOZIKPf?Q@s`Oow1L*+Sryn$cJT)PR$qm%L){qAq$mwS2LtdMlvC5bD@J6gAD?N4xQ~ES$qyQj^o0j8AR@$0f^_ynvqH`pQW? zP&=uvjRUH&mGxyRKoe?`D8%n z{o*)9_aX!9pV0T!vk7{83{hM1P?~&>!|BqqpQ_V(={DU@_P4h;lVelscDHh8E}>ac z!Y%gsO+3P(jIRX1g4|zGt{fzr0v->VelUIA@U-+qb<|17>Lzob?QnL`zG0sy4lcW{ za#Pm8|7P5B38cXrWpSpt#6G>rTE@SVWS{aG6Avp;e7XEnV5+*Do-p1`^F>IRsVUOm zn(yFiWQXwEx64g3xjLmm5t%y(Dk-SGV4XpeMdGKnrA`0yDZ9B`m3@t>BZ&^0w~!bg zDdp;>q*!d6$B%Guu^6(mFunQ}tE_rk2p-nmRy%r1N^aVp zd*x$bqos`1-2TI19bVgtv*FHxOKWs;tLIs}o;9#n;E1y$pQ}8-%?;qNgVoe=qc1!C zhgZg-zxJ*<4B&>s?oKno-ry)U!cX^(Hh4M;3{FA|fHbK)#~vK8C&S)y`K1WYwJ*?4 zLlVmtyA);Z$G)8hGZ4d;1z)+ggTQ}|sAK)~{{11loWjw1C)r=x;fI}%fH?4qOSZyg zUjuUG{XeDW#nuYAb2AZEXs@n2Ma&>_jTo&B2yAVQ$iptvzY3}kAx*A_(voIGc>3@Y zDdq&7T%^KSpw8^W9(-;fuQ6#$rjF#%FvS5$*Bwx-)8{BX@{wY_L^zh_| zwVr?UoaTGsg6?{&+I_n0z8VHLPR|{EF#pb;&Kv8=Cra%(e1$9}oxc4|#{XgA<1@Gd z`AF;jZ1Iz0-KNTz+f7q0;^F7DCq01?a(D0ozr1_0wX}J-!S!JkKl1S@FG|#P(LPS> z>VD@hIzMcOYQ@{;mN%u$3>=Hp*{uv^{Ij~{+WeMhpJCDItv@G3kXyvU2t-y|;*iJL zdAPp=)K8W}0VfK-*!d?jvYPU46oigAMBr}?sJ6SYTQ5iPXfum8=)o0D&?$9x_prgU zb8WJ6U(u(^2;5SNecRB2BF)@l^Yi`r%1l7pAysD~Q1&o6Er*vM-H^`ID2pIjEa}Zt z_|3Gy>xD%YcuQ|2kb!oKo*#kkcUk?1@jlYY7QpzND%YDR*Cd9_`LEZgF`pH!D?p=R zZ8|5@=OC#PtSw4__3zn>Bvkk{v>GkN+H;QNIHwt5dL=(6V@u{4?fsb;vea@d2Yr&+ z0)fy-1c23Ey4Z3J7Jrvy5ct*rBQI87$V>|k1O@<$64STUlHlFmQcJc%Br~WV4+VTu zx953;Ax%GOfi%4Uo@W!V7Mb~&a|s zUr3YJE;XKhi(3-#(hvf2LK_|C@PcH1`j;Trxq$f}8p%XsQ9O6!)u^VAaaYuq%*rXJE~yoE*44~?fu&whH1POmuNFn?Qj-l?G9_b zjvp6L=+?lQwQ)P^vuhF*_S2CpE1cskA6DbrT`YX-WHmPmOm^Bl$m0CHD}!8%@M9`t zK2-;l8op=56PVHV^yDXqsm;|+s*`75^zymfi(H?m=}Go5i#^y+!&C0>ss$=xAzL~2 zO7(8?AtCvl`t=@eiiEmQzE3N_vb;!30Y__6Ocab)p_)EG*&$=>R{2v(#Y++2M%>P zTv3gYqHXrpY#Ct_IiDC6x+-cl}@VBM2j=~<@i7iT02-&olsC#8HwNiw*ACKv_uM=D`YCb5$rUtelt zKBb|-oc+^1ygZ=YvRQ4YutpaKe_m$SuSgVI5Ct@~+&rYFmk-}3tTh~um7zNz~MNQM%H(+O;3x_vSv#M2m;C`Ann603=QBn7Umx&!TtnI1NhDF zzlQ`~t>tLL;|q2$@Bfu;b7%8rtvasN6$nbb&@H$r#qW;1=CIN%{+^$s-<*p09^>m2 zIlR)d*>QEW#bB*-bbYlLxuaIPxxKTpEQnGs!l=SD63)OBHOZT`aa#(K)vm*j=G=$ zxbVB76MeOfzwwS|fL=`qF(xhOb|55p2Gc7SuYA(AuEO|6aGl z`3JR;_R0~{7GJ%Bq6RjW^JDiiU|)ep|oZn!&9W_q>Up$)*2%FGyv2e4h+3 zZ&P_J)l^2X|9Xy{^{-7Sym&6`wrLLkk#*C&EZEG)v=x|?Ull!VS`^u1ZZyE$$UjTW zU)q*=5VQfm66S}4lYg8(>LnjnXjrIjwPg~DpJ+2r?kp^%Cp}RpX0%dHfL~~iK)Jlk z7Emrf{WJo~d5hkt&mj-awq>Az*fnrD+7`Vo`}@TC?eN6bbTt7Um@+s8N2ujC$xxJA z$V=U6d~CJOZYkvNKn9?heY5Nk1O#&$$YDLzvfrgRRE*by zNnTJVy#xh&W^8M;v$4`*)Lr>)L<-`ybF(s5+HFQJSzGK4EcWn;NF<={l-|p}$AZJX z0_0I8%`kMARSb}7FH!Ei$tlmCa!#@rqt5>N#{&N2<&$ajDg1ypdTx?ACH47( z_2q%@I;Qo-?l3%M54DBUPO|Di$cC)s3qnh4N1lTSr7Mxx#9~tN<5{R*mZYEb!(R2R z-&M-de;bYRy3l^)|=OEoI3C3ekbP)RLF9|aDX$mF`4J8!7( zv&TE0ubx#Cmm`p%*fhSTl-LN~6Lru#Zvw58w=91K_zmgm--f1g`dtF@r{mhe+6n<8 z0&V#X$Z;M>2tC~kY^_jlo&$`4EA^U4n-PWZkE1R zN`SIKyn}|Absh+Xzw+O_2Uwwc;n=v5z-a14Hj;}$a7G)b=3{H{YT_U$7JB0gv;WCIY2VsNdfO7A+Xw3RX0r&Hm}zyeXj5;l%@_A3az1 zCW#_(7+h>- zf5R}%{k5Aq=h`PanU?dMX|COuJl9uSp3OIq4}rYVBM^%f*dt4N2~Q?)hXa~f*kCzt zaFhBequ8ByG2=K$V4M0koT)tx_scQAm)Q)U+1&#e~}l~Q?A zLoFu0{fit#eqTVvA01Bu#z4dC_ak&BTNByRZ(-iz*e9UlqIOdB%cX3#L^(qgnEQ-Q zV0Ca9G@l%W!!>i*Ym2;nQF}1Dr!JPutKEPB4#Z}Gy_tAc!S0VEJN76rjq__2_~6XX z>j=!v1KU%@?0@L9ml5(YwLaVPtsO{~ z`jm$a=le^aNGwbW;8sT*aR}DG8ky&<-TdSVfIbgGT@SS{VF`Y4$M$mdIQV;Vlm|>~X}mL+!+x8JNOoaaSQHV1 zK|w(@rHKAMQ_e}j=6JSpDN*EYoa?P1(tF_OaISG6Ji~wJ`e?CkaHrN*L(y-}GtT)P z?KK}8B>S9gr$4BHf38fQTe^VjI=y9R(Skb^otY3m;ih*MXk2V`?XR* zWNjyCg4n0emJZmW0I3_HKxS=Y@&{0#!3f>4hfbOXTQaXBv}{x_gTf9rzg(tHkeR5V zCZ`7)z|s3lFAEfjXaCWktLNtBd>Z--j3v3(yH%}7T)T_4At&w-#3TV^Hkbht^YvCvm&>kk-8dhXYO5=Ylqch){gZcS zZQIVg$I49Csut%xb;#Lpn;}$5$Fwn0H4QeD^;>t|bqX9-;Kw2XKFgSIj1}GqVd`a0 zAv_gl7Ned1N31P({cC&F3o1!MhQ+TjlWVW({^Ep;$7kApYmBq^bo_eir%O=FSHsqU zG!@6>;|Ob$`Z5vbIk%dcmt@!D->zJ(LBqC~?=VBuoo?6+*Yvq9ieD+E?Sw>TYLhYR z_4kWEy%$t)a=vUdOct>ka;I<2+$7)3WM23AH%628wK2KJ9uJxV?XsN^xrX~PZpejE z*^_2x^wE+SdU^~(i}C2-D53E}Q&_>%B0GD|C18E7=v&s`74=$xh#1!3)giXiXxHfU zu#>o{%6%g)3SdWLd&!uu=^meXSf;ecyL_r_O~u1&1gL|R zER^WKx)fBeYAPlU^J8#FePWO9G)BIo*G=0|ues$1kGoQu#Es|yvmD=qK!TDfROvtw zLxF~v|8Y9~bzCQ%h&c!N37_&^R#Qmz6x1ky{Rg+%auYiTMGRYT{lxK_f%raL58o7W8|+JjP8^@BOK^sK7_6 zeETdrGz`iJRyfnuv7e((m3lDs!T1zjOjKmtc!=k1ni&(=TkeFV}b#|Jb`eHL1I`|D9UZH!x-0*5Qx)2uss1762vH zvs-`2j@#m))EF2~V@exE#kho6+2v^yEvy|~JjiX?%5bAQHsXT`3Zz(j`-rf=WS7`f zzR)e{G)*J5vOeHa?Gt{;guWB}LU00s(AfS&l_Ewny#La6WT`~j9Ku;NTawJBxRIZK z>`a+>yR}{H`%ZyCc^@b$;%vRLvJfMW08I6$c(vOKN3KT+c2AW%ns}65Fn%a`p5e?c zD1~BjXJoMtD6HEI7B#Tym>CBAz*aF0+gmWpIa5eFSss{; znZP2x|3vNi9gMT?@zp;y{6P)P%7lhA<`Y&}mBTZlr>FU$BW-cdz zXQcDWRg`>xvF00wF$^Vzl56k!&+ZfyHV@CXb?$_3SikQ9hy5d=gtkmO0BlyOe&U=? zW&Gl#c)P-cH0-XD->t3O;hq?&j;gDrk4BT$D;Rt$KjGy2Gk*+OIbq}b?K`6d%vh~e`K%VP9=tWvxHHqJQ%Cm4(GUGS zsh)6vz!!n}Ix|1W*qneBQg~IO*ts(^;5cJb57WetVH7#*D8C^T7Jpm2iK@%{2flX) z<6~Zf>qVtXKDBomJSe@+3TyiAD%@HIOc3xD|_#! zYn1i(oWaH(NUMiIay~qZR?XL#+$T!}5vDH)xIhDQxa?D)M}Sh~5aS@BzUJEQj0CsD zHh<0l1}c?A!61u%fCR0w6*ut4jT9ROAg9;wcQ9$&M{<1YDNVd;Ka0YCMV=!V2B=%P-S22`K$VD)#B{Ss6YJk~^Ob*B4J23eXj~3;3 z*&@&?`Hv>mfM=%W)QptXHYrDcj(YI?yHJQ+f1=|8F3a!B7%++0$F}GeBABAIFoEKCAkz<$`jEc0ecl`ta_9D*oMqB?)_R~Jt zw|#7?Iv$_7{_XMAtoC(&2xoy>^H@3?BMHV2rX1mWU zEe4}X)&|yJI|&B!z83bpmHf$Xzw8feyFl78wjeI* zciuOD0i(&z?x6Vqf#eY2$7N9Lv$75_H#gVWELDK9HQ*wX+ad!-$bp3M%^ulP5()wW zGAcrRN@5r&(~PW)O^l8A)O%Z9PlDLecqUGH|LpvE1wM@(Secwn`Of++75J47?dvF{ zyv%ON#IRfT_d;GR7T5oUxA0;>r@uH4harkmC0|3mlK@~xRKQy3yd$aNPft&B1Nc4i zhY{$V1D_2V8VPgnW}-pT8vDh8uDb)uH!tR~JV*J9)f~>-0VlOA=#un!K+9zi# z<@>wzg=&~@R8@}3c>2-e)M8DE34lBkUh&M?pkl^`U6Zws-GPbG>SI{Cb-Z6NX>NODv~ltdcbn$g zx&1T{=trx4on9}BJ3egtkXC;f9V)BTLYfnFp2lM;$F$&g??LdsfXnd_m`;VknYsL~ zr{ue%$tUVeC^`9T|SkkM12AgXF){E@Qhs|sc zDvSA|-XoFaev^(V5#Yiyd{SX*VevIFvF!aD*-b?lx1APV-SKzraK%h`-uo{rnBF(F zR#~ymEPu${k7nSJWD{lvzzaknx$Vzlw=g@Owc1&W^O2IDdvr7C&|hpJ$BFIZwR3fN ziXzCz%zu4b>WgSWj1+pp%Lfk^dD+NdGtC0iZS^+$%T(}7mP}i4cx(BVK_~>*BbjHT)oK_;RAiq z>~$w~^%oJK6>xKdI4ruN#~;mPEB1D=Ohf37RvrO%2560UTEn9IN^}?JCUy9%xexL` zB@&r+E(?GiQROo#hookiMxRXAwLUVNsrT*{OF~7B^Y{y% zLBfKJ7)6i$7vW$uzmi{w8gl|VV?Ve)o~ozsM1QkW7hM1tnZF-=d)#|B3dL?(jPiRq zh_)RIPXneuKr*?&tXihJ{;%dXQO|?Euuk}6vXSa9Q*6xicKcoaPcrxo3kvNPy`6TK;sE+G zbh%tmMxl%Fa({hTCOd5hbTp9inX!Fv^krb|&rdBNg0N6#nNOd4E`3k<)yFGY_OgHgsT08)y*3sOZu6LR@#75K` z)-TsD^P$v0cP>H_vV7mV^fFFZCGFy^LH#d&f1(OegeQPbsi zH9w~p4USIh!(N}VN@wqGbnXzW4fkY>N< zFk?9RDbFutk8f^pd1U)-zZkAYOm_B+4)hJtRR0-TUw7C-E*5z^>Dl%Pxbhun5r>eP@#soS;mI&SJ}~1;*jKD8SGS1%V^~BhTNk z;w<`VPS?gKJ(lX^cj>5)+RdM1mPtKQBp`54CO345U1H7!o6#wH#kxsQ1mj=3d9TJ) zPi3zspH|XbLHxWZudv06sPcabOLvQLVk<%OLvv6tNVC2{jPUnIMg8j+l9*p7E$%+^ z-0TA8vp}Ozkn>b->Ai?pBVy7XH`qhv0-xGi_<1pqe=XHfVg?~pr%{e-(S}xmxCD%s zS^`mJ8Hd@j%jvpJ_a@L90wC)<-v|)3AvEqu%$`sY>ilXwp;^5ImfS0&m6yga8U|9Y zd55m7GXD*w5$C5PyIuiOLDw7F4F@Hvf6d8REDl_|lOeZvdy+-|y5Be3hBAR}E$R(Q z>~1ewjn`%JtK(WNFfpfSH7u)L>M!$dj$kXuf4b6T;9;gVn98aLO(^It@a67YNq{PL zk5g9;Y?2pf572K%@6GK>Y&YlP2Zew50m~>>e?@}K<5VFJ;$zf;F4sx-n|Y8lek>|o z%tXwQap8WDG$E)kQn8mab7%bu%65NhOFzdEDT(_cFc|(CYl;ulP2Dn_{-Rnk%I9#x zk2uBe#pTE-GN^4{;NAt%T}Z|hy*!#~`xht~pKMf{ay}Op)bqQY=e)}N1@)xn!%GNM zaqw`c;>duh_lIKW!<*@xZ_+!9c?<~!1cxp+$mbKn0^~~RyDWOii-cj!TFYX>NZ7QC<)=9ZAD%cmOD_C44^;*!{K2ZFF4iHU-@YnnA18 z1#F9Rl5wU4X=C9mk+7SenBx7u8;PoZcjsMlMXOdn)zITuX|{G ze9#ay3;q6Tni5Iq(?FiV<#DL|Vm z)|_%z+@4WSyZ3-<3z+n;rppyt@q%CrcCkDBwYI0y{ag5w;yPNZE87%WK@EE@*Oc00 z=vDtMd@5o$36JwZMr7>?l(U0Ig<+5vE(20(leoCF>`MTQvgNXJ5=@Qxd|jE_Jm%cT z?^Ni7JRpd^Z*qDxerU=rSk?rF19}dsb62aypRm57;rn;%pvZ#e2P#7tKbkg50acuc zjTb#uZm_)C7-$ogkP5bp)tJ|6<6+AL#}T=8&WQ5IwfnV2+8ZB4 zt~+B!tyV#|b7z#;#`{&JVZ4V2Sn3maFy%GJ#xr$IYSL>w@Cnbku^pl%S&Gj+Jc{*8(5N@CP?5WPehz4b!k;q}UFW*@OfV{-VOM z$>UhizI%Yh2+zeX93(wN*OD_b3Ia<~<0+fZ?R*DBKf0RVTbv%n6szZL<~_C~gLTG)vc}2gOhzA3O*&6zTM$m2d189obh8_Uo`~0?bcK`WOE}rjh8|! zEzGnV+JA+#T1yucgbI0V+5>T?X+ZTgOp{$nF)3d4DMBCrJ)he~AbJHdP0gokkF&dN zzfrA1<$UkPpH!eBc5lnnom^Aqg+YFd7#CV78^ zzN8zArz^581)dRmn3Z?jZQ-RoY`Vya|8~o*Z{#uVBEQ}=Dvk2c&(sAnHfrg%b{UD+ z)uL7SrVv{@`@QAjFNKC50J#p-5Kw?L!Mj&W=|KTbiPpp%N z&_ep<_x*|l80?la_t`vmdV`rKlh4VKH-8VWGuZ@lBGIG1q&(anWz@lT0nih4839{F z>8k8hetJZ@J0}J|DaGt?*ahjRW)%%vlP8QipqrZ;9gfBt>T~^q5`*-#fBgVe>t;RE zIw={bPFOeA&TalY*bi3cQjZu#%HIL{O+kzs^ba&S=tA)+7Rm@VFnwkCg|BSncTNh+ zo~Jh1u{6{^lHf0QZyc8D1jwc{pIhGUNuU{2LW4rYa7Vj0-rvj_!Gf!Z#;FHyR3eQC z6uaZhR=RsEwqliqsEr zQN0@V()e?T6E7nNk)yoZ=TXIXLHKjgKwpQ?p&VOWTG;)B^EV0wcd)j0Y`1KliVZ!1 z2TPS%hWtQFC36D?KihbD75bG$rMklJn`;bUvCn=tlzJBA z^_X$zodrsDjNCa*)sCeHZS1zH*E`Addv0cQ2(VmV+qyU$epe!@?BiS3Fi|KzI?^xA z&KCYE)=v#+U~4Wjl7or#==%5oucYmlO{}LXTLYmOpm3yW`Es~gC?U4wzMBuyEHHQ= z-&QSVsiQ(7x`)1bZz_40jL_(*NQea z(6pMIXTfi!!rU4&-r5oee4TLU(uYQyDU^S%op%cUK0Wxyzk?(L-W9u-s8u?V&;1UG zJK}RJVsV4*PsO!L%TdjS`i)vG&<9)mr%@kBA||m)X;0+zyDcjVoVH~R+A^>Y<5xM) z$IfjA6mGG{3NMGK^=Rw42a%p|u`gz0mO<sMs-r(`26jP!)NsdLGWx!1 zF=QAhBg*6Wv~&VRi7xnazxPTBXa(b$eAywGqt9IpiDEVl6ISTOP|0&wE%x4;3#J$`RieA#<{w1m(wdh;JlsS zu<-+a;hOT8$1MSv%uhhULV`Qi=;^t+@H)?XSVxt@;W;|Kyqqs80WX?Q^#RrX55Zhu zpvIi8gEj&MYKA|RXf2hfgTrjIM-t-&l*K6`a=`B6dYHjKb1||vbVx~bN3~`*cw2SFQnXH+ z%fS`trfPn(YvrmaDep&-k2TSkmf?GZ6{ALq-DM1+kAYJi{LtLQLg*$?3NC7Y{(Hq3fx)Xe4U&BG5K=TgsaM_D>G6d%KLqiPgK9JKLzn>HKS_uSBKBkZh2c8}eh% zp#xEw9=s-3Ig;LjjAzi_=L40Zyh4NR=&%Frjp#NVkN2rJdSyZPI5eBK~| zVmx7T0~xIc-J}-Xetc_=O~<;^Eq)*7PA#Uvoul$)GK7F&DSX@F z5><}b)yJFqO_v$2QO=3komb26=588N);mLku|w^ceVKgHy`sPMWyrWAKYB|O*dI?e zjQd2-qu)X;mLrIXi)FGI(hG@7DW?0`Wg>7W#i(J0>Nvo@d1_i(Nr`p&!PziZqjPT` zi$R7!O-1+nG^X7vCPwMIXIOFwMiHLJ^w8%r+i)n-)4TKlIJNKNA6c9^5yJl;&>ko1A~~Bs-QSaM)u0*uw4?E0vsyg*4<5IZ31(}$@$&Ou`Y?w97}H42?@>+ zNo{Mn;i+J^^}VqfQ~!V&Jok1U)c}2*!5`u?Zng^YVEnYDfVy$AVxuAMToA4U0^afc^gJ%3F~P zEY+0N=5YLz*sI~$$CqrV5{66sB6TGOidpJ*pB#JpCnKKNQV`&vxrO2?Tq6w#`L7K&3gD6K^_^gb{ zCOGvc-ADef(*87uAoR)aopS%Z!o)f@F)pV(&HiWNlX0iGu^zr7u};JV>$1D-YUA+W zAnheWkm(^V70q{HW3TG_DU>Y8`}2t!eQzlJwA@to$)~4j7i<;`#pnBkBFmp$_78Q| z{puGIY7K4ckXD>8>#`nAhx4j&N8GkBqzOHyt4MRKb4^|uU0bQxZ$epz8*8Xu3m3`$ zPWovy`Z*H^WES7wZW4A`C#tEgcsvA}?_aiGX$VP4JuBbl=21y~-1lT6dp{`6wmO~w znraRW4wqNXc^vUE_mWrJeUL2|OE5t{lCvTn9UgEMNvw7M;mpu&>(BH9?(7`g*n7ru zw(vEd+{gFWeuW(868L5fJ!5)*1_EtrCIR^)OZFTkYG*4BH0~>oS!ezxL zn=>1h?bvBnR{O}{y?5eJ*&jjx)r5?xIL%I+F6;J^on`plWcd@^@nVaGzH!@vD{g$` zG8X9-zY0z1kqC50<_5F1N?iOE^}E=#A|^sT69u)|vF-G~KJooaUC5bvLq|=gf|JZ| zHUC-*a_1%z1$x*e>W|#?tMg5CoADx;-CDoI9cmSrn*0$eyU87jTBB?IMo&sEBl86&5Otv$G10*n3FeD89i= ztoTG@Y>B$E)z%PeGie*@db?3~!s81)-&6?;3>OoW5$}hMSmk9`6GXv?<57r1wY4$Z znyKtgSu!TR!beK9H^$`&b=a6lNofeucs4J65*7;$4Xwa1os04E-xKtOalu0k6)w{- zyYuJ@j42S1wMwe$`c)?t`6FIBy=vOAj$10Y-0+CVt1}@%&42sht!u}P{{GKPtXRvk za+cA!0-1yI;NH-VyzCOmap7t<1!ikfJ=B+PsRn7e%CcnT$9Xw5_H`e`hw16J9C>lw z!Y9$bkm{B}=inX6UJ(0Ka&WfCr1w2gP<@KoFLs$qZ*itlY27^ktGWaA9y6*X#giCf z(UG63s;XvkvYqAZwN++6FHw#6lW|&=P6ivqd;Bk5NAWwnoW=N7(>t5ww|Egg@$Xzl zS#P|$R0s?JaHKZFC8@rj@$=RnCg^z-y*!Hh*1Px;-3*bkYtix&p5;~ z3bSXzd@E~vSdgYU+1%eFlEwrPsKq7*{mFvV{rJ-~FEZEy+h^bH?+`Tla>U>04wKR( zSMdir&ijrxPh>ofuMNkmA4}8v7@4}9o*BBucAn47x#7WVgD!V}9h;^VVQ({-&(Vw4 zw8_^`s+qo2uEYsWMuM7Fj%HaSsMRsEkc`DzT&6yxiq zIJiTw&}>CElN28x;i{vAxl?eE&|dsW1!txQvy}5i)A9-S+Gr=|oJD z>)ge}*{~!y>Iad$ZEM(%=1|{-^HwXPmv!^VERV#`bUAodHde@&w7-!r5Z<4#hJLY= zGKb5-Q-H;*Y<*ZnN5a~Fq%UkUDb0vv(KIgpTqGx^!hPQ%DT#iif=Q91!@j1VphTIQ zm7Qbs@)RAf{C#SEJ^-19np#F`)aw?Go4-7GN*X-jyFdmSTKZ7>@81=~-HnlT^%R7J zp#`Hq@QNnv!%9n-!txVH@_Kx^0Uhjcsm!UOU_5_sG79=%UF|O22G{jbckXs(7Z{2v z_bDs980`qow!?R}fk*!ERFz&@hctICFPV#T1&8ruX=#H@IixW*F)^naw{+nut!|g9 zrncx@YVLl`fb8NiV8$ENT7Yluu3u7Ij5lyokY9W%ubgREvA+4*e;DGSV74(<$4-zA zY_zbT{2Qtgrs2^VX>&vjIw^CUf`ZT_L>qQiCYsEb4>iTFqd9r`JUr)VY~L4{WN{&6 zhP1k7bXD618%bvynDMbUMBVurIHgr}GXnX1T~ph23kytJyoL3Wru94q1Y3t&zlJH& z@aI|ne7YiUa^SgnL02?zij>9n^*l&t|Md|b%PROIh=S5GjOuNVLmePf+ZvcZojLN| z;5NM66LhWQEB{dEaJ^yvSJn_8|QZ*xZL3}AL^&|mbE}8-e2=toAkcWwIahqk3#zQ zm2FIr@9}>CH_JHae{^{|F#l(6S4nX;snHtNmJ7MegZl|@Z0zbvud8#|SYR1>Gb)UD z)mieZphx#r#JuTq7233SzZs^ z_E7dB<;d#ZZBbl&fYtE@^i$N^ARJO~6iU|x^JsN|)Xaqn(Qk8S17iChSqs4=2|=0p zoLsMxs9Aqa#e7fcJ9OPBlY}*#F_n)u291G%VNZr=B};6@y#BdKH+2%qg;sv`_G_}Q z`!nY9*j(3>$E%0Vdb!jveU~@JmcBFZH8w@;bI{>Z7+QKs;#U=#45hM!BD@#kL z@bXPSMI-H0YyF5#>=H)Cr;bnF#hEreb<^7xk*MXp%!7;vig5s|T8F~sdKf*SFEnDb zYe)WRY|QVzQ_vgG{6#7I=4KodFFp~?bf+}8*nMUB*mAags0+ChVti(X5EI2zw@Bpf z)&_g#;)AXlhi|9(3pu{oFw+No=EPYBQhZn+*G~UblD1yfVNr*;C3INW8F)m{C-d|% zR@?jNFB&0dAIj#2er+v>qGF74_}}iEtv9xQeu zKEX&14Vlgq%PS}u>KP0&_IW()$?nB6dOT*(6ckKNO_ehcF`ohV1bmz9TnTYg_+y z^Hp8+z2D-KM4S|>ww?h+3?3nd^6Ho<*9$g&pzH`8Z_qj#L^K!^x!CBxNS%7A=;+b9 zj1!;Xq!c1mXK}kG1I*MQdD{8%VrX%3) zeoHD6L$8XCj$P+;$RS04+-gPa1T9R9hu2Zw0-&mLW*{Dc&@O_6356{8*oBE?c??bN z>?5zQi_P$iBJ(iEv!d$j*WIGX&H5n4UY2ZN&%I1lnkP=8nVs*;({)4p;qT%T9@E(5 zq8i$=>I9fELX0rvj?Ht(E-dGd-aB(@p;5i4#8;&BXuiEGcP+2p^xA2;_Xq2WApzoP zg)iyp1^)DB^fW0MZ(4mt^bmdu=|N_VC9sKo|Ng5raWO0^>foS2nNhRJb=_RhWoET5 zCM#-6{|i*ddH3b+ND2@11E|1fH3bB`!^flYjrbUjRvK@M zTU(Fn&V@RJaz~O~4o_bfW@nwY#l6QQVf_?MXZr?eo33wTBV#moH!4Q9Zv}MyR4Of( z8*i_+2i;(itgJ3Sdc(!mlvTK&?;QW3lsUr3e-~+Xbkw-CM9A;)vM}o~9!Wmt`lq{e z2p=j4Iw?{W+)6ge4%rU2wtN>C$;CXr#HO-q$q z$~~>KozvW%{WbO~CPrDbFdmt$h~IoBPEpldc>C*3T|mIFzRf z4ry-x#r6l8g_T*KbTroFn-T+642T8Q7R8SwJK*39V==?Kbysx zo$F2sUe1!W^&K_Wkb(k{MIUW zw!W_R=2{UIC9a_V-#>+>@5IzhO^sFJ)55i_tWbpV^7n6J)%0vw=?Msg_WCnL5GxH& z=NntW(%iB+qqVgB*$z1|H8s>RRAt%AW6HXDo?w`l_*m~BwGX zmmc!k=DKE!BS(#-h5LF)qs-&bM9)?0C+(EK2<7?gLVFu_qsJ~X!AjRWj0qw95?8Jd z2YdUpWP<^r5~|hpMtv(gF)?{_S&6r)^+#O#`pk?3m&KksS$Fremm#Yny7d4tY*;WM z-3FfB>#0d2!q&wGbV3NWF&btg@(s&wDapyfjdAJr&LSF|IW{A~fX=UK(rpi2h;46}f7b_5 zSdd$fsc+iaAfF7M2fBe+WR3-^ z#N}rHn^k1b*T`)w^k^PBO~5$3SVmZB1YCazk!aFO=D{`U< z8lmMaEUC8uEcE=`{Q1Rsc||$Bowb0&x$dd%qUz$@+&r?-8!s;twCUGZLNi_cqx*yx zd~|(NPI;*>f5K8dI&(t0g@pw@o<1rq4lmZ0{%FSa>ttpclU@Hc#a1@ql(uIAA`=SN zl4fX~#2ckrv~-m6Z4AXkdm_@ixF5}C4EpP#1}ca%vaZ@49ZUS_8bpi1GF*Z zWbs$Yah}*OB4Uw*`iy^nIhFdP7w_AXBcdq)P9lAD)l-w?e489hpuI+jKldY^vqZDv zbk6C0Jn*fou_yQo&E+Bu09dqOK(wB*1Eou6BS*zU?D;I7P|da|ik)6$fQ zbjMl1ZTtReTHQs0^pBV|a1R+m(Tdak)UCQ3e^VSE!!Q4yX4I1%As-J$R`D;feoa8$gosQK}|UtB!4NddKRw{ART2g$~j)NUO1p%nX+ zqOvS921-Uo2f3S!#M8^sF-$JL(y?{`i{%t`Y&{eyhzOx ztYUOi&PT_WbBiLDkqO>;aDqfKR$?m7O49n0B;2vzBZ+FYV?N~Je*D|{cvHN*R-t#x zfN2=hks)-eCz6?&(O?bb>Q;MdyS=vY{vD#bGg z^I((BW>3=nWwLTn-{7Ex=+p7~quS5B;^buz=JS`7Xn<}TE9GSsC5vUhDSYrPc4FVCn5Mf)V5D^@sQ6NtJ=&R17p#W-ZST z7zm#Pm**R9-?mE}exAJs(q-?i2M~YGX2KB@L$*Bg&i;;R_|92F$+fJlpQcsr7;{O| zTe2+#fz1U0|D$GXJ!aSDXwAog(3xI~PeSr*o(l=sAo)ZN5oS-2nh-~V44nj=xF3`( z5#F6?aFtt*7Zj6`ze_!OuJc|YyRN^9A?pSpOaKlSlQ%STglS==wI!I(u{j93V0LYDEWcBs8Z?=~B564~)v--S>1UIP57Jm8z{|TEYJWw6ac _rp9%YUu_^i*U=`g%FI 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 NJ4tzok~bed|1YCCG%ElA literal 0 HcmV?d00001 diff --git a/contracts/phase9/annotated/mobile-ar-dark_v1.0.png b/contracts/phase9/annotated/mobile-ar-dark_v1.0.png new file mode 100644 index 0000000000000000000000000000000000000000..ec4f7762c3b3c23f18c138b4b706eee2852a2d3a GIT binary patch literal 75193 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

pQZN+HQAD2SIpjSbwH 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�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

M4uDn zd_3H-{|r23>z`RH2+6o!8E5qWHs!b=IdT?%5n>#T

+j0F!~+NQd<$ooKME*0Tc- zMxXro8OTbLr8Qtub6CMy(XxDSHug9VE4}(aqKt!xLLxNQ+}e7?%}=iV*4>@#1t0Gp z!b5f^KW4#=n-L+g=(9nib7* z2@2L__iB;8UfFoPO=$3KFTb$*Ah`!eg!8q*7pm7#v84DQdyx5LqG{9!h+GWri`WuRtyD9ICh_CvQ9j4V-(`eg8D~a1I_>otMT!*f#g; z(On?5U=Uh&QkVY0b3`)DvtOluXH$w7+NP}6NGCxBL2WT`iXp4Ne}ioY{YkqAEJmf7 z0y^dTxB8y{QNpvNGT(EQG(HQZp!kan5b={6m6r&aDl_m}It=vkmZUOfT1rm- z6Vyu((y}8PwaqMt`yfS^`Ih!XtPr;c8KgsXH|22@)Z|YTUcQ{!aKgYPG(!bso7{fw zh4<#+vv5PL)?yiD4p**G(-09yKm58V@@JLA$JEp%F(0z9vQpoD;/jprzUQ#rxS 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 b&Zxp7AH2H8oVf}58wjbQrTkjaD(rs&?P>s4 literal 0 HcmV?d00001 diff --git a/contracts/phase9/annotated/tablet-fr-light_v1.0.png b/contracts/phase9/annotated/tablet-fr-light_v1.0.png new file mode 100644 index 0000000000000000000000000000000000000000..be38c5ee218175495cc2d2f016dad0a73fa61d29 GIT binary patch literal 102305 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 literal 0 HcmV?d00001 diff --git a/contracts/phase9/annotated/tour-dialog-fr-dark_v1.0.png b/contracts/phase9/annotated/tour-dialog-fr-dark_v1.0.png new file mode 100644 index 0000000000000000000000000000000000000000..6d359fda4398648bae942be8e2e7c9c01b5bd29d GIT binary patch literal 94445 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 literal 0 HcmV?d00001 diff --git a/contracts/phase9/assets/ASSET_MANIFEST_v1.0.csv b/contracts/phase9/assets/ASSET_MANIFEST_v1.0.csv new file mode 100644 index 0000000..f69b4fb --- /dev/null +++ b/contracts/phase9/assets/ASSET_MANIFEST_v1.0.csv @@ -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 diff --git a/contracts/phase9/assets/ASSET_USAGE_RULES_v1.0.md b/contracts/phase9/assets/ASSET_USAGE_RULES_v1.0.md new file mode 100644 index 0000000..b245808 --- /dev/null +++ b/contracts/phase9/assets/ASSET_USAGE_RULES_v1.0.md @@ -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. diff --git a/contracts/phase9/assets/brand-mark_v1.0.svg b/contracts/phase9/assets/brand-mark_v1.0.svg new file mode 100644 index 0000000..3054167 --- /dev/null +++ b/contracts/phase9/assets/brand-mark_v1.0.svg @@ -0,0 +1,6 @@ + +homePageCar mark + + + + diff --git a/contracts/phase9/assets/logo-horizontal_v1.0.svg b/contracts/phase9/assets/logo-horizontal_v1.0.svg new file mode 100644 index 0000000..8547c18 --- /dev/null +++ b/contracts/phase9/assets/logo-horizontal_v1.0.svg @@ -0,0 +1,6 @@ + +homePageCar + + +homePageCar + diff --git a/contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md b/contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md new file mode 100644 index 0000000..2052337 --- /dev/null +++ b/contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md @@ -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. diff --git a/contracts/phase9/components/COMPONENT_STATE_MATRIX_v1.0.csv b/contracts/phase9/components/COMPONENT_STATE_MATRIX_v1.0.csv new file mode 100644 index 0000000..2409f94 --- /dev/null +++ b/contracts/phase9/components/COMPONENT_STATE_MATRIX_v1.0.csv @@ -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 diff --git a/contracts/phase9/components/CONTENT_CONSTRAINTS_v1.0.csv b/contracts/phase9/components/CONTENT_CONSTRAINTS_v1.0.csv new file mode 100644 index 0000000..635bb79 --- /dev/null +++ b/contracts/phase9/components/CONTENT_CONSTRAINTS_v1.0.csv @@ -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 diff --git a/contracts/phase9/components/RESPONSIVE_BEHAVIOR_MATRIX_v1.0.csv b/contracts/phase9/components/RESPONSIVE_BEHAVIOR_MATRIX_v1.0.csv new file mode 100644 index 0000000..668bb8e --- /dev/null +++ b/contracts/phase9/components/RESPONSIVE_BEHAVIOR_MATRIX_v1.0.csv @@ -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 diff --git a/contracts/phase9/components/RTL_THEME_MATRIX_v1.0.csv b/contracts/phase9/components/RTL_THEME_MATRIX_v1.0.csv new file mode 100644 index 0000000..fa15e3c --- /dev/null +++ b/contracts/phase9/components/RTL_THEME_MATRIX_v1.0.csv @@ -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" diff --git a/contracts/phase9/implementation/TECHNOLOGY_PROFILE_v1.0.md b/contracts/phase9/implementation/TECHNOLOGY_PROFILE_v1.0.md new file mode 100644 index 0000000..f124123 --- /dev/null +++ b/contracts/phase9/implementation/TECHNOLOGY_PROFILE_v1.0.md @@ -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/ +``` diff --git a/contracts/phase9/implementation/component-contracts_v1.0.ts b/contracts/phase9/implementation/component-contracts_v1.0.ts new file mode 100644 index 0000000..ea85b4f --- /dev/null +++ b/contracts/phase9/implementation/component-contracts_v1.0.ts @@ -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>; formError?: string; onSubmit(values: DemoFormValues): Promise; } +export interface TourProps { steps: WorkflowStep[]; activeIndex: number; open: boolean; onOpenChange(open:boolean): void; onStepChange(index:number): void; } diff --git a/contracts/phase9/implementation/hreflang-generator_v1.0.ts b/contracts/phase9/implementation/hreflang-generator_v1.0.ts new file mode 100644 index 0000000..e408527 --- /dev/null +++ b/contracts/phase9/implementation/hreflang-generator_v1.0.ts @@ -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; +} diff --git a/contracts/phase9/implementation/localization-config_v1.0.ts b/contracts/phase9/implementation/localization-config_v1.0.ts new file mode 100644 index 0000000..be713bd --- /dev/null +++ b/contracts/phase9/implementation/localization-config_v1.0.ts @@ -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 = { 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 }; } diff --git a/contracts/phase9/implementation/theme-config_v1.0.ts b/contracts/phase9/implementation/theme-config_v1.0.ts new file mode 100644 index 0000000..a792303 --- /dev/null +++ b/contracts/phase9/implementation/theme-config_v1.0.ts @@ -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 }; diff --git a/contracts/phase9/interaction/ANALYTICS_EVENT_SPEC_v1.0.csv b/contracts/phase9/interaction/ANALYTICS_EVENT_SPEC_v1.0.csv new file mode 100644 index 0000000..5b7c4ee --- /dev/null +++ b/contracts/phase9/interaction/ANALYTICS_EVENT_SPEC_v1.0.csv @@ -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 diff --git a/contracts/phase9/interaction/INTERACTION_NOTES_v1.0.md b/contracts/phase9/interaction/INTERACTION_NOTES_v1.0.md new file mode 100644 index 0000000..fc717b1 --- /dev/null +++ b/contracts/phase9/interaction/INTERACTION_NOTES_v1.0.md @@ -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 `

` 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. diff --git a/contracts/phase9/interaction/analytics-contract_v1.0.ts b/contracts/phase9/interaction/analytics-contract_v1.0.ts new file mode 100644 index 0000000..c875446 --- /dev/null +++ b/contracts/phase9/interaction/analytics-contract_v1.0.ts @@ -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; diff --git a/contracts/phase9/interaction/demo-form-contract_v1.0.ts b/contracts/phase9/interaction/demo-form-contract_v1.0.ts new file mode 100644 index 0000000..963bc14 --- /dev/null +++ b/contracts/phase9/interaction/demo-form-contract_v1.0.ts @@ -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; } diff --git a/contracts/phase9/interaction/theme-bootstrap_v1.0.js b/contracts/phase9/interaction/theme-bootstrap_v1.0.js new file mode 100644 index 0000000..c00dbb3 --- /dev/null +++ b/contracts/phase9/interaction/theme-bootstrap_v1.0.js @@ -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; +})(); diff --git a/contracts/phase9/localization/LOCALIZATION_IMPLEMENTATION_v1.0.md b/contracts/phase9/localization/LOCALIZATION_IMPLEMENTATION_v1.0.md new file mode 100644 index 0000000..abe957a --- /dev/null +++ b/contracts/phase9/localization/LOCALIZATION_IMPLEMENTATION_v1.0.md @@ -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 + +``` + +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. diff --git a/contracts/phase9/localization/ROUTE_MANIFEST_v1.0.json b/contracts/phase9/localization/ROUTE_MANIFEST_v1.0.json new file mode 100644 index 0000000..36ab4bc --- /dev/null +++ b/contracts/phase9/localization/ROUTE_MANIFEST_v1.0.json @@ -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 + } +} diff --git a/contracts/phase9/localization/TRANSLATION_KEY_INVENTORY_v1.0.csv b/contracts/phase9/localization/TRANSLATION_KEY_INVENTORY_v1.0.csv new file mode 100644 index 0000000..29ff51b --- /dev/null +++ b/contracts/phase9/localization/TRANSLATION_KEY_INVENTORY_v1.0.csv @@ -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 diff --git a/contracts/phase9/localization/locales/ar/homepage.json b/contracts/phase9/localization/locales/ar/homepage.json new file mode 100644 index 0000000..f3e6900 --- /dev/null +++ b/contracts/phase9/localization/locales/ar/homepage.json @@ -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": "إغلاق" + } +} diff --git a/contracts/phase9/localization/locales/en/homepage.json b/contracts/phase9/localization/locales/en/homepage.json new file mode 100644 index 0000000..0aa92e3 --- /dev/null +++ b/contracts/phase9/localization/locales/en/homepage.json @@ -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" + } +} diff --git a/contracts/phase9/localization/locales/fr/homepage.json b/contracts/phase9/localization/locales/fr/homepage.json new file mode 100644 index 0000000..b4c981e --- /dev/null +++ b/contracts/phase9/localization/locales/fr/homepage.json @@ -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" + } +} diff --git a/contracts/phase9/qa/ACCESSIBILITY_CHECKLIST_v1.0.csv b/contracts/phase9/qa/ACCESSIBILITY_CHECKLIST_v1.0.csv new file mode 100644 index 0000000..6663585 --- /dev/null +++ b/contracts/phase9/qa/ACCESSIBILITY_CHECKLIST_v1.0.csv @@ -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 diff --git a/contracts/phase9/qa/BROWSER_SUPPORT_MATRIX_v1.0.csv b/contracts/phase9/qa/BROWSER_SUPPORT_MATRIX_v1.0.csv new file mode 100644 index 0000000..2b876a9 --- /dev/null +++ b/contracts/phase9/qa/BROWSER_SUPPORT_MATRIX_v1.0.csv @@ -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 diff --git a/contracts/phase9/qa/PERFORMANCE_BUDGETS_v1.0.json b/contracts/phase9/qa/PERFORMANCE_BUDGETS_v1.0.json new file mode 100644 index 0000000..d0639f3 --- /dev/null +++ b/contracts/phase9/qa/PERFORMANCE_BUDGETS_v1.0.json @@ -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." + ] +} diff --git a/contracts/phase9/qa/PLAYWRIGHT_ACCEPTANCE_SPEC_v1.0.md b/contracts/phase9/qa/PLAYWRIGHT_ACCEPTANCE_SPEC_v1.0.md new file mode 100644 index 0000000..3c872d1 --- /dev/null +++ b/contracts/phase9/qa/PLAYWRIGHT_ACCEPTANCE_SPEC_v1.0.md @@ -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. diff --git a/contracts/phase9/qa/QA_MATRIX_v1.0.csv b/contracts/phase9/qa/QA_MATRIX_v1.0.csv new file mode 100644 index 0000000..4ef4453 --- /dev/null +++ b/contracts/phase9/qa/QA_MATRIX_v1.0.csv @@ -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 diff --git a/contracts/phase9/qa/test-ids_v1.0.csv b/contracts/phase9/qa/test-ids_v1.0.csv new file mode 100644 index 0000000..9400360 --- /dev/null +++ b/contracts/phase9/qa/test-ids_v1.0.csv @@ -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 diff --git a/contracts/phase9/qa/validate-phase9-package_v1.0.mjs b/contracts/phase9/qa/validate-phase9-package_v1.0.mjs new file mode 100644 index 0000000..37fe2fd --- /dev/null +++ b/contracts/phase9/qa/validate-phase9-package_v1.0.mjs @@ -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=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 diff --git a/contracts/phase9/reference/VALIDATION_RESULTS_v1.0.md b/contracts/phase9/reference/VALIDATION_RESULTS_v1.0.md new file mode 100644 index 0000000..ec9af33 --- /dev/null +++ b/contracts/phase9/reference/VALIDATION_RESULTS_v1.0.md @@ -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. diff --git a/contracts/phase9/tokens/TOKEN_USAGE_RULES_v1.0.md b/contracts/phase9/tokens/TOKEN_USAGE_RULES_v1.0.md new file mode 100644 index 0000000..e60756a --- /dev/null +++ b/contracts/phase9/tokens/TOKEN_USAGE_RULES_v1.0.md @@ -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. diff --git a/contracts/phase9/tokens/design-tokens_v1.0.json b/contracts/phase9/tokens/design-tokens_v1.0.json new file mode 100644 index 0000000..03e916f --- /dev/null +++ b/contracts/phase9/tokens/design-tokens_v1.0.json @@ -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)" + } + } +} diff --git a/contracts/phase9/tokens/semantic-tokens_v1.0.css b/contracts/phase9/tokens/semantic-tokens_v1.0.css new file mode 100644 index 0000000..9419d46 --- /dev/null +++ b/contracts/phase9/tokens/semantic-tokens_v1.0.css @@ -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; } +} diff --git a/contracts/phase9/tokens/tokens_v1.0.ts b/contracts/phase9/tokens/tokens_v1.0.ts new file mode 100644 index 0000000..061fd76 --- /dev/null +++ b/contracts/phase9/tokens/tokens_v1.0.ts @@ -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; +export const layout = { containerMaxPx: 1280, touchTargetMinPx: 44, spacingBasePx: 4 } as const; +export const motion = { fastMs: 120, standardMs: 160, overlayMs: 220 } as const; diff --git a/contracts/phase9/validation/CONTENT_AND_STRUCTURE_VALIDATION_v1.0.json b/contracts/phase9/validation/CONTENT_AND_STRUCTURE_VALIDATION_v1.0.json new file mode 100644 index 0000000..00e8638 --- /dev/null +++ b/contracts/phase9/validation/CONTENT_AND_STRUCTURE_VALIDATION_v1.0.json @@ -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": [] +} diff --git a/contracts/phase9/validation/STATIC_VALIDATION_RESULTS_v1.0.json b/contracts/phase9/validation/STATIC_VALIDATION_RESULTS_v1.0.json new file mode 100644 index 0000000..e1e2c4e --- /dev/null +++ b/contracts/phase9/validation/STATIC_VALIDATION_RESULTS_v1.0.json @@ -0,0 +1,5 @@ +{ + "status": "PASSED", + "checks": 38, + "files": 18 +} diff --git a/contracts/phase9/validation/VALIDATION_RESULTS_v1.0.md b/contracts/phase9/validation/VALIDATION_RESULTS_v1.0.md new file mode 100644 index 0000000..3238474 --- /dev/null +++ b/contracts/phase9/validation/VALIDATION_RESULTS_v1.0.md @@ -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`. diff --git a/docs/BRAND_MIGRATION_v1.0.md b/docs/BRAND_MIGRATION_v1.0.md new file mode 100644 index 0000000..e93e1f3 --- /dev/null +++ b/docs/BRAND_MIGRATION_v1.0.md @@ -0,0 +1,25 @@ +# Brand Migration Record + +The project name changed from `homePageCar` to `RentalDriveGo` at Phase 10. + +## Preserved historical authority + +`contracts/phase9` is an immutable copy of the approved Phase 9 package. Its names, files, checksums, and historical references are not rewritten. This preserves auditability and prevents a rename from masquerading as retroactive approval. + +## Updated implementation surfaces + +Runtime locale catalogs under `src/content/locales` use `RentalDriveGo`. The application package, page metadata, title, shell label, and documentation use the new name. + +## Intentionally retained identifiers + +The following legacy technical identifiers remain because they are part of the Phase 9 contract and may exist in user storage: + +- `hpc-locale` +- `hpc-theme` +- `hpc.theme.preference` + +Changing them requires an explicit compatibility migration. Renaming a cookie for cosmetic purity while discarding users' preferences would be branding theater, not engineering. + +## Asset decision + +Phase 9 logo files contain the former name and are retained only inside the immutable contract package. They are not copied into `public`. The repository shell uses a text-based `R` mark as a non-public implementation placeholder. A final RentalDriveGo logo asset requires Product and Design approval before release. diff --git a/docs/DECISION_LOG_v12.0.md b/docs/DECISION_LOG_v12.0.md new file mode 100644 index 0000000..66ab84f --- /dev/null +++ b/docs/DECISION_LOG_v12.0.md @@ -0,0 +1,58 @@ +# RentalDriveGo Decision Log v12.0 + +Date: 2026-06-25 +Scope: Phase 12 reusable component-system implementation + +## D12-001: Preserve the Phase 11 styling architecture + +Status: Accepted. + +Phase 12 uses CSS Modules and Phase 11 semantic tokens exclusively. No utility CSS framework, CSS-in-JS runtime, or arbitrary raw brand-color API was added. + +## D12-002: Prefer native platform semantics + +Status: Accepted. + +Buttons, links, form controls, `details`, `progress`, and `dialog` remain native elements. Custom behavior is added only where keyboard state, focus return, browser APIs, or controlled composition require it. + +## D12-003: Guard the component workbench + +Status: Accepted. + +`/[locale]/component-lab` is the Storybook-equivalent fixture route. It is available only when `COMPONENT_FIXTURES_ENABLED=true`, is marked noindex, and uses deterministic fictional content. + +## D12-004: Keep the dependency graph unchanged + +Status: Accepted. + +The component system uses React, browser primitives, and the existing stack. No icon, overlay, form, animation, class-merging, or state-management dependency was added. A small internal SVG icon map avoids shipping an entire icon library for several symbols. + +## D12-005: Use semantic, constrained component APIs + +Status: Accepted. + +Public APIs expose intent, status, density, alignment, or meaningful variants. Arbitrary colors and large Boolean prop collections are prohibited. Link and button semantics remain distinct. + +## D12-006: Treat RTL as component behavior, not a global mirror + +Status: Accepted. + +CSS logical properties and document direction control layout. Directional icons opt into mirroring; brands, media, vehicle imagery, process chronology, and universal media controls remain fixed unless explicitly specified. + +## D12-007: Suppress unresolved production evidence and destinations + +Status: Accepted. + +Claims, metrics, customer evidence, testimonials, pricing, CRM transmission, login destinations, sales destinations, and final media remain typed blocked states, disabled treatments, or development fixtures tied to existing issue IDs. Compilation is not product approval. + +## D12-008: Keep server rendering as the default + +Status: Accepted. + +Only stateful controls and browser-dependent utilities create client boundaries. Static surfaces, typography, media shells, evidence structures, workflow patterns, comparison patterns, and section patterns remain server-compatible. + +## D12-009: Record runtime evidence without laundering environment failures + +Status: Accepted. + +Static validation, formatting, lint, strict type checking, unit tests, production build, and direct HTTP route checks are recorded as executed. Browser navigation, visual baselines, frozen pnpm installation, audit, Node 24 verification, and manual assistive-technology checks remain explicit gates. diff --git a/docs/DECISION_LOG_v13.0.md b/docs/DECISION_LOG_v13.0.md new file mode 100644 index 0000000..0ab0698 --- /dev/null +++ b/docs/DECISION_LOG_v13.0.md @@ -0,0 +1,52 @@ +# RentalDriveGo Decision Log v13.0 + +Date: 2026-06-25 +Scope: Phase 13 multilingual homepage assembly + +## D13-001: Assemble rather than fork the component system + +Status: Accepted. + +The homepage is composed from Phase 12 components and semantic layout primitives. No duplicate button, card, accordion, preview, workflow, comparison, or CTA family was introduced. + +## D13-002: Keep route content typed and locale-owned + +Status: Accepted. + +A typed `HomepageContent` model transforms complete EN, FR, and AR catalog messages into stable route-level content objects. Presentation code does not index translation arrays directly. + +## D13-003: Treat unavailable destinations as product state + +Status: Accepted. + +Demo, product-tour, pricing, and sales actions remain non-navigable with localized disabled reasons. No empty hash, root fallback, guessed URL, CRM call, or fake submission was added. + +## D13-004: Publish measurement definitions, not fictional results + +Status: Accepted. + +The results section explains KPI definitions and evidence methodology without numeric claims. Customer evidence, testimonials, logos, certifications, SLAs, and partner names remain suppressed. + +## D13-005: Use an illustrative operational preview + +Status: Accepted. + +The hero uses the Phase 12 `ProductPreview` with deterministic fictional rows from localized catalogs. It is explicitly captioned as illustrative and does not impersonate an approved product capture. + +## D13-006: Preserve document-level RTL and identifier isolation + +Status: Accepted. + +Arabic uses the existing document-level RTL shell. Layout CSS uses logical declarations, while vehicle identifiers remain isolated left-to-right through `BidiText`. Media and brand elements are not globally mirrored. + +## D13-007: Make section anchors real + +Status: Accepted. + +The existing header and footer hashes now resolve to implemented `product`, `workflow`, `modules`, `pricing`, and `faq` sections. Locale routing continues through the approved route helper. + +## D13-008: Record environment limits without converting them into acceptance + +Status: Accepted. + +Static validation, formatting, lint, strict type checking, unit coverage, production build, and direct HTTP locale responses are recorded as executed. Chromium loopback navigation remains administrator-blocked, so browser, axe, visual, keyboard, touch, screen-reader, zoom, and forced-colors acceptance remain open. diff --git a/docs/DEPENDENCY_MANIFEST_v1.0.md b/docs/DEPENDENCY_MANIFEST_v1.0.md new file mode 100644 index 0000000..71578c8 --- /dev/null +++ b/docs/DEPENDENCY_MANIFEST_v1.0.md @@ -0,0 +1,60 @@ +# Exact Dependency Manifest + +- **Project:** RentalDriveGo Web +- **Recorded:** 2026-06-25 +- **Authority:** `package.json` and `pnpm-lock.yaml` +- **Policy:** Exact direct versions, frozen lockfile in CI, reviewed automated updates + +## Runtime and package manager + +| Component | Exact version | Role | +| --------- | ------------: | ------------------------- | +| Node.js | 24.17.0 | Production and CI runtime | +| pnpm | 11.9.0 | Package manager | + +## Production dependencies + +| Package | Exact version | Role | +| --------------------------------------- | ------------: | ----------------------------------------------- | +| `next` | 16.2.9 | SSR framework and App Router | +| `react` | 19.2.7 | UI runtime | +| `react-dom` | 19.2.7 | React DOM renderer | +| `zod` | 4.4.3 | Runtime boundary schemas for later integrations | +| `@fontsource-variable/inter` | 5.2.8 | Self-hosted Latin variable font | +| `@fontsource-variable/noto-sans-arabic` | 5.2.10 | Self-hosted Arabic variable font | + +## Development dependencies + +| Package | Exact version | Role | +| ----------------------------- | ------------: | -------------------------------------- | +| `typescript` | 6.0.3 | Strict static type checking | +| `eslint` | 9.39.4 | Lint engine | +| `@eslint/js` | 9.39.4 | Core ESLint rules | +| `eslint-config-next` | 16.2.9 | Next.js lint rules | +| `eslint-config-prettier` | 10.1.8 | Formatting-rule conflict prevention | +| `typescript-eslint` | 8.62.0 | TypeScript lint integration | +| `globals` | 17.7.0 | Runtime global definitions | +| `prettier` | 3.8.4 | Deterministic formatting | +| `vitest` | 4.1.9 | Unit test runner | +| `@vitest/coverage-v8` | 4.1.9 | Unit coverage | +| `jsdom` | 29.1.1 | DOM test environment | +| `@testing-library/react` | 16.3.2 | React test utilities | +| `@testing-library/jest-dom` | 6.9.1 | DOM assertions | +| `@testing-library/user-event` | 14.6.1 | Interaction simulation | +| `@playwright/test` | 1.61.1 | Browser and visual testing | +| `@axe-core/playwright` | 4.12.1 | Automated browser accessibility checks | +| `@types/node` | 24.10.9 | Node.js type declarations | +| `@types/react` | 19.2.17 | React type declarations | +| `@types/react-dom` | 19.2.3 | React DOM type declarations | + +## Supply-chain controls + +- `pnpm-lock.yaml` locks all resolved transitive versions and integrity hashes. +- CI uses `pnpm install --frozen-lockfile`. +- The pnpm workspace enforces `minimumReleaseAge: 1440` minutes for unreviewed new releases. +- Native package build scripts are allowlisted rather than globally trusted. +- `postcss` is overridden to `8.5.15` to remove the audited vulnerable transitive resolution while retaining framework compatibility. +- Dependabot proposes weekly npm and GitHub Actions updates for review. +- `pnpm audit --audit-level low` reported no known vulnerabilities on 2026-06-25. + +No dependency range in `package.json` is floating. The lockfile, rather than this narrative table, is the machine authority for the full transitive graph. diff --git a/docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv b/docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv new file mode 100644 index 0000000..33f2231 --- /dev/null +++ b/docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv @@ -0,0 +1,22 @@ +Issue_ID,Severity,Area,Status,Code_path_or_control,Release_gate,Owner,Exit_criteria,Notes +P9-001,Critical,Participant acceptance,Inherited open,contracts/phase9/research; docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv,Before release,Research,"Run required pilot, core, and accessibility cohorts; fix/retest S0/S1 findings.",No production claim of usability acceptance. +P9-002,High,CRM integration,Inherited open,src/contracts/phase9/demo-form-contract.ts; no endpoint implemented,Before production integration,Sales Ops + Engineering,"Approve and integration-test endpoint, routing, duplicates, idempotency, retry, spam controls, monitoring, and ownership.",Demo submission remains unimplemented. +P9-003,High,Legal consent,Inherited open,No production form or legal copy implemented,Before production form,Legal,"Approve localized consent, privacy linkage, retention, and market requirements.",Suppressed rather than guessed. +P9-004,High,Analytics and consent,Inherited open,src/contracts/phase9/analytics-contract.ts; no vendor adapter,Before beta,Analytics + Legal,"Approve vendor, event authority, consent policy, retention, replay policy, and non-PII payloads.",Contract imported; collection disabled. +P9-005,High,Native linguistic review,Inherited open,"src/content/locales/{fr,ar}; CI locale parity",Before release,Content + Localization,"Native review of all visible copy, metadata, errors, and bidi samples.",Mechanical parity is not linguistic approval. +P9-006,High,Illustrative product preview,Inherited open,No preview shipped,Before release,Product + Design,Approve illustration or provide governed product capture.,Suppressed. +P9-007,High,Multi-location claim,Inherited open,scripts/validate-prohibited-content.mjs; visible shell only,Before beta,Product,Approve capability or revise/suppress affected copy.,No new claim introduced. +P9-008,High,Pricing model,Inherited open,No pricing route or component,Before pricing publication,Commercial,Approve public pricing and limits in writing.,Quote-only posture preserved by omission. +P9-009,High,Security evidence,Inherited open,No public security claims,Before claims publish,Security + Legal,"Provide scoped evidence, approvals, and expiry dates.","Security headers are implementation controls, not marketing claims." +P9-010,Medium,Framework selection,Resolved in Phase 10,docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md,Scaffold merge,Architecture,Architecture decision accepted and implemented.,"Next.js App Router SSR, strict TypeScript, CSS Modules, OCI target." +P9-011,Medium,Browser policy owner,Inherited open,.github/workflows/ci.yml; playwright.config.ts,Before beta,Product + Engineering,"Approve supported browser matrix, owner, telemetry, and exception/retirement process.","Configured matrix is a test baseline, not a policy claim." +P9-012,Medium,Product tour medium,Inherited open,No product tour implemented,Before release,Product + Marketing,Approve accessible localized dialog fallback or media/transcript.,Suppressed. +P9-013,Medium,Markets and formatting,Inherited open,src/lib/localization; no currency/phone market assumptions,Before regional campaign,Product + Legal,"Define markets, currency, timezone, phone, and jurisdiction independently of locale.",Locale is not treated as market. +P9-014,Medium,Login destination,Inherited open,No login link implemented,Before release,Product + Engineering,"Approve destination, security behavior, locale return path, and analytics.",Suppressed. +P9-015,Medium,Alternate sales contact,Inherited open,No secondary contact destination,Before release,Sales Ops,Provide approved contact route or approve suppression.,Placeholder address not imported into runtime. +P9-016,Medium,Customer evidence,Inherited open,"No logos, metrics, testimonials, or case studies",Optional post-launch,Marketing + Legal,Provide attributable evidence records and approvals.,Suppressed. +P9-017,Low,Exact dependency versions,Resolved in Phase 10,package.json; pnpm-lock.yaml; docs/DEPENDENCY_MANIFEST_v1.0.md,Scaffold,Engineering,"Exact versions pinned, audited, locked, and automated update review enabled.",No floating direct dependency ranges. +P10-001,High,Canonical production origin,Open,src/lib/localization/site-origin.ts; .env.example,Before production deployment,Product + Infrastructure,Approve public domain/origin and configure SITE_ORIGIN in production.,Build fails closed in production when missing. +P10-002,High,RentalDriveGo visual identity,Open,public/.gitkeep; docs/BRAND_MIGRATION_v1.0.md,Before public release,Product + Design,Approve and supply final accessible logo assets for light/dark contexts.,Old-name Phase 9 assets are retained only in immutable contracts and not shipped. +P10-003,Medium,Browser suite execution,Environment blocked locally,.github/workflows/ci.yml; tests/browser; tests/a11y; tests/visual,Before Phase 11 acceptance,Engineering + QA,Run configured Playwright matrix in unblocked CI; generate/review baselines; close all failures.,Local Chromium is administrator-blocked and browser download DNS failed. +P10-004,Low,Exact target runtime verification,Open verification,.github/workflows/ci.yml; Dockerfile; .node-version,Before scaffold merge,Engineering,Pass full quality and browser workflows on Node.js 24.17.0.,Local host exposes Node.js 22.16.0; target remains pinned to 24.17.0. diff --git a/docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv b/docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv new file mode 100644 index 0000000..d0778f6 --- /dev/null +++ b/docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv @@ -0,0 +1,26 @@ +Issue_ID,Severity,Area,Status,Code_path_or_control,Release_gate,Owner,Exit_criteria,Notes +P9-001,Critical,Participant acceptance,Inherited open,contracts/phase9/research; docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv,Before release,Research,"Run required pilot, core, and accessibility cohorts; fix/retest S0/S1 findings.",No production claim of usability acceptance. +P9-002,High,CRM integration,Inherited open,src/contracts/phase9/demo-form-contract.ts; no endpoint implemented,Before production integration,Sales Ops + Engineering,"Approve and integration-test endpoint, routing, duplicates, idempotency, retry, spam controls, monitoring, and ownership.",Demo submission remains unimplemented. +P9-003,High,Legal consent,Inherited open,No production form or legal copy implemented,Before production form,Legal,"Approve localized consent, privacy linkage, retention, and market requirements.",Suppressed rather than guessed. +P9-004,High,Analytics and consent,Inherited open,src/contracts/phase9/analytics-contract.ts; no vendor adapter,Before beta,Analytics + Legal,"Approve vendor, event authority, consent policy, retention, replay policy, and non-PII payloads.",Contract imported; collection disabled. +P9-005,High,Native linguistic review,Inherited open,"src/content/locales/{fr,ar}; CI locale parity",Before release,Content + Localization,"Native review of all visible copy, metadata, errors, and bidi samples.",Mechanical parity is not linguistic approval. +P9-006,High,Illustrative product preview,Inherited open,No preview shipped,Before release,Product + Design,Approve illustration or provide governed product capture.,Suppressed. +P9-007,High,Multi-location claim,Inherited open,scripts/validate-prohibited-content.mjs; visible shell only,Before beta,Product,Approve capability or revise/suppress affected copy.,No new claim introduced. +P9-008,High,Pricing model,Inherited open,No pricing route or component,Before pricing publication,Commercial,Approve public pricing and limits in writing.,Quote-only posture preserved by omission. +P9-009,High,Security evidence,Inherited open,No public security claims,Before claims publish,Security + Legal,"Provide scoped evidence, approvals, and expiry dates.","Security headers are implementation controls, not marketing claims." +P9-010,Medium,Framework selection,Resolved in Phase 10,docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md,Scaffold merge,Architecture,Architecture decision accepted and implemented.,"Next.js App Router SSR, strict TypeScript, CSS Modules, OCI target." +P9-011,Medium,Browser policy owner,Inherited open,.github/workflows/ci.yml; playwright.config.ts,Before beta,Product + Engineering,"Approve supported browser matrix, owner, telemetry, and exception/retirement process.","Configured matrix is a test baseline, not a policy claim." +P9-012,Medium,Product tour medium,Inherited open,No product tour implemented,Before release,Product + Marketing,Approve accessible localized dialog fallback or media/transcript.,Suppressed. +P9-013,Medium,Markets and formatting,Inherited open,src/lib/localization; no currency/phone market assumptions,Before regional campaign,Product + Legal,"Define markets, currency, timezone, phone, and jurisdiction independently of locale.",Locale is not treated as market. +P9-014,Medium,Login destination,Inherited open,No login link implemented,Before release,Product + Engineering,"Approve destination, security behavior, locale return path, and analytics.",Suppressed. +P9-015,Medium,Alternate sales contact,Inherited open,No secondary contact destination,Before release,Sales Ops,Provide approved contact route or approve suppression.,Placeholder address not imported into runtime. +P9-016,Medium,Customer evidence,Inherited open,"No logos, metrics, testimonials, or case studies",Optional post-launch,Marketing + Legal,Provide attributable evidence records and approvals.,Suppressed. +P9-017,Low,Exact dependency versions,Resolved in Phase 10,package.json; pnpm-lock.yaml; docs/DEPENDENCY_MANIFEST_v1.0.md,Scaffold,Engineering,"Exact versions pinned, audited, locked, and automated update review enabled.",No floating direct dependency ranges. +P10-001,High,Canonical production origin,Open,src/lib/localization/site-origin.ts; .env.example,Before production deployment,Product + Infrastructure,Approve public domain/origin and configure SITE_ORIGIN in production.,Build fails closed in production when missing. +P10-002,High,RentalDriveGo visual identity,Open,public/.gitkeep; docs/BRAND_MIGRATION_v1.0.md,Before public release,Product + Design,Approve and supply final accessible logo assets for light/dark contexts.,Old-name Phase 9 assets are retained only in immutable contracts and not shipped. +P10-003,Medium,Browser suite execution,Environment blocked locally,.github/workflows/ci.yml; tests/browser; tests/a11y; tests/visual,Before Phase 11 acceptance,Engineering + QA,Run configured Playwright matrix in unblocked CI; generate/review baselines; close all failures.,Local Chromium is administrator-blocked and browser download DNS failed. +P10-004,Low,Exact target runtime verification,Open verification,.github/workflows/ci.yml; Dockerfile; .node-version,Before scaffold merge,Engineering,Pass full quality and browser workflows on Node.js 24.17.0.,Local host exposes Node.js 22.16.0; target remains pinned to 24.17.0. +P11-001,High,Phase 11 browser verification,Environment blocked,"tests/browser; tests/a11y; playwright.config.ts",Before Phase 11 acceptance,Engineering + QA,"Install pinned dependencies and browsers in unblocked Node 24.17.0 CI; pass all functional and accessibility projects.",Static implementation is complete; execution evidence is not fabricated. +P11-002,High,Visual baseline generation and approval,Environment blocked,"tests/visual; tests/visual/README.md",Before Phase 11 acceptance,Design + QA,"Generate all Chromium snapshots with the pinned browser; review locale/theme/viewport/drawer/focus cases; commit approved baselines.",Scenario coverage exists but PNG baselines were not generated locally. +P11-003,Low,Exact Phase 11 target runtime verification,Open verification,"package.json; .node-version; .github/workflows/ci.yml",Before Phase 11 merge,Engineering,"Run static, unit, build, package, and browser gates on Node 24.17.0 and pnpm 11.9.0.",Local host is Node 22.16.0 and could not download pnpm 11.9.0. +P11-004,Medium,Application-shell copy linguistic approval,Inherited open,"src/content/locales/fr/shell.json; src/content/locales/ar/shell.json",Before release,Content + Localization,"Complete native French and Arabic review of Phase 11 shell, state, metadata, and pending-destination copy.",Mechanical parity passes; linguistic approval remains P9-005. diff --git a/docs/IMPLEMENTATION_ISSUE_REGISTER_v1.2.csv b/docs/IMPLEMENTATION_ISSUE_REGISTER_v1.2.csv new file mode 100644 index 0000000..2300253 --- /dev/null +++ b/docs/IMPLEMENTATION_ISSUE_REGISTER_v1.2.csv @@ -0,0 +1,31 @@ +Issue_ID,Severity,Area,Status,Code_path_or_control,Release_gate,Owner,Exit_criteria,Notes +P9-001,Critical,Participant acceptance,Inherited open,contracts/phase9/research; docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv,Before release,Research,"Run required pilot, core, and accessibility cohorts; fix/retest S0/S1 findings.",No production claim of usability acceptance. +P9-002,High,CRM integration,Inherited open,src/contracts/phase9/demo-form-contract.ts; no endpoint implemented,Before production integration,Sales Ops + Engineering,"Approve and integration-test endpoint, routing, duplicates, idempotency, retry, spam controls, monitoring, and ownership.",Demo submission remains unimplemented. +P9-003,High,Legal consent,Inherited open,No production form or legal copy implemented,Before production form,Legal,"Approve localized consent, privacy linkage, retention, and market requirements.",Suppressed rather than guessed. +P9-004,High,Analytics and consent,Inherited open,src/contracts/phase9/analytics-contract.ts; no vendor adapter,Before beta,Analytics + Legal,"Approve vendor, event authority, consent policy, retention, replay policy, and non-PII payloads.",Contract imported; collection disabled. +P9-005,High,Native linguistic review,Inherited open,"src/content/locales/{fr,ar}; CI locale parity",Before release,Content + Localization,"Native review of all visible copy, metadata, errors, and bidi samples.",Mechanical parity is not linguistic approval. +P9-006,High,Illustrative product preview,Inherited open,No preview shipped,Before release,Product + Design,Approve illustration or provide governed product capture.,Suppressed. +P9-007,High,Multi-location claim,Inherited open,scripts/validate-prohibited-content.mjs; visible shell only,Before beta,Product,Approve capability or revise/suppress affected copy.,No new claim introduced. +P9-008,High,Pricing model,Inherited open,No pricing route or component,Before pricing publication,Commercial,Approve public pricing and limits in writing.,Quote-only posture preserved by omission. +P9-009,High,Security evidence,Inherited open,No public security claims,Before claims publish,Security + Legal,"Provide scoped evidence, approvals, and expiry dates.","Security headers are implementation controls, not marketing claims." +P9-010,Medium,Framework selection,Resolved in Phase 10,docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md,Scaffold merge,Architecture,Architecture decision accepted and implemented.,"Next.js App Router SSR, strict TypeScript, CSS Modules, OCI target." +P9-011,Medium,Browser policy owner,Inherited open,.github/workflows/ci.yml; playwright.config.ts,Before beta,Product + Engineering,"Approve supported browser matrix, owner, telemetry, and exception/retirement process.","Configured matrix is a test baseline, not a policy claim." +P9-012,Medium,Product tour medium,Inherited open,No product tour implemented,Before release,Product + Marketing,Approve accessible localized dialog fallback or media/transcript.,Suppressed. +P9-013,Medium,Markets and formatting,Inherited open,src/lib/localization; no currency/phone market assumptions,Before regional campaign,Product + Legal,"Define markets, currency, timezone, phone, and jurisdiction independently of locale.",Locale is not treated as market. +P9-014,Medium,Login destination,Inherited open,No login link implemented,Before release,Product + Engineering,"Approve destination, security behavior, locale return path, and analytics.",Suppressed. +P9-015,Medium,Alternate sales contact,Inherited open,No secondary contact destination,Before release,Sales Ops,Provide approved contact route or approve suppression.,Placeholder address not imported into runtime. +P9-016,Medium,Customer evidence,Inherited open,"No logos, metrics, testimonials, or case studies",Optional post-launch,Marketing + Legal,Provide attributable evidence records and approvals.,Suppressed. +P9-017,Low,Exact dependency versions,Resolved in Phase 10,package.json; pnpm-lock.yaml; docs/DEPENDENCY_MANIFEST_v1.0.md,Scaffold,Engineering,"Exact versions pinned, audited, locked, and automated update review enabled.",No floating direct dependency ranges. +P10-001,High,Canonical production origin,Open,src/lib/localization/site-origin.ts; .env.example,Before production deployment,Product + Infrastructure,Approve public domain/origin and configure SITE_ORIGIN in production.,Build fails closed in production when missing. +P10-002,High,RentalDriveGo visual identity,Open,public/.gitkeep; docs/BRAND_MIGRATION_v1.0.md,Before public release,Product + Design,Approve and supply final accessible logo assets for light/dark contexts.,Old-name Phase 9 assets are retained only in immutable contracts and not shipped. +P10-003,Medium,Browser suite execution,Environment blocked locally,.github/workflows/ci.yml; tests/browser; tests/a11y; tests/visual,Before Phase 11 acceptance,Engineering + QA,Run configured Playwright matrix in unblocked CI; generate/review baselines; close all failures.,Local Chromium is administrator-blocked and browser download DNS failed. +P10-004,Low,Exact target runtime verification,Open verification,.github/workflows/ci.yml; Dockerfile; .node-version,Before scaffold merge,Engineering,Pass full quality and browser workflows on Node.js 24.17.0.,Local host exposes Node.js 22.16.0; target remains pinned to 24.17.0. +P11-001,High,Phase 11 browser verification,Environment blocked,tests/browser; tests/a11y; playwright.config.ts,Before Phase 11 acceptance,Engineering + QA,Install pinned dependencies and browsers in unblocked Node 24.17.0 CI; pass all functional and accessibility projects.,Static implementation is complete; execution evidence is not fabricated. +P11-002,High,Visual baseline generation and approval,Environment blocked,tests/visual; tests/visual/README.md,Before Phase 11 acceptance,Design + QA,Generate all Chromium snapshots with the pinned browser; review locale/theme/viewport/drawer/focus cases; commit approved baselines.,Scenario coverage exists but PNG baselines were not generated locally. +P11-003,Low,Exact Phase 11 target runtime verification,Open verification,package.json; .node-version; .github/workflows/ci.yml,Before Phase 11 merge,Engineering,"Run static, unit, build, package, and browser gates on Node 24.17.0 and pnpm 11.9.0.",Local host is Node 22.16.0 and could not download pnpm 11.9.0. +P11-004,Medium,Application-shell copy linguistic approval,Inherited open,src/content/locales/fr/shell.json; src/content/locales/ar/shell.json,Before release,Content + Localization,"Complete native French and Arabic review of Phase 11 shell, state, metadata, and pending-destination copy.",Mechanical parity passes; linguistic approval remains P9-005. +P12-001,High,Browser and accessibility execution,Environment blocked,tests/browser; tests/a11y; playwright.config.ts,Before Phase 12 acceptance,Engineering + QA,Run all 44 Chromium browser/accessibility scenarios and the approved cross-browser matrix in an environment where loopback navigation is not administrator-blocked; fix product failures.,Chromium launched locally but every loopback navigation was rejected with net::ERR_BLOCKED_BY_ADMINISTRATOR before application response. +P12-002,High,Visual regression baselines,Environment blocked,tests/visual; tests/fixtures/component-system/component-matrix.json,Before Phase 12 acceptance,Design + QA,Generate and review stable light/dark EN/FR/AR desktop/mobile/focus/error/long-content baselines with the pinned browser.,Visual scenarios are authored; image capture is blocked by the same Chromium loopback policy. +P12-003,Medium,Pinned runtime verification,Open verification,package.json; .node-version; .github/workflows/ci.yml,Before Phase 12 merge,Engineering,"Pass install, static, unit, build, browser, accessibility, visual, audit, and package gates on Node 24.17.0 and pnpm 11.9.0.",Source/static/unit/build checks passed under Node 22.16.0 with exact direct packages installed through npm fallback; target runtime remains unverified. +P12-004,Medium,Frozen installation and dependency audit,Environment blocked,pnpm-lock.yaml; package.json; docs/phase12/DEPENDENCY_CHANGE_REPORT_v1.0.md,Before Phase 12 merge,Engineering + Security,Complete pnpm install --frozen-lockfile and pnpm audit --audit-level low with registry access.,Registry DNS returned EAI_AGAIN. npm fallback enabled local checks but does not satisfy the frozen pnpm or audit gates. +P12-005,Medium,Manual assistive-technology and zoom QA,Open verification,docs/quality/PHASE_12_MANUAL_QA_RESULTS_v1.0.csv,Before Phase 12 acceptance,Accessibility + QA,"Complete keyboard, touch, screen-reader, 200/400 percent zoom, reduced-motion, forced-colors, locale, theme, and viewport manual matrix; attach evidence.","Static semantics, unit interactions, and server-rendered routes are verified; human browser and assistive-technology observations are not fabricated." diff --git a/docs/IMPLEMENTATION_ISSUE_REGISTER_v1.3.csv b/docs/IMPLEMENTATION_ISSUE_REGISTER_v1.3.csv new file mode 100644 index 0000000..f8ad50b --- /dev/null +++ b/docs/IMPLEMENTATION_ISSUE_REGISTER_v1.3.csv @@ -0,0 +1,34 @@ +Issue_ID,Severity,Area,Status,Code_path_or_control,Release_gate,Owner,Exit_criteria,Notes +P9-001,Critical,Participant acceptance,Inherited open,contracts/phase9/research; docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv,Before release,Research,"Run required pilot, core, and accessibility cohorts; fix/retest S0/S1 findings.",No production claim of usability acceptance. +P9-002,High,CRM integration,Inherited open,src/contracts/phase9/demo-form-contract.ts; no endpoint implemented,Before production integration,Sales Ops + Engineering,"Approve and integration-test endpoint, routing, duplicates, idempotency, retry, spam controls, monitoring, and ownership.",Demo submission remains unimplemented. +P9-003,High,Legal consent,Inherited open,No production form or legal copy implemented,Before production form,Legal,"Approve localized consent, privacy linkage, retention, and market requirements.",Suppressed rather than guessed. +P9-004,High,Analytics and consent,Inherited open,src/contracts/phase9/analytics-contract.ts; no vendor adapter,Before beta,Analytics + Legal,"Approve vendor, event authority, consent policy, retention, replay policy, and non-PII payloads.",Contract imported; collection disabled. +P9-005,High,Native linguistic review,Inherited open,"src/content/locales/{fr,ar}; CI locale parity",Before release,Content + Localization,"Native review of all visible copy, metadata, errors, and bidi samples.",Mechanical parity is not linguistic approval. +P9-006,High,Illustrative product preview,Inherited open,No preview shipped,Before release,Product + Design,Approve illustration or provide governed product capture.,Suppressed. +P9-007,High,Multi-location claim,Inherited open,scripts/validate-prohibited-content.mjs; visible shell only,Before beta,Product,Approve capability or revise/suppress affected copy.,No new claim introduced. +P9-008,High,Pricing model,Inherited open,No pricing route or component,Before pricing publication,Commercial,Approve public pricing and limits in writing.,Quote-only posture preserved by omission. +P9-009,High,Security evidence,Inherited open,No public security claims,Before claims publish,Security + Legal,"Provide scoped evidence, approvals, and expiry dates.","Security headers are implementation controls, not marketing claims." +P9-010,Medium,Framework selection,Resolved in Phase 10,docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md,Scaffold merge,Architecture,Architecture decision accepted and implemented.,"Next.js App Router SSR, strict TypeScript, CSS Modules, OCI target." +P9-011,Medium,Browser policy owner,Inherited open,.github/workflows/ci.yml; playwright.config.ts,Before beta,Product + Engineering,"Approve supported browser matrix, owner, telemetry, and exception/retirement process.","Configured matrix is a test baseline, not a policy claim." +P9-012,Medium,Product tour medium,Inherited open,No product tour implemented,Before release,Product + Marketing,Approve accessible localized dialog fallback or media/transcript.,Suppressed. +P9-013,Medium,Markets and formatting,Inherited open,src/lib/localization; no currency/phone market assumptions,Before regional campaign,Product + Legal,"Define markets, currency, timezone, phone, and jurisdiction independently of locale.",Locale is not treated as market. +P9-014,Medium,Login destination,Inherited open,No login link implemented,Before release,Product + Engineering,"Approve destination, security behavior, locale return path, and analytics.",Suppressed. +P9-015,Medium,Alternate sales contact,Inherited open,No secondary contact destination,Before release,Sales Ops,Provide approved contact route or approve suppression.,Placeholder address not imported into runtime. +P9-016,Medium,Customer evidence,Inherited open,"No logos, metrics, testimonials, or case studies",Optional post-launch,Marketing + Legal,Provide attributable evidence records and approvals.,Suppressed. +P9-017,Low,Exact dependency versions,Resolved in Phase 10,package.json; pnpm-lock.yaml; docs/DEPENDENCY_MANIFEST_v1.0.md,Scaffold,Engineering,"Exact versions pinned, audited, locked, and automated update review enabled.",No floating direct dependency ranges. +P10-001,High,Canonical production origin,Open,src/lib/localization/site-origin.ts; .env.example,Before production deployment,Product + Infrastructure,Approve public domain/origin and configure SITE_ORIGIN in production.,Build fails closed in production when missing. +P10-002,High,RentalDriveGo visual identity,Open,public/.gitkeep; docs/BRAND_MIGRATION_v1.0.md,Before public release,Product + Design,Approve and supply final accessible logo assets for light/dark contexts.,Old-name Phase 9 assets are retained only in immutable contracts and not shipped. +P10-003,Medium,Browser suite execution,Environment blocked locally,.github/workflows/ci.yml; tests/browser; tests/a11y; tests/visual,Before Phase 11 acceptance,Engineering + QA,Run configured Playwright matrix in unblocked CI; generate/review baselines; close all failures.,Local Chromium is administrator-blocked and browser download DNS failed. +P10-004,Low,Exact target runtime verification,Open verification,.github/workflows/ci.yml; Dockerfile; .node-version,Before scaffold merge,Engineering,Pass full quality and browser workflows on Node.js 24.17.0.,Local host exposes Node.js 22.16.0; target remains pinned to 24.17.0. +P11-001,High,Phase 11 browser verification,Environment blocked,tests/browser; tests/a11y; playwright.config.ts,Before Phase 11 acceptance,Engineering + QA,Install pinned dependencies and browsers in unblocked Node 24.17.0 CI; pass all functional and accessibility projects.,Static implementation is complete; execution evidence is not fabricated. +P11-002,High,Visual baseline generation and approval,Environment blocked,tests/visual; tests/visual/README.md,Before Phase 11 acceptance,Design + QA,Generate all Chromium snapshots with the pinned browser; review locale/theme/viewport/drawer/focus cases; commit approved baselines.,Scenario coverage exists but PNG baselines were not generated locally. +P11-003,Low,Exact Phase 11 target runtime verification,Open verification,package.json; .node-version; .github/workflows/ci.yml,Before Phase 11 merge,Engineering,"Run static, unit, build, package, and browser gates on Node 24.17.0 and pnpm 11.9.0.",Local host is Node 22.16.0 and could not download pnpm 11.9.0. +P11-004,Medium,Application-shell copy linguistic approval,Inherited open,src/content/locales/fr/shell.json; src/content/locales/ar/shell.json,Before release,Content + Localization,"Complete native French and Arabic review of Phase 11 shell, state, metadata, and pending-destination copy.",Mechanical parity passes; linguistic approval remains P9-005. +P12-001,High,Browser and accessibility execution,Environment blocked,tests/browser; tests/a11y; playwright.config.ts,Before Phase 12 acceptance,Engineering + QA,Run all 44 Chromium browser/accessibility scenarios and the approved cross-browser matrix in an environment where loopback navigation is not administrator-blocked; fix product failures.,Chromium launched locally but every loopback navigation was rejected with net::ERR_BLOCKED_BY_ADMINISTRATOR before application response. +P12-002,High,Visual regression baselines,Environment blocked,tests/visual; tests/fixtures/component-system/component-matrix.json,Before Phase 12 acceptance,Design + QA,Generate and review stable light/dark EN/FR/AR desktop/mobile/focus/error/long-content baselines with the pinned browser.,Visual scenarios are authored; image capture is blocked by the same Chromium loopback policy. +P12-003,Medium,Pinned runtime verification,Open verification,package.json; .node-version; .github/workflows/ci.yml,Before Phase 12 merge,Engineering,"Pass install, static, unit, build, browser, accessibility, visual, audit, and package gates on Node 24.17.0 and pnpm 11.9.0.",Source/static/unit/build checks passed under Node 22.16.0 with exact direct packages installed through npm fallback; target runtime remains unverified. +P12-004,Medium,Frozen installation and dependency audit,Environment blocked,pnpm-lock.yaml; package.json; docs/phase12/DEPENDENCY_CHANGE_REPORT_v1.0.md,Before Phase 12 merge,Engineering + Security,Complete pnpm install --frozen-lockfile and pnpm audit --audit-level low with registry access.,Registry DNS returned EAI_AGAIN. npm fallback enabled local checks but does not satisfy the frozen pnpm or audit gates. +P12-005,Medium,Manual assistive-technology and zoom QA,Open verification,docs/quality/PHASE_12_MANUAL_QA_RESULTS_v1.0.csv,Before Phase 12 acceptance,Accessibility + QA,"Complete keyboard, touch, screen-reader, 200/400 percent zoom, reduced-motion, forced-colors, locale, theme, and viewport manual matrix; attach evidence.","Static semantics, unit interactions, and server-rendered routes are verified; human browser and assistive-technology observations are not fabricated." +P13-001,High,Homepage browser accessibility and visual execution,Environment blocked,tests/browser/homepage.spec.ts; tests/a11y/homepage.a11y.spec.ts; tests/visual/homepage.visual.spec.ts,Before Phase 13 acceptance,Engineering + QA,"Run the authored homepage scenarios in unblocked pinned-browser CI; fix functional, axe, reflow, focus, and visual failures; approve baselines.",Local Chromium launches but rejects every loopback navigation with net::ERR_BLOCKED_BY_ADMINISTRATOR before application response. +P13-002,Medium,Phase 13 manual responsive and assistive-technology QA,Open verification,docs/quality/PHASE_13_MANUAL_QA_RESULTS_v1.0.csv,Before Phase 13 acceptance,Accessibility + QA,"Complete keyboard, touch, screen-reader, 200/400 percent zoom, reduced-motion, forced-colors, locale, theme, viewport, and content-expansion review; attach evidence.",Source and automated scenarios exist; human observations are not fabricated. +P13-003,Medium,Exact Phase 13 target runtime and package verification,Open verification,package.json; .node-version; pnpm-lock.yaml; .github/workflows/ci.yml,Before Phase 13 merge,Engineering + Security,"Pass frozen pnpm install, all validation suites, audit, build, and package verification on Node 24.17.0 and pnpm 11.9.0.",Available host is Node 22.16.0; npm fallback was used only to execute local checks. diff --git a/docs/PHASE_10_HANDOFF_v1.0.md b/docs/PHASE_10_HANDOFF_v1.0.md new file mode 100644 index 0000000..e4052bc --- /dev/null +++ b/docs/PHASE_10_HANDOFF_v1.0.md @@ -0,0 +1,68 @@ +# Phase 10 Handoff to Phase 11 + +## Handoff status + +Phase 10 repository bootstrap and architecture are complete. Phase 11 may implement approved homepage components and sections only after the CI browser job passes and must not bypass the inherited release gates. + +## Authoritative inputs for Phase 11 + +Read in this order: + +1. `docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md` +2. `docs/PHASE_10_IMPLEMENTATION_REPORT_v1.0.md` +3. `docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv` +4. `docs/quality/VALIDATION_RESULTS_v1.0.md` +5. `contracts/phase9/09_DEVELOPER_HANDOFF_v1.0.md` +6. `contracts/phase9/DECISION_LOG_v9.0.md` +7. `contracts/phase9/DEFINITION_OF_DONE_v1.0.md` +8. `src/contracts/phase9/route-manifest.json` +9. `src/contracts/phase9/component-contracts.ts` +10. `src/content/locales/{en,fr,ar}` + +When runtime copies and immutable Phase 9 history differ only because of the approved project rename, use the runtime RentalDriveGo copy. For design, behavior, evidence, and release policy, the immutable Phase 9 package remains authoritative unless a later recorded decision supersedes it. + +## Required Phase 11 entry gates + +Before merging homepage implementation: + +- Run the full CI workflow on Node.js 24.17.0. +- Install official Playwright browsers and pass functional and accessibility suites. +- Generate and review the three initial visual baselines. +- Confirm no critical/high regression from the implementation issue register. +- Keep `PUBLIC_RELEASE_APPROVED=false`. + +## Implementation rules that may not be weakened + +- Preserve server-rendered locale, `lang`, `dir`, theme, canonical, and `hreflang` behavior. +- Keep Arabic at document-level RTL and use logical CSS. +- Consume semantic tokens; do not add raw brand colors. +- Keep server components as the default and justify every client boundary. +- Do not add public claims, evidence, pricing, legal text, CRM behavior, analytics vendors, login destinations, or contact routes without resolving the corresponding issue. +- Do not import Phase 8 prototype source as production implementation. +- Do not disable validators to make a branch green. Fix the branch. + +## Phase 11 suggested sequence + +1. Pass the scaffold in clean CI and commit reviewed visual baselines. +2. Build foundational primitives from the Phase 9 component contracts. +3. Add header/navigation behavior without inventing unresolved destinations. +4. Implement homepage sections in approved order using locale resources and semantic tokens. +5. Add section-level unit, accessibility, RTL, responsive, and visual checks as each section lands. +6. Keep unavailable evidence-driven modules suppressed behind explicit approved content gates. + +## Commands + +```bash +corepack enable +corepack prepare pnpm@11.9.0 --activate +pnpm install --frozen-lockfile +pnpm check +SITE_ORIGIN=http://127.0.0.1:3000 PUBLIC_RELEASE_APPROVED=false pnpm build +pnpm test:e2e +``` + +`pnpm check` covers static quality and unit gates. Browser tests remain separate because they require installed browser binaries and a network environment not governed by an administrator-wide URL blocklist. + +## Exit condition for Phase 11 + +Phase 11 is not complete merely because sections render. It must preserve all Phase 10 gates, pass supported locale/theme/viewport scenarios, and leave every unresolved product or legal decision traceable rather than encoded as anonymous copy or dead links. diff --git a/docs/PHASE_10_IMPLEMENTATION_REPORT_v1.0.md b/docs/PHASE_10_IMPLEMENTATION_REPORT_v1.0.md new file mode 100644 index 0000000..fadc5dd --- /dev/null +++ b/docs/PHASE_10_IMPLEMENTATION_REPORT_v1.0.md @@ -0,0 +1,126 @@ +# Phase 10 Implementation Report + +## Executive status + +The RentalDriveGo repository foundation is implemented and buildable. It imports and validates the complete Phase 9 package, establishes server-rendered locale/direction/theme/metadata behavior, enforces a nonce-based CSP, pins the runtime and dependency graph, and includes CI, unit, browser, accessibility, visual, audit, and custom contract gates. + +**Phase 10 engineering scaffold status: complete with environmental verification exceptions.** + +**Public release status: blocked.** Critical and high Phase 9 product, research, legal, localization, analytics, CRM, evidence, and branding issues remain open. The repository deliberately emits `noindex` and disallows crawling until release approval is explicitly enabled. + +## Phase 9 package audit + +The uploaded package was extracted with path-safety checks and treated as immutable input. + +- Supplied Phase 9 validator: passed, 38 checks over 19 targets. +- Manifest: 61 payload entries. +- Size and SHA-256 verification: every manifested entry matched. +- Extracted package count: 62 files because the package manifest does not list itself. +- Immutable copy: `contracts/phase9`. + +No authoritative Phase 9 file was edited during the RentalDriveGo rename. + +## Architecture delivered + +- Next.js 16.2.9 App Router and React 19.2.7. +- Dynamic SSR for locale pages because per-request CSP nonces are required. +- Strict TypeScript 6.0.3. +- CSS Modules plus exact Phase 9 semantic token CSS. +- Server-first component boundary with client code limited to locale/theme interaction. +- Vendor-neutral OCI standalone deployment artifact. +- Node.js 24.17.0 and pnpm 11.9.0 pinned in repository, CI, and container. +- Exact direct dependency versions and frozen transitive lockfile. + +The accepted decision is recorded in `docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md`. + +## Imported contract package + +The repository contains: + +- immutable complete Phase 9 package under `contracts/phase9`; +- implementation locale catalogs for EN, FR, and AR; +- route manifest; +- exact design tokens and semantic CSS; +- component TypeScript contracts; +- analytics contract and event specification; +- demo-form contract; +- performance budgets; +- visual-regression scenarios; +- QA matrices, browser policy draft, accessibility checklist, and acceptance specifications. + +Runtime copies are placed under `src/contracts/phase9`. The original package remains the historical authority when a runtime copy is transformed for module naming or product branding. + +## Application shell delivered + +- Locale routes `/en`, `/fr`, `/ar`. +- Root negotiation from cookie, then `Accept-Language`, then English. +- Server-rendered `lang` and document-level `dir`. +- Server-readable theme preference with light/dark/system support. +- Pre-paint nonce-bearing theme bootstrap. +- CSP nonce propagated through the Next.js request lifecycle. +- Production CSP without `unsafe-inline` or `unsafe-eval`. +- Canonical and complete `hreflang` set, including `x-default`. +- Release-safe robots/noindex behavior. +- Locale switching with approved query-state and hash preservation only. +- Minimal localized shell and skip link, without beginning full homepage section implementation. + +## Validation and CI delivered + +Custom CI gates detect: + +1. Phase 9 checksum or validator failure. +2. Locale key, route, direction, or brand parity failure. +3. Route/canonical/`hreflang` divergence. +4. Token drift or raw brand-color introduction. +5. Physical left/right CSS declarations. +6. Placeholder destinations, simulated production success, or research-only production behavior. + +The GitHub Actions workflow runs validation, formatting, linting, strict type checking, unit coverage, package audit, production build, Playwright functional tests, accessibility scans, and visual regression. Dependabot proposes reviewed weekly dependency and action updates. + +## Actual execution results + +Passed locally: + +- Phase 9 supplied package validator. +- All Phase 9 file size and SHA-256 checks. +- Seven repository validators, including the Phase 10 package manifest gate. +- Prettier check. +- ESLint with zero warnings. +- Strict TypeScript check. +- 9 unit tests across 3 files. +- Unit coverage: 95.31% statements, 89.18% branches, 100% functions, 94.64% lines. +- Production build and standalone asset preparation. +- HTTP server-rendered shell smoke check. +- Package audit at low severity threshold with no known vulnerabilities. + +Environment-blocked locally: + +- Managed Chromium has an administrator `URLBlocklist` of `*`, causing `ERR_BLOCKED_BY_ADMINISTRATOR` for loopback pages. +- Playwright browser download fallback failed because `cdn.playwright.dev` DNS resolution returned `EAI_AGAIN`. +- The host exposes Node.js 22.16.0, while the repository, CI, and OCI target are pinned to Node.js 24.17.0. + +Therefore browser, accessibility, visual-baseline, and exact-target-runtime evidence must pass in CI before Phase 11 acceptance. These are recorded as open verification gates rather than falsely marked passed. + +Detailed machine-readable and narrative results are in `docs/quality/VALIDATION_RESULTS_v1.0.*`. + +## Corrections made during implementation + +Initial dependency selection used ESLint 10, but the pinned React/Next lint ecosystem was not compatible. ESLint was pinned to 9.39.4 instead of forcing incompatible peers. + +Next.js experimental typed routes generated a JSX namespace conflict with the pinned React and TypeScript types. The experiment was removed; deterministic route-manifest validation remains the route-safety authority. + +The first standalone test command used `next start`, which conflicts with Next's standalone output mode. The build now prepares static/public assets inside the standalone bundle and starts the generated Node server directly. + +The initial CSP style rule permitted `unsafe-inline`. It was replaced by a request nonce, and inline `colorScheme` mutation was removed in favor of CSS driven by theme data attributes. + +A vulnerable transitive PostCSS resolution was replaced with audited PostCSS 8.5.15 through a workspace override. The final low-threshold package audit is clean. + +## Unresolved release gates + +P9-010 and P9-017 are closed by this phase. All other Phase 9 issues remain explicit. Phase 10 adds gates for the production canonical origin, final RentalDriveGo visual identity, browser-suite execution, and exact target-runtime verification. + +The implementation register is `docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv`. + +## Scope boundary respected + +No full homepage sections, CRM endpoint, analytics vendor, public pricing, legal consent, login destination, sales address, customer evidence, security marketing claim, or prototype-only behavior was implemented. Omission here is intentional risk control, not missing enthusiasm. diff --git a/docs/PHASE_11_IMPLEMENTATION_REPORT_v1.0.md b/docs/PHASE_11_IMPLEMENTATION_REPORT_v1.0.md new file mode 100644 index 0000000..421b958 --- /dev/null +++ b/docs/PHASE_11_IMPLEMENTATION_REPORT_v1.0.md @@ -0,0 +1,346 @@ +# Phase 11 Implementation Report + +## 1. Executive summary + +Phase 11 implements the production foundation for RentalDriveGo design tokens, themes, localization, directionality, route generation, metadata, typography, responsive layout, application shell, accessibility utilities, and global route states. + +The implementation is integrated into the Phase 10 repository and packaged as a complete repository. Nine static repository gates pass. All 62 TypeScript and TSX source/test files pass a syntax transpilation scan. + +**Formal acceptance remains blocked.** The local host exposes Node.js 22.16.0 instead of the pinned 24.17.0, and `corepack prepare pnpm@11.9.0 --activate` could not fetch the pnpm package. Consequently, frozen installation, Prettier, ESLint, strict TypeScript 6.0.3, Vitest, production build, audit, Playwright, axe execution, and screenshot generation were not run. These are explicit P11 release gates, not imaginary green checks. + +## 2. Input files reviewed + +Primary Phase 10 inputs reviewed: + +- `docs/PHASE_10_HANDOFF_v1.0.md` +- `docs/PHASE_10_IMPLEMENTATION_REPORT_v1.0.md` +- `docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md` +- `docs/DEPENDENCY_MANIFEST_v1.0.md` +- `docs/IMPLEMENTATION_ISSUE_REGISTER_v1.0.csv` +- `PHASE_10_PACKAGE_MANIFEST_v1.0.json` +- `.github/workflows/ci.yml` +- `README.md` +- `package.json` and `pnpm-lock.yaml` + +Phase 9 authorities reviewed or consumed: + +- developer handoff and decision log; +- definition of done and open issue register; +- route manifest and localization implementation; +- English, French, and Arabic catalogs; +- design tokens, semantic token CSS, and token usage rules; +- component contracts, state matrix, responsive matrix, and RTL/theme matrix; +- accessibility, browser, performance, Playwright, and visual-regression specifications. + +## 3. Baseline validation results + +The Phase 10 report records a successful static/unit/build baseline with browser-environment exceptions. In this Phase 11 environment: + +```bash +node --version +# v22.16.0 + +corepack prepare pnpm@11.9.0 --activate +# failed fetching the pnpm tarball from registry.npmjs.org +``` + +Because the approved package manager could not be activated, Phase 10 dependency-driven commands were not rerun. The immutable Phase 9 package validator was rerun successfully and all 61 manifested payload checksums match. + +No `.env`, secret, cache, build output, coverage output, browser report, or test-result directory is included in the repository manifest. + +## 4. Architecture decisions applied + +`docs/architecture/ADR-0002_PHASE_11_FOUNDATIONS.md` records: + +- additive component-token layering without modifying Phase 9; +- cookie-canonical theme persistence with local-storage continuity; +- nonce-bearing pre-paint resolution plus CSS-only system fallback; +- route-ID-driven locale switching and metadata; +- typed server catalogs and a minimal client shell-catalog boundary; +- explicit market inputs for formatting; +- local variable font packages with script-specific metrics; +- server-first shell composition with interaction-only client boundaries; +- native dialog mobile navigation; +- noindex pending route shells instead of invented destinations; +- production-route Playwright fixtures instead of a new Storybook dependency. + +## 5. Token implementation + +The traceable token flow is: + +```text +Phase 9 raw token JSON +-> immutable Phase 9 semantic CSS +-> Phase 11 component-facing token layer +-> global styles and CSS Modules +``` + +`src/styles/component-tokens.css` adds required surface, text, border, interactive, focus, status, overlay, disabled, selection, skeleton, shadow, container, layering, typography, and layout roles. + +No Phase 9 token was removed, renamed, or corrected. Phase 11 additions are documented in `docs/TOKEN_IMPLEMENTATION_v1.0.md` and enforced by `scripts/validate-phase11-foundation.mjs`. + +## 6. Theme implementation + +Implemented preferences: + +- `light` +- `dark` +- `system` + +Behavior: + +- server reads `hpc-theme`; +- initial HTML exposes `data-theme-preference` and `data-theme`; +- a nonce-bearing head bootstrap resolves storage and system preference before interaction; +- explicit preferences ignore later operating-system changes; +- system mode tracks operating-system changes; +- cookie and local storage persist selection; +- same-window controls synchronize through a custom event; +- cross-tab changes synchronize through the storage event; +- a CSS media fallback keeps system-dark pages readable without JavaScript; +- no global theme transition is introduced. + +## 7. Localization and routing implementation + +Implemented: + +- locale roots `/en`, `/fr`, and `/ar`; +- route-manifest generation for home, login, privacy, terms, and accessibility; +- semantic route resolution from localized slugs and pathnames; +- locale switching that preserves only approved campaign parameters and valid hashes; +- locale cookie persistence; +- exact shell key parity across all three locales; +- typed server catalog loading; +- localized pending routes for unresolved approved paths; +- no hidden English fallback. + +Root detection remains cookie, then `Accept-Language`, then English. + +## 8. RTL implementation + +Arabic receives server-rendered `lang="ar"` and `dir="rtl"` before hydration. Application CSS passed the logical-property validator across 12 CSS files. The mobile drawer uses logical margins so its origin follows direction. Brand identity is not mirrored. + +`BidiText` and identifier-preservation utilities support mixed Latin/Arabic plates, VINs, phones, reservation IDs, URLs, and similar atomic values. + +## 9. Typography implementation + +- Inter Variable for English and French. +- Noto Sans Arabic Variable for Arabic. +- Component-facing display, heading, body, label, caption, line-height, and tracking roles. +- Arabic-specific line height and no forced Latin tracking. +- Semantic heading hierarchy independent of visual token size. +- Content-driven block sizing and browser zoom compatibility foundations. + +## 10. Application-shell implementation + +Header: + +- provisional text brand identity under the existing P10-002 gate; +- route-manifest home navigation; +- locale and theme controls; +- explicit unavailable login and demo treatments; +- sticky responsive composition; +- native modal mobile drawer below 1120 CSS px; +- Escape close, focus containment, background scroll lock, and focus return. + +Footer: + +- localized semantic groups; +- internal hash destinations from the home route; +- route-manifest legal and login links that open noindex pending shells; +- disabled contact and demo items rather than invented integrations; +- responsive stacked/grouped layout. + +The homepage remains a Phase 11 foundation matrix, not the complete production marketing homepage. Approved navigation hashes point to clearly marked deferred-section fixtures. + +## 11. Accessibility implementation + +Implemented: + +- skip link and stable `#main-content` target; +- visible `:focus-visible` treatment; +- semantic header, nav, main, sections, and footer landmarks; +- forced-colors focus support; +- reduced-motion behavior; +- visually hidden utility; +- accessible icon wrapper; +- live-region primitive; +- bidi isolation primitive; +- named icon-only controls; +- native dialog mobile navigation; +- localized loading, error, not-found, and pending states. + +Automated axe tests are authored for all locale/theme combinations. Execution remains P11-001. + +## 12. Metadata and SEO implementation + +`src/lib/metadata/build-metadata.ts` generates server metadata from locale and route ID: + +- localized title and description; +- self-referential canonical; +- reciprocal English, French, Arabic, and `x-default` alternates; +- Open Graph title, description, URL, site name, locale, and alternates; +- social summary metadata; +- release-safe robots behavior. + +Pending destinations are always noindex. No organization, review, rating, pricing, legal, address, phone, or contact structured data is emitted. + +## 13. Automated test results + +Executed: + +```bash +node scripts/run-validations.mjs +``` + +Result: **9 passed repository gates**. + +- Phase 9 immutable contract: pass, 61 checksums. +- Runtime and direct-dependency pins: pass, Node 24.17.0, pnpm 11.9.0, and 25 exact direct versions represented in the lockfile. +- Locale key/direction parity: pass. +- Route/runtime/hash/query/`hreflang` parity: pass, 5 route IDs. +- Phase 9 token integrity: pass. +- Phase 11 foundation token/shell integrity: pass. +- Logical CSS: pass, 12 files. +- Prohibited content: pass. +- Metadata foundation: pass. + +Executed syntax scan: + +- 62 TypeScript/TSX files transpiled without syntax errors using host TypeScript 5.8.3. + +Not executed because dependency installation was unavailable: + +- Prettier check; +- ESLint; +- strict TypeScript 6.0.3 project check; +- Vitest and coverage; +- production build; +- pnpm audit; +- Playwright functional suites; +- axe execution; +- visual snapshot comparison. + +Authored tests cover formatting, route resolution, theme persistence/system behavior, initial HTML, metadata, locale switching, pending routes, mobile navigation, skip focus, no-JavaScript behavior, responsive overflow, text expansion, accessibility, and visual matrices. + +## 14. Manual QA results + +Manual results are recorded in `docs/quality/MANUAL_QA_RESULTS_v1.0.csv`. + +Static inspections passed for route parity, document RTL, logical CSS, reduced-motion rules, bidi primitives, content-driven layouts, and locale expansion structure. + +Browser, assistive-technology, zoom, back/forward, theme persistence, mobile dialog, and production-build checks remain blocked pending an executable pinned environment. + +## 15. Visual-regression coverage + +Defined canonical scenarios: + +- desktop English light and dark; +- tablet French light and dark; +- mobile Arabic light and dark; +- mobile Arabic dark drawer open; +- desktop English keyboard focus. + +Generated baselines: **0**. + +No fake screenshots were created. The exact status is recorded in `docs/quality/VISUAL_REGRESSION_RESULTS_v1.0.json` and P11-002. + +## 16. Performance observations + +- No new runtime dependency was added. +- Server components remain the default. +- Client boundaries are limited to route-aware navigation, selectors, theme synchronization, global localized client states, and mobile navigation. +- Fonts remain self-hosted package assets. +- No analytics, CRM, media player, component-workbench, CSS-in-JS, or state-management runtime was introduced. +- Dynamic SSR remains inherited because request-specific CSP nonces are required. + +Measured build size and runtime performance were not available because the production build could not execute. + +## 17. Deviations from Phase 9 or Phase 10 + +Documented deviations/additions: + +1. A Phase 11 component-facing token layer was added because Phase 9 does not expose all required status, overlay, disabled, selection, skeleton, layout, and typography roles. +2. Phase 10’s package manifest remains a historical input. It is not used as the active integrity gate after legitimate Phase 11 source changes. Phase 11 has its own generated manifest and validator. +3. Storybook was not added because Phase 10 did not approve a workbench dependency. Production-route Playwright matrices and `tests/fixtures/foundation-matrix.json` are the approved equivalent. +4. Route-manifest legal and login paths render explicit pending shells because final content/destinations remain unresolved. + +No immutable Phase 9 file was changed. + +## 18. Open issues and release blockers + +The complete register is `docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv`. + +Phase 11-specific blockers: + +- P11-001: browser and accessibility execution; +- P11-002: screenshot generation and review; +- P11-003: exact Node 24.17.0/pnpm 11.9.0 verification; +- P11-004: native French and Arabic shell-copy review. + +Inherited Critical/High product, research, evidence, legal, localization, CRM, analytics, identity, and canonical-origin gates remain open. `PUBLIC_RELEASE_APPROVED` must remain false. + +## 19. Files added, modified, and removed + +The machine-readable list is `docs/quality/PHASE_11_FILE_CHANGES_v1.0.txt`. + +Against the Phase 10 ZIP, the final delta is 55 added files, 24 modified files, and 0 removed files. The exact list is `docs/quality/PHASE_11_FILE_CHANGES_v1.0.txt`; the generated Phase 11 package manifest is the authoritative complete inventory of 201 hashed payload files. + +## 20. Exact commands + +Install: + +```bash +corepack enable +corepack prepare pnpm@11.9.0 --activate +pnpm install --frozen-lockfile +``` + +Validate static foundations: + +```bash +pnpm validate +pnpm validate:package +``` + +Local package-manifest verification completed successfully for 201 payload files after generation. + +Validate quality and unit behavior: + +```bash +pnpm format:check +pnpm lint +pnpm typecheck +pnpm test:unit +pnpm audit --audit-level low +``` + +Build and run: + +```bash +SITE_ORIGIN=http://127.0.0.1:3000 PUBLIC_RELEASE_APPROVED=false pnpm build +HOSTNAME=127.0.0.1 PORT=3000 SITE_ORIGIN=http://127.0.0.1:3000 PUBLIC_RELEASE_APPROVED=false pnpm start +``` + +Browser and accessibility tests: + +```bash +pnpm exec playwright install --with-deps chromium firefox webkit +pnpm test:browser +pnpm test:a11y +pnpm test:e2e +``` + +Visual baselines: + +```bash +pnpm test:visual:update --project=chromium +pnpm test:visual --project=chromium +``` + +Regenerate and verify the package manifest only after all reviewed changes: + +```bash +pnpm manifest:generate +pnpm validate:package +``` diff --git a/docs/PHASE_12_HANDOFF_v1.0.md b/docs/PHASE_12_HANDOFF_v1.0.md new file mode 100644 index 0000000..931ee25 --- /dev/null +++ b/docs/PHASE_12_HANDOFF_v1.0.md @@ -0,0 +1,193 @@ +# Phase 12 Handoff: Reusable Product and Marketing Components + +## Handoff status + +Phase 11 source implementation is complete for tokens, theme, localization, routing, metadata, layout primitives, application shell, accessibility foundations, and global state shells. + +Formal Phase 11 acceptance remains blocked by P11-001, P11-002, and P11-003: the pinned Node/pnpm quality suite, browser/accessibility suite, and reviewed visual baselines must run in an unblocked environment. Do not treat a compiled placeholder as evidence that those gates closed. + +## Read first + +1. `docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md` +2. `docs/architecture/ADR-0002_PHASE_11_FOUNDATIONS.md` +3. `docs/PHASE_11_IMPLEMENTATION_REPORT_v1.0.md` +4. `docs/TOKEN_IMPLEMENTATION_v1.0.md` +5. `docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv` +6. `docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.md` +7. `contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md` +8. `contracts/phase9/components/RTL_THEME_MATRIX_v1.0.csv` +9. `contracts/phase9/components/RESPONSIVE_BEHAVIOR_MATRIX_v1.0.csv` +10. `src/content/locales/{en,fr,ar}` + +## Component directories and naming + +```text +src/components/app-shell/ persistent header, drawer, footer, controls, global states +src/components/foundation/ bidi, icon, live-region, and status primitives +src/components/layout/ container, section, stack, cluster, and responsive grid +src/components// Phase 12 reusable product or marketing components +``` + +Use PascalCase component files and matching `ComponentName.module.css` files. Keep one primary component per file. Do not add barrel exports by default. + +## Token consumption rules + +- Components consume roles from `src/styles/component-tokens.css`. +- Do not consume raw `--color-blue-*`, `--color-orange-*`, `--color-gray-*`, or other palette variables in component CSS. +- Do not add literal color functions or hexadecimal values outside token declarations. +- Do not edit `src/styles/tokens.css`; it is checksum-identical to the Phase 9 authority. +- New roles require a documented token migration and validator update. +- Orange remains limited to conversion and approved focus emphasis. + +## Theme rules + +- Use semantic/component tokens only; do not branch component markup by theme. +- Never add a global transition during theme changes. +- Test light and dark explicitly. Test system mode with operating-system changes. +- Do not write a second theme provider or persistence mechanism. +- Do not weaken the nonce-based CSP bootstrap. + +## Translation-key conventions + +- All visible production copy belongs in locale resources. +- Use semantic namespaces matching the component contract, such as `workflow.*` or `modules.*`. +- English, French, and Arabic must retain exact key and scalar-type parity. +- Do not add hidden English fallbacks. +- Arabic is formal Modern Standard Arabic and must receive native review under P9-005/P11-004. +- Components receive typed content props or the established typed message boundary; they do not fetch unrelated translations internally. + +## Route generation utilities + +Use functions from `src/lib/localization/config.ts`: + +- `localizedPath(routeId, locale)` +- `localeSwitchUrl(currentUrl, targetLocale, routeId)` +- `routeIdFromPathname(pathname)` +- `routeIdFromSlug(locale, slug)` +- `hreflangMap(origin, routeId)` + +Do not concatenate locale routes manually. Do not preserve unknown query parameters or unapproved hashes. + +## RTL rules + +- Arabic uses document-level `dir="rtl"` before hydration. +- Use logical CSS properties only. +- Use one DOM tree for all directions. +- Directional arrows and connectors may mirror when their meaning requires it. +- Brand marks, vehicle imagery, screenshots, checks, globes, charts, and media controls do not mirror automatically. +- Use `BidiText` for plates, VINs, reservation IDs, phones, URLs, email addresses, model codes, and mixed-direction values. + +## Typography utilities + +- Latin: Inter Variable stack. +- Arabic: Noto Sans Arabic stack with independent line height. +- Use component-facing type sizes and line-height tokens. +- Keep heading rank semantic; do not choose an `h` element for its visual size. +- Never use fixed text heights or image-based text. + +## Layout primitives + +Use `Container`, `Section`, `Stack`, `Cluster`, and `ResponsiveGrid` from `src/components/layout/LayoutPrimitives.tsx` before inventing local layout abstractions. + +Approved responsive gates remain: + +- compact: 320–767 CSS px +- medium: 768–1119 CSS px +- wide: 1120 CSS px and above + +Layouts remain content-driven and must pass English, long French, and Arabic independently. + +## Accessibility primitives and patterns + +- `BidiText` +- `AccessibleIcon` +- `LiveRegion` +- `StatusBadge` +- global `.visually-hidden` +- global skip navigation and `#main-content` +- native `` pattern demonstrated by `MobileNavigation` +- global `:focus-visible`, forced-colors, and reduced-motion foundations + +Icon-only controls require an accessible name. Decorative icons are hidden. Do not remove outlines or disable zoom. + +## Component API conventions + +- Props describe meaning, not visual implementation. +- Keep server components as the default. +- Add `'use client'` only for interaction, browser APIs, or client navigation state. +- Content models must tolerate expansion and missing evidence. +- Unsupported evidence suppresses a component or uses an explicitly approved neutral state. +- Do not invent destinations, claims, prices, metrics, logos, legal copy, or integrations. + +## Story and test pattern + +Phase 10 did not approve Storybook. Use the production shell and the equivalent fixture matrix in `tests/fixtures/foundation-matrix.json`. + +For each component add: + +1. unit tests for pure behavior and formatting; +2. browser keyboard and interaction tests; +3. axe coverage on representative rendered states; +4. responsive overflow checks at approved widths; +5. English, French, and Arabic coverage; +6. light and dark coverage; +7. RTL behavior checks; +8. canonical Chromium snapshots after review. + +## Open issues affecting Phase 12 + +At minimum, review P9-001 through P9-016, P10-001 through P10-004, and P11-001 through P11-004 in `docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv`. + +Particularly relevant component gates: + +- no demo form until CRM and legal consent are approved; +- no analytics adapter until vendor and consent rules are approved; +- no preview, customer evidence, security claims, public pricing, login URL, or sales contact until each owner closes its issue; +- no final public header/footer identity until RentalDriveGo logo assets are approved. + +## Files requiring an architecture decision before modification + +- `contracts/phase9/**` +- `src/styles/tokens.css` +- `src/contracts/phase9/**` +- `src/lib/security/csp.ts` +- `src/lib/theme/bootstrap-script.ts` +- `src/lib/theme/config.ts` +- `src/lib/localization/config.ts` +- `src/lib/metadata/build-metadata.ts` +- `src/proxy.ts` +- `next.config.ts` +- `package.json` dependency graph +- `playwright.config.ts` browser policy + +## Commands before and after each component change + +Before: + +```bash +pnpm install --frozen-lockfile +pnpm validate +pnpm typecheck +``` + +After: + +```bash +pnpm format:check +pnpm lint +pnpm typecheck +pnpm test:unit +SITE_ORIGIN=http://127.0.0.1:3000 PUBLIC_RELEASE_APPROVED=false pnpm build +pnpm test:e2e +``` + +Before packaging: + +```bash +pnpm manifest:generate +pnpm validate:package +``` + +## Phase 12 entry condition + +Do not begin merge acceptance until the Phase 11 browser suite and visual baselines run successfully in the pinned environment. Development may proceed behind the explicit gates, but release certainty may not be manufactured from optimism and a green syntax scan. diff --git a/docs/PHASE_12_IMPLEMENTATION_REPORT_v1.0.md b/docs/PHASE_12_IMPLEMENTATION_REPORT_v1.0.md new file mode 100644 index 0000000..f04a6da --- /dev/null +++ b/docs/PHASE_12_IMPLEMENTATION_REPORT_v1.0.md @@ -0,0 +1,177 @@ +# Phase 12 Implementation Report + +## 1. Executive summary + +Phase 12 implements a reusable, typed, accessible, localization-ready, theme-aware, RTL-native component system on the Phase 11 RentalDriveGo repository. It adds 52 implemented inventory entries across foundation, actions, forms, controls, overlays, feedback, surfaces, typography, navigation, media, product previews, workflows, comparisons, evidence, CTA, and section patterns. Seven entries remain blocked by product decisions and one optional toast component is deliberately excluded. + +The repository passes static validation, formatting, linting, strict TypeScript validation, 22 unit tests, coverage thresholds, and the production build under the available Node 22.16.0 host. Six standalone server routes return HTTP 200 with correct `lang` and `dir` values. Formal Phase 12 acceptance remains blocked because Node 24.17.0 was unavailable, frozen pnpm installation and audit were prevented by registry DNS failures, and Chromium was denied loopback navigation by administrator policy. Those conditions are recorded, not converted into fictional quality evidence. + +## 2. Authoritative inputs reviewed + +- Phase 11 repository and complete handoff package. +- `docs/PHASE_11_IMPLEMENTATION_REPORT_v1.0.md`. +- `docs/PHASE_12_HANDOFF_v1.0.md`. +- Phase 11 architecture, token, localization, RTL, metadata, CI, test, visual, issue, and package records. +- Immutable Phase 9 implementation contracts and 61-file checksum package. +- The Phase 12 implementation specification supplied with this task. + +## 3. Baseline repository validation + +The Phase 11 source and static contract were inspected before implementation. The host exposed Node 22.16.0 instead of the pinned 24.17.0. The exact pnpm 11.9.0 CLI was installed, but `pnpm install --frozen-lockfile` could not complete because registry DNS repeatedly returned `EAI_AGAIN`. An npm fallback installed the exact direct dependency versions without changing `package.json` or `pnpm-lock.yaml`, enabling real local compiler, test, and build execution. + +## 4. Component inventory summary + +- Total entries: 60. +- Implemented: 52. +- Blocked: 7. +- Excluded: 1 (`Toast`). +- Interactive entries: 19. +- Client-runtime entries: 9. +- Localization-required entries: 57. + +The machine-readable authority is `docs/phase12/COMPONENT_INVENTORY_v1.0.json`. + +## 5. Architecture and API decisions + +ADR-0003 and `DECISION_LOG_v12.0.md` record semantic CSS Modules, native platform primitives, server-first rendering, constrained intent-based APIs, a guarded component-lab route, an internal reviewed SVG icon map, no dependency additions, and explicit suppression of unresolved production content. + +## 6. Foundational utilities + +Implemented visually hidden content, accessible IDs, hydration-safe client state, media-query and reduced-motion observation, Escape handling, outside-click handling, scroll locking, bidi isolation, ref forwarding, and a reusable internal class-name helper. Focus behavior is kept close to the consuming control rather than buried in a universal abstraction with opinions about everything. + +## 7. Icon implementation + +`Icon` exposes approved names, semantic sizes, decorative/meaningful behavior, accessible labels, and explicit fixed-versus-mirrored direction behavior. Icons use semantic current color and do not automatically mirror brands, media controls, or vehicle/media imagery. + +## 8. Button and link implementation + +Buttons support primary, conversion, secondary, tertiary, ghost, destructive, link-style, icon-only, loading, disabled, icon placement, and responsive full-width treatment. Links support inline, navigation, standalone, external, skip, utility, disabled unresolved destinations, and direction-aware icons. Native semantics are preserved. + +## 9. Form-control implementation + +Implemented field wrappers, labels, required indicators, support/error text, text/email/telephone/URL inputs, textarea, native select, checkbox, radio, switch, fieldset/legend composition, form error summary, and count support. No transmission or final demo-form business logic is present. + +## 10. Selection and overlay implementation + +Implemented tabs, segmented controls, pagination, accordion/disclosure, dropdown menu, tooltip, and native-dialog foundations. Stateful controls expose selection programmatically. Tabs use RTL-aware horizontal keys without changing universal activation expectations. Dialogs define initial focus, constrained focus, Escape dismissal, scroll lock, inert background behavior, and focus return. + +## 11. Feedback and status implementation + +Implemented alert, inline alert, status badge, tag treatment, progress, spinner, skeleton, empty/error/success/information/warning state patterns, and live-region foundations. Toast is excluded because no approved critical use case justifies ephemeral information. + +## 12. Surface and content implementation + +Implemented card, interactive card, feature card, metric shell, evidence shell, media card foundations, comparison surfaces, panels, callouts, content containers, and semantic typography primitives. Fixed content heights and arbitrary colors are prohibited. + +## 13. Navigation implementation + +Implemented breadcrumbs, section/anchor navigation, footer link groups, current-page treatment, primary/mobile item foundations, and localized route-aware link behavior. Long French and Arabic labels wrap instead of losing critical meaning. + +## 14. Media implementation + +Implemented responsive image/media frames, aspect ratios, product screenshot shells, video-poster shells, decorative/meaningful image semantics, captions, and placeholder labeling. No unapproved customer photography, final product capture, or copyrighted asset is included. + +## 15. Product-preview implementation + +Implemented controlled marketing previews for reservation, vehicle/fleet state, workflow, return/maintenance alerts, dashboard stats, booking/calendar-like summaries, and responsive operations tables through composable preview shells and deterministic fictional fixtures. These are not functioning back-office screens and do not imply live data. + +## 16. Workflow and comparison implementation + +Workflow steps, connectors, timelines, numbered/icon sequences, stacked/horizontal presentation, fragmented-versus-connected comparisons, before/after, and capability pairing are implemented. Process chronology remains meaningful in Arabic; decorative connectors do not carry essential information. + +## 17. Evidence and CTA implementation + +Evidence models accept `approved`, `pending-review`, `research-only`, and `prohibited` status. Production rendering suppresses unapproved evidence. CTA patterns support primary, dual-action, inline, card, section, final, and contact-sales shells while preserving disabled unresolved destinations. + +## 18. Section-pattern implementation + +Implemented section headers, split content, media-and-copy, feature grid, metric/workflow/comparison/testimonial/CTA/FAQ shells, and alternating feature composition. Section order is not hard-coded and the complete homepage is intentionally not assembled. + +## 19. Localization validation + +Locale parity validation passes. Component content is supplied through typed props, locale catalogs, or guarded development fixtures. EN, FR, AR, long-content, formal Arabic, and mixed-direction identifiers are represented. Central formatting utilities remain the source of truth. + +## 20. RTL validation + +Arabic server HTML returns `dir="rtl"`. All component CSS passes the logical-property validator. Direction-sensitive icons opt into mirroring. Media, brands, universal controls, identifiers, and process meaning are handled deliberately rather than with blanket transforms. + +## 21. Theme validation + +Components consume semantic Phase 11 tokens and inherit light, dark, and system behavior. No raw brand-color API or second theming layer was introduced. + +## 22. Responsive validation + +CSS is content-driven across wide desktop, desktop, tablet, mobile, and narrow mobile targets. Automated browser scenarios cover 320, 390, 768, 1024, and 1440 CSS-pixel widths plus a 200-percent zoom equivalent, but execution remains environment-blocked. Source and standalone HTML checks pass; manual 200/400-percent zoom remains P12-005. + +## 23. Accessibility validation + +Components define names, roles, values, states, keyboard behavior, focus visibility, error relationships, live-region behavior, reduced-motion behavior, and touch-target foundations. Unit interaction tests pass. Automated axe and manual screen-reader runs are authored/recorded but blocked by the browser environment. + +## 24. Test results + +- Repository/static validation: pass, 10 gates. +- Formatting: pass. +- ESLint: pass with zero warnings. +- Strict TypeScript: pass. +- Unit tests: 22 passed, 0 failed, 0 skipped across 8 files. +- Coverage: 92.40% statements, 86.04% branches, 95.45% functions, 92.64% lines. +- Production build with an explicit local `SITE_ORIGIN`: pass. A build without `SITE_ORIGIN` fails closed as designed. +- Standalone HTTP matrix: 6 of 6 routes pass. +- Browser/accessibility: 44 scenarios discovered; execution blocked before application response by `ERR_BLOCKED_BY_ADMINISTRATOR`. + +## 25. Visual-regression results + +Representative light/dark, EN/FR/AR, desktop/mobile, focus, error, long-content, and RTL scenarios are authored. No PNG baseline is claimed. Generation and design approval remain P12-002. + +## 26. Manual QA results + +`docs/quality/PHASE_12_MANUAL_QA_RESULTS_v1.0.csv` records source/unit/server checks and explicit blocks for keyboard-only browser flow, touch, screen readers, zoom, and forced colors. Static inspection is not mislabeled as human assistive-technology testing. + +## 27. Performance and bundle impact + +No dependency was added. Only nine inventory entries require client runtime. Source grew from 62 files/148,035 bytes to 135 files/251,655 bytes. The built standalone output is 35 MiB, static output 1.5 MiB, and server output 9.7 MiB. See `docs/phase12/BUNDLE_IMPACT_REPORT_v1.0.md`. + +## 28. Dependency changes + +None. Exact direct versions and the pnpm lockfile remain unchanged. See `docs/phase12/DEPENDENCY_CHANGE_REPORT_v1.0.md`. + +## 29. Deviations from approved specifications + +- Storybook was not added; the Phase 11 approved guarded production-route fixture strategy remains in use. +- Toast is excluded because it is optional and no approved retained-information use case exists. +- Final demo form, pricing, testimonials, customer logos, final product media, login URL, and sales destination remain blocked rather than invented. +- Browser and visual acceptance evidence could not be generated under the host policy. + +## 30. Open issues and release blockers + +The cumulative register is `docs/IMPLEMENTATION_ISSUE_REGISTER_v1.2.csv`. New Phase 12 gates are P12-001 through P12-005. Inherited content, evidence, integration, legal, market, brand, and destination issues remain open. + +## 31. Files added, changed, and removed + +Added component families under `src/components/{actions,controls,feedback,forms,marketing,media,navigation,overlays,surfaces,typography}`, expanded foundations, guarded fixture content and route, tests, validators, ADR, inventories, matrices, reports, and handoff records. Existing shell and localization files were adjusted only to expose reusable component integration and fixture support. No approved Phase 9 contract file was modified. No production source file was removed. + +## 32. Commands required to install, validate, test, build, and run + +```bash +corepack enable +pnpm install --frozen-lockfile +pnpm validate +pnpm format:check +pnpm lint +pnpm typecheck +pnpm test:unit +pnpm test:browser +pnpm test:a11y +pnpm test:visual +SITE_ORIGIN=https://approved.example pnpm build +pnpm audit +COMPONENT_FIXTURES_ENABLED=true SITE_ORIGIN=http://127.0.0.1:3000 pnpm start +pnpm manifest:generate +pnpm validate:package +``` + +Executed results and evidence paths are in `docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.{md,json}`. + +## 33. Phase 13 readiness assessment + +Phase 13 development may assemble the homepage from the implemented components without redesigning the core system. Merge/release acceptance should not be declared until P12-001 through P12-005 are closed. Phase 13 must preserve the component APIs, semantic tokens, localization and route utilities, evidence-status policy, destination gates, fixture guard, and immutable Phase 9 contracts. diff --git a/docs/PHASE_13_HANDOFF_v1.0.md b/docs/PHASE_13_HANDOFF_v1.0.md new file mode 100644 index 0000000..521e960 --- /dev/null +++ b/docs/PHASE_13_HANDOFF_v1.0.md @@ -0,0 +1,212 @@ +# Phase 13 Handoff: Homepage Assembly + +## Handoff status + +The Phase 12 component source is implemented and usable for Phase 13 development. Static validation, formatting, lint, strict type checking, unit tests, coverage, production build, and standalone HTTP locale checks pass in the available environment. Formal Phase 12 acceptance remains gated by P12-001 through P12-005. + +## Authoritative inputs + +Read first: + +1. `docs/PHASE_12_IMPLEMENTATION_REPORT_v1.0.md` +2. `docs/phase12/COMPONENT_INVENTORY_v1.0.json` +3. `docs/phase12/COMPONENT_CATALOG_v1.0.md` +4. `docs/phase12/COMPONENT_SPECIFICATION_TRACEABILITY_v1.0.csv` +5. `docs/phase12/ACCESSIBILITY_BEHAVIOR_MATRIX_v1.0.csv` +6. `docs/phase12/RTL_BEHAVIOR_MATRIX_UPDATE_v1.0.csv` +7. `docs/phase12/RESPONSIVE_VALIDATION_MATRIX_v1.0.csv` +8. `docs/DECISION_LOG_v12.0.md` +9. `docs/IMPLEMENTATION_ISSUE_REGISTER_v1.2.csv` +10. `PHASE_12_PACKAGE_MANIFEST_v1.0.json` + +Earlier Phase 7 homepage composition, Phase 8 findings, Phase 9 contracts, and Phase 11 token/localization/shell foundations remain authoritative where Phase 12 does not supersede implementation detail. + +## Approved component inventory and import paths + +The exact import path, variants, accessibility behavior, RTL behavior, theme behavior, responsive behavior, prohibited usage, tests, limitations, and expected homepage consumers for every public component are documented in `docs/phase12/COMPONENT_CATALOG_v1.0.md` and the machine-readable inventory. + +Primary families: + +```text +@/components/actions/* +@/components/controls/* +@/components/feedback/* +@/components/forms/* +@/components/foundation/* +@/components/marketing/* +@/components/media/* +@/components/navigation/* +@/components/overlays/* +@/components/surfaces/* +@/components/typography/* +``` + +Do not duplicate a component because a page section wants a slightly different margin. Compose it or propose an explicit semantic variant. + +## Variant restrictions + +- Use semantic intents such as `conversion`, `secondary`, `available`, or `warning`. +- Do not expose arbitrary raw colors, shadows, radii, spacing, or classes as product APIs. +- Use `Button` for actions and `ActionLink` for navigation. +- Icon-only controls require accessible labels. +- Interactive cards may not contain independent nested interactive controls. +- Heading appearance is independent of semantic heading level. +- Evidence marked `research-only` or `prohibited` must never render as production proof. + +## Composition guidance + +Use explicit section patterns rather than one universal section with a landfill of Boolean props. Keep route composition responsible for copy, ordering, and content models. Components remain content-independent. The guarded component lab at `/{locale}/component-lab` shows representative composition when `COMPONENT_FIXTURES_ENABLED=true`. + +## Section-pattern inventory + +Approved patterns include `SectionHeader`, split content, media-and-copy, feature grid, workflow section, comparison section, metric/evidence strip, testimonial shell, FAQ shell, CTA section, and alternating feature section. Sticky media and bento layouts require Phase 7 approval before use. + +## Homepage section-to-component mapping + +| Homepage section | Primary components | +| --------------------------- | ------------------------------------------------------------------------ | +| Header verification | Existing `SiteHeader`, navigation items, locale/theme controls | +| Hero | `SectionHeader`, `CTAGroup`, `MediaFrame`, `ProductPreview` | +| Trust proof shell | `EvidenceShell`, `Metric`, logo/quote shells with governed status | +| Fragmented versus connected | `Comparison`, `ComparisonCard`, `Callout` | +| Rental workflow | `Workflow`, `WorkflowStep`, `SectionHeader` | +| Feature/capability sections | `FeatureGrid`, `FeatureCard`, media-and-copy pattern | +| Product UI previews | `ProductPreview`, responsive table/media shells, `BidiText` | +| Operational benefits | `Metric`, `Callout`, `FeatureCard` without unsupported quantified claims | +| Evidence/testimonial shells | `EvidenceShell`, quote shell, source note; approved content only | +| FAQ | FAQ/accordion section shell | +| Final CTA | CTA section, primary conversion action, disabled unresolved alternatives | +| Footer verification | Existing `SiteFooter`, footer link groups | + +## Translation and content locations + +- Runtime locale catalogs: `src/content/locales/{en,fr,ar}`. +- Guarded development fixtures: `src/content/development/component-lab.ts`. +- Homepage copy must be added as complete semantic messages, never concatenated fragments. +- Use existing format utilities for dates, numbers, currency, identifiers, and bidi isolation. +- Native French and Arabic review remains required under P9-005/P11-004. + +## Typed homepage content models + +Phase 13 should define route-level content objects that reference component semantics rather than presentation accidents. Evidence must use the Phase 12 `EvidenceStatus` model. Actions must distinguish navigational links from button actions and unresolved destinations. + +## Route-generation utilities + +Use the existing localization route manifest and route helpers. Do not hard-code locale prefixes or use `href="#"`. Preserve only approved campaign parameters during locale changes. Unknown login, demo, sales, tour, and contact destinations remain disabled or issue-linked. + +## Theme rules + +Consume semantic tokens only. All sections must pass light, dark, and system. Do not add page-local raw brand colors or global transitions. Conversion orange remains restricted to the dominant approved action. + +## RTL rules + +- Arabic uses true document-level RTL. +- Use logical properties. +- Mirror only semantically directional icons. +- Do not mirror brand marks, vehicle/product media, or universal media controls. +- Preserve process chronology and conceptual comparison meaning. +- Isolate plates, VINs, reservation IDs, phone numbers, email addresses, URLs, and currency values. + +## Responsive rules + +Validate 1440, 1024, 768, 390, and 320 CSS-pixel widths, reduced viewport height, landscape mobile where relevant, 200-percent zoom, required 400-percent reflow, long French/Arabic text, and RTL at each principal width. No horizontal page overflow is permitted. Component-level overflow must be explicit and accessible. + +## Accessibility rules + +Preserve heading hierarchy, landmarks, focus order, visible focus, touch targets, error descriptions, live-region restraint, reduced motion, forced-colors fallbacks, and logical reading order. Complete the P12 browser/axe/manual gates before acceptance. Automated tests do not replace keyboard and screen-reader review, a fact software teams rediscover with impressive regularity. + +## Image and media rules + +Use approved responsive image behavior with explicit intrinsic dimensions and alt semantics. Do not mirror media automatically. Final product screenshots, customer photography, logos, video, and poster assets remain blocked until approved. Development placeholders must remain unmistakably non-production. + +## Evidence-status handling + +Only approved evidence may render as production proof. Pending review may appear only in governed preview contexts. Research-only and prohibited evidence are suppressed from production rendering. Never invent metrics, quotes, customer names, logos, or quantified improvements to make a section feel complete. + +## CTA destination handling + +Use localized route and destination contracts. A missing destination renders disabled or development-marked behavior, not an empty link or guessed URL. Demo submission, CRM, analytics, consent, login, sales, and product-tour integrations remain outside Phase 13 unless separately approved. + +## Known blockers + +P12-001 through P12-005 plus inherited P9/P10/P11 content, evidence, legal, integration, branding, market, and destination issues. See `docs/IMPLEMENTATION_ISSUE_REGISTER_v1.2.csv`. + +## Files Phase 13 may modify + +- Add homepage composition under `src/app/[locale]`. +- Add localized homepage catalogs under `src/content/locales/{en,fr,ar}`. +- Add typed homepage content models under `src/content` or the approved route-content location. +- Add narrowly scoped component variants only when the existing API cannot express an approved design. +- Add homepage browser/a11y/visual tests and deterministic fixtures. +- Update Phase 13 reports, issue records, decision records, and package manifest. + +## Files Phase 13 must not modify without an architecture decision + +- `contracts/phase9/**`. +- Phase 11 semantic token foundations. +- Locale and route core utilities. +- Theme persistence/bootstrap behavior. +- CSP/security foundations. +- Existing component semantics or public APIs in breaking ways. +- Evidence suppression and unresolved-destination controls. +- Package manager, runtime pins, styling method, icon foundation, or testing stack. + +## Required validation commands + +```bash +pnpm install --frozen-lockfile +pnpm validate +pnpm format:check +pnpm lint +pnpm typecheck +pnpm test:unit +pnpm test:browser +pnpm test:a11y +pnpm test:visual +SITE_ORIGIN=https://approved.example pnpm build +pnpm audit +pnpm manifest:generate +pnpm validate:package +``` + +## Screenshot and visual-regression matrix + +At minimum capture the full homepage for: + +- EN light/dark desktop and mobile. +- FR light/dark desktop and mobile with long content. +- AR light/dark desktop and mobile with true RTL and mixed identifiers. +- Focus-visible navigation and primary CTA. +- Mobile drawer open. +- Evidence pending/suppressed development state. +- Error and unavailable destination states. +- 320 CSS-pixel and approved tablet widths. + +Stabilize dates, identifiers, animations, fonts, and fixtures before baseline generation. + +## Recommended homepage implementation order + +1. Header integration verification. +2. Hero. +3. Trust-proof shell. +4. Fragmented-versus-connected comparison. +5. End-to-end rental workflow. +6. Feature or capability sections. +7. Product UI previews. +8. Operational benefits. +9. Evidence or testimonial shells. +10. FAQ. +11. Final CTA. +12. Footer integration verification. + +## Phase 13 definition of done + +- The approved homepage sequence is assembled from Phase 12 components without duplicate component families. +- EN, FR, and AR content is externalized and reviewed. +- Arabic document RTL and mixed-direction identifiers are correct. +- Light, dark, and system themes pass. +- All approved responsive widths, zoom/reflow, reduced motion, and forced-colors checks pass. +- Browser, axe, visual, keyboard, touch, and screen-reader evidence is recorded. +- Unsupported claims, evidence, logos, testimonials, pricing, URLs, CRM, analytics, consent, and media remain blocked or suppressed. +- The production build and package manifest pass on Node 24.17.0 and pnpm 11.9.0. +- Open Critical/High issues are visible and release gates are not waived by silence. diff --git a/docs/PHASE_13_IMPLEMENTATION_REPORT_v1.0.md b/docs/PHASE_13_IMPLEMENTATION_REPORT_v1.0.md new file mode 100644 index 0000000..1d26efe --- /dev/null +++ b/docs/PHASE_13_IMPLEMENTATION_REPORT_v1.0.md @@ -0,0 +1,106 @@ +# Phase 13 Implementation Report + +## 1. Executive summary + +Phase 13 replaces the Phase 11 foundation placeholder at `/{locale}` with the complete RentalDriveGo marketing homepage assembled from the Phase 12 component system. The route now renders the approved narrative in English, French, and Arabic: hero, operational coverage, fragmented-versus-connected comparison, reservation-to-return workflow, operating roles, product modules, measurement framework, integrations, security evaluation, pricing preview, FAQ, and final CTA. + +The implementation preserves document-level Arabic RTL, light/dark/system themes, semantic tokens, logical CSS, route helpers, evidence controls, and unavailable-destination behavior. It does not invent customer proof, quantified outcomes, certifications, public prices, partner names, product captures, CRM behavior, analytics, legal consent, login, tour, sales, or demo destinations. + +Static validation, formatting, lint, strict type checking, 27 unit tests, coverage thresholds, production build, standalone preparation, and direct HTTP locale checks pass in the available environment. Formal acceptance remains blocked by browser policy, manual accessibility review, native linguistic approval, exact Node 24.17.0 execution, frozen pnpm completion, audit completion, and inherited product approvals. + +## 2. Authoritative inputs + +- `docs/PHASE_13_HANDOFF_v1.0.md`. +- `docs/PHASE_12_IMPLEMENTATION_REPORT_v1.0.md`. +- Phase 12 component inventory, catalog, accessibility, RTL, responsive, traceability, and issue records. +- Existing EN, FR, and AR homepage catalogs. +- Immutable Phase 9 contracts and Phase 11 token, theme, localization, route, metadata, security, and shell foundations. + +## 3. Homepage composition + +The route sequence is documented in `docs/phase13/HOMEPAGE_SECTION_MATRIX_v1.0.csv`. Header and footer hashes now resolve to real sections for `product`, `workflow`, `modules`, `pricing`, and `faq`. + +The implementation uses existing `ActionLink`, `Accordion`, `CTA`, `Comparison`, `FeatureCard`, `FeatureGrid`, `ProductPreview`, `SectionHeader`, `Workflow`, `Callout`, `Card`, typography, icon, container, section, and stack primitives. No duplicate public component family was introduced. + +## 4. Typed content model + +`src/content/homepage-model.ts` creates one typed `HomepageContent` object per locale. It converts localized pair and triple arrays into stable IDs and semantic records, fails closed on malformed content, supplies approved icon semantics, isolates product-preview identifiers, and requires unavailable reasons for unresolved actions. + +The route owns order and composition. Components remain locale-independent and content-independent. Details are in `docs/phase13/HOMEPAGE_CONTENT_MODEL_v1.0.md`. + +## 5. Hero and product preview + +The hero uses the approved conversion hierarchy while both actions remain disabled because destinations are unresolved. The product view is a deterministic illustrative `ProductPreview` built from fictional localized fixture content. The caption explicitly states that final screens require approved product data and captures. + +`ProductPreview` received one backward-compatible `headingLevel` prop. The default remains level 3; the hero uses level 2 to avoid a semantic jump from the page heading to a level-3 preview heading. The change is recorded in `docs/phase13/COMPONENT_VARIANT_UPDATE_v1.0.md`. + +## 6. Evidence, claims, pricing, and destinations + +- Operational coverage and capability descriptions are presented without customer proof. +- The results section publishes KPI definitions and measurement methodology, not invented values. +- Named integration partners are suppressed. +- Security certifications and service-level claims are suppressed. +- Public prices, discounts, packages, and limits are suppressed. +- Demo, tour, pricing, and sales actions are non-navigable and include localized unavailable reasons. +- No `href="#"`, guessed URL, root fallback navigation, CRM request, fake success state, or analytics adapter was added. + +## 7. Localization and RTL + +All visible route copy is read from the existing locale catalogs. English and French render LTR; Arabic renders with true document-level RTL. Page CSS uses logical declarations. Directional workflow icons use the existing mirroring contract, while product media and branding remain fixed. Vehicle identifiers remain separate left-to-right `BidiText` values. + +Native French and Arabic review remains required under P9-005 and P11-004. + +## 8. Responsive, theme, and accessibility implementation + +The route uses content-driven grids and switches two-column hero, integration, and pricing layouts to a single column below 768 CSS pixels. Actions become full width on compact mobile. Decorative hero transforms are removed in forced-colors and reduced-motion contexts. The implementation contains one page-level `h1`, coherent subsequent heading levels, native FAQ disclosures, visible focus inherited from the foundation, disabled-action reasons, and no page-local raw palette values. + +Authored tests cover 1440, 1024, 768, 390, and 320 widths through the existing responsive suite plus Phase 13 homepage scenarios. Browser execution remains blocked locally, so these scenarios are not presented as observed passes. + +## 9. Test additions + +- `tests/unit/homepage-content.test.ts`: five content-model and destination-policy tests. +- `tests/browser/homepage.spec.ts`: nine locale, section, disabled-action, bidi, anchor, and FAQ scenarios. +- `tests/a11y/homepage.a11y.spec.ts`: three locale axe scenarios plus heading-outline validation. +- `tests/visual/homepage.visual.spec.ts`: seven EN/FR/AR light/dark desktop/tablet/mobile/320 baselines. + +## 10. Validation results + +Passed: + +- Static repository validation through Phase 13. +- Prettier formatting check. +- ESLint with zero warnings. +- Strict TypeScript validation. +- 27 unit tests across 9 files. +- Coverage thresholds: 92.4 percent statements, 86.04 percent branches, 95.45 percent functions, and 92.64 percent lines. +- Next.js production build and standalone preparation. +- Direct HTTP 200 checks for EN, FR, and AR with correct `lang`, `dir`, and localized hero payloads. +- Phase 13 package manifest generation and verification. + +Blocked or open: + +- Frozen pnpm installation after registry `EAI_AGAIN` failures. +- Dependency audit because registry connectivity did not permit completion. +- Exact Node 24.17.0 verification because the available host is Node 22.16.0. +- Browser, axe, and visual execution because system Chromium rejects loopback navigation with `net::ERR_BLOCKED_BY_ADMINISTRATOR`. +- Manual keyboard, touch, screen-reader, zoom/reflow, reduced-motion, forced-colors, theme, RTL, and visual review. + +Detailed evidence is in `docs/quality/PHASE_13_VALIDATION_RESULTS_v1.0.{md,json}`, the HTTP result JSON, command log, manual matrix, and file-change list. + +## 11. Files changed + +The source delta adds the homepage content model, Phase 13 tests, validators, manifest scripts, decision and issue records, composition documentation, and quality evidence. It modifies the homepage route and stylesheet, package scripts and metadata, validation runner, and `ProductPreview` heading semantics. No file was deleted. The exact list is recorded in `docs/quality/PHASE_13_FILE_CHANGES_v1.0.txt`. + +## 12. Open gates + +Inherited P9, P10, P11, and P12 gates remain authoritative. Phase 13 adds: + +- P13-001: browser, axe, and visual execution in unblocked CI. +- P13-002: manual responsive and assistive-technology QA. +- P13-003: exact target runtime, frozen installation, audit, and package verification in the pinned environment. + +See `docs/IMPLEMENTATION_ISSUE_REGISTER_v1.3.csv`. + +## 13. Phase 14 readiness + +Phase 14 may proceed with approved integration or production-readiness work using this homepage as the assembled route baseline. It must not reinterpret disabled destinations, illustrative media, open evidence, unapproved pricing, or unresolved legal and analytics controls as completed merely because the page now looks like a product rather than a scaffolding accident. diff --git a/docs/TOKEN_IMPLEMENTATION_v1.0.md b/docs/TOKEN_IMPLEMENTATION_v1.0.md new file mode 100644 index 0000000..041bf46 --- /dev/null +++ b/docs/TOKEN_IMPLEMENTATION_v1.0.md @@ -0,0 +1,45 @@ +# Phase 11 Token Implementation + +## Authority and flow + +The immutable Phase 9 files remain the raw and semantic source authority: + +```text +src/contracts/phase9/design-tokens.json + -> src/styles/tokens.css + -> src/styles/component-tokens.css + -> component CSS Modules and global styles +``` + +`src/styles/tokens.css` remains byte-identical to `contracts/phase9/tokens/semantic-tokens_v1.0.css`. Phase 11 does not rename or edit those variables. + +## Phase 11 additions + +`src/styles/component-tokens.css` adds documented component-facing roles required by the Phase 11 scope: + +- page, primary, elevated, muted, and strong surfaces; +- primary, secondary, subdued, and inverse text; +- standard and strong borders; +- primary, conversion, danger, link, and focus roles; +- success, warning, error, and information states; +- overlay, disabled, selection, skeleton, and shadow roles; +- container, gutter, section spacing, header offset, and layer roles; +- display, heading, body, label, caption, line-height, and tracking roles. + +These are aliases over approved Phase 9 values. Status roles use the approved raw status ramps because Phase 9 did not expose complete semantic status aliases. This extension is additive and does not mutate the historical contract. + +## Consumption rules + +1. Component and page CSS consume Phase 11 component-facing tokens. +2. Raw palette variables are allowed only in `tokens.css` and `component-tokens.css`. +3. Literal color functions and hexadecimal values are prohibited outside token declaration files. +4. Orange remains reserved for conversion emphasis and focus where approved. +5. Physical directional properties remain prohibited. +6. Breakpoint literals remain the approved `768px` and `1120px` values because CSS custom properties cannot be used in media-query conditions. +7. Shadows, timing, radius, spacing, typography, and layout roles are centralized rather than repeated through components. + +## Automated enforcement + +- `scripts/validate-tokens.mjs` verifies the immutable Phase 9 token source and detects raw color values. +- `scripts/validate-phase11-foundation.mjs` verifies required Phase 11 roles and rejects raw palette consumption or literal colors in component styles. +- `scripts/validate-css-logical.mjs` rejects physical directional CSS. diff --git a/docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md b/docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md new file mode 100644 index 0000000..8b9d243 --- /dev/null +++ b/docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md @@ -0,0 +1,153 @@ +# ADR-0001: Repository Foundation and Runtime Architecture + +- **Status:** Accepted for Phase 10 +- **Date:** 2026-06-25 +- **Decision owners:** Architecture and Engineering +- **Supersedes:** Phase 9 open issues P9-010 and P9-017 +- **Scope:** Marketing-site repository foundation only + +## Context + +Phase 9 requires a server-rendered multilingual application that establishes locale, document direction, theme, metadata, canonical links, and `hreflang` before hydration. It also requires strict TypeScript, logical CSS, a CSP-compatible no-flash theme strategy, limited browser JavaScript, deterministic validation, and browser-based accessibility and visual checks. + +The project name changed from `homePageCar` to `RentalDriveGo` at Phase 10. The original Phase 9 package is retained byte-for-byte under `contracts/phase9`; implementation copies carry the new product name. Legacy cookie and storage identifiers remain intentionally unchanged because they are part of the approved Phase 9 technical contract and changing them would break continuity without an approved migration. + +## Decision + +### Application framework and rendering + +Use **Next.js 16.2.9 App Router** with **React 19.2.7** and **strict TypeScript 6.0.3**. + +All locale pages use dynamic server rendering. The request proxy creates a unique CSP nonce and forwards it through the request headers so Next.js can attach the nonce to framework scripts and styles. Dynamic rendering is accepted as the cost of correct per-request CSP nonces and pre-hydration locale/theme behavior. Static export is explicitly out of scope. + +The public route model is: + +```text +/ -> locale negotiation and redirect +/en -> English, LTR +/fr -> French, LTR +/ar -> Arabic, RTL +``` + +The route manifest in `src/contracts/phase9/route-manifest.json` is the route authority. The framework's experimental typed-route generator is not enabled because it produced an incompatible generated JSX namespace with the pinned React/TypeScript toolchain. Route integrity is instead enforced by deterministic manifest validation and browser tests. + +### Locale and direction + +The server resolves locale from an explicit route first. Root negotiation uses the first valid value from: + +1. `hpc-locale` cookie +2. `Accept-Language` +3. English fallback + +Each locale layout renders the correct `` and document-level `dir` value before hydration. Arabic uses `dir="rtl"`; application CSS uses logical properties. Atomic LTR values remain subject to the Phase 9 bidi-isolation contract when those components are implemented. + +### Theme and no-flash bootstrap + +Theme preference is `light`, `dark`, or `system` and is read server-side from `hpc-theme`. The server emits an initial theme attribute. A nonce-bearing inline bootstrap executes in `` before interactive components, resolves local storage and system color preference, and updates only `data-theme-preference` and `data-theme`. + +The CSP uses: + +```text +script-src 'self' 'nonce-{requestNonce}' 'strict-dynamic' +style-src 'self' 'nonce-{requestNonce}' +``` + +Production CSP does not permit `unsafe-inline` or `unsafe-eval`. Development alone permits `unsafe-eval` for the framework toolchain. Theme color-scheme behavior is expressed in CSS from the resolved data attribute, not through an inline style mutation. + +### Styling + +Use **CSS Modules** for component scope and global semantic CSS custom properties for tokens. `src/styles/tokens.css` remains checksum-identical to the Phase 9 source token file. Application styles may not introduce raw brand colors or physical left/right layout declarations. CI validators enforce both constraints. + +No runtime CSS-in-JS system or utility framework is included. That avoids a second token authority and unnecessary client/runtime cost. + +### Client JavaScript boundary + +Server components are the default. Client components are limited to current interaction boundaries: + +- locale selector +- theme controller and selector + +Future Phase 11 components may add client code only where interaction requires it. CRM submission, analytics, dialogs, product tour, and login routing are not implemented until their governing Phase 9 issues are approved. + +### Testing and quality stack + +- Unit and contract behavior: Vitest 4.1.9 with V8 coverage +- DOM component utilities: Testing Library +- Browser, accessibility, and visual checks: Playwright 1.61.1 +- Automated accessibility scan: axe-core through `@axe-core/playwright` +- Linting: ESLint 9.39.4 with Next.js and TypeScript rules +- Formatting: Prettier 3.8.4 +- Package audit: pnpm audit + +Canonical visual baselines use Chromium. Functional browser coverage is configured for Chromium, Firefox, WebKit, mobile Chromium, and mobile WebKit emulation. Phase 9's browser-policy ownership issue remains open; this configuration is a verification baseline, not a unilateral support-policy claim. + +### Package and runtime management + +Use **Node.js 24.17.0** and **pnpm 11.9.0**, pinned in `package.json`, `.node-version`, `.nvmrc`, and the CI workflow. All direct dependencies use exact versions. The lockfile is committed and CI installs with `--frozen-lockfile`. + +The pnpm workspace applies a 24-hour minimum package-release age, except for explicitly pinned packages selected during this architecture decision. Package build scripts are allowlisted. Dependabot opens reviewed update proposals rather than silently advancing versions. + +### Deployment target + +The deployable artifact is a **vendor-neutral OCI container** running the Next.js standalone Node server on Linux. No cloud provider, domain, CDN, region, or managed service is invented. The container is suitable for an approved OCI-compatible platform once infrastructure ownership is decided. + +Required runtime inputs: + +- `SITE_ORIGIN`: approved absolute public origin +- `PUBLIC_RELEASE_APPROVED`: remains `false` until release gates close +- `PORT`: defaults to `3000` +- `HOSTNAME`: defaults to `0.0.0.0` in the container + +When release approval is false, metadata is `noindex` and `robots.txt` disallows crawling. + +### Repository conventions + +```text +contracts/phase9/ immutable authoritative Phase 9 package +src/app/ App Router routes and metadata +src/components/ reusable application components +src/content/locales/ implementation locale resources +src/contracts/phase9/ runtime-consumable contract copies +src/lib/ localization, theme, and security primitives +src/styles/ exact tokens and global semantic CSS +scripts/ deterministic repository validators + tests/ unit, browser, accessibility, and visual tests + docs/ ADR, dependency record, issue register, reports +``` + +Files use UTF-8, LF line endings, strict TypeScript, named domain modules, and no barrel exports by default. Code paths may not silently resolve product, legal, analytics, security, pricing, evidence, or integration decisions. + +## Consequences + +Positive consequences: + +- Locale, direction, theme, and metadata are correct before hydration. +- The Phase 9 contract remains auditable and checksum-verifiable. +- CSP nonces work with the framework's server rendering model. +- The scaffold does not ship fabricated integrations, destinations, evidence, or claims. +- A vendor-neutral container avoids premature infrastructure lock-in. + +Costs and tradeoffs: + +- Per-request nonces force dynamic rendering and reduce static CDN opportunities. +- The app cannot be publicly released until critical and high Phase 9 issues close. +- The renamed product has no approved final logo asset; the shell uses a temporary text mark only. +- Browser and assistive-technology coverage still requires execution in approved CI/device environments. + +## Rejected alternatives + +- **Static export:** rejected because request-specific CSP nonces and server-readable preference cookies would be weakened. +- **Client-only locale/theme setup:** rejected because it would permit wrong-language, wrong-direction, or wrong-theme first paint. +- **Runtime CSS-in-JS or an unrelated utility token system:** rejected because it would create duplicate token authorities and more browser work. +- **Prototype conversion:** rejected by scope and because Phase 8 prototype behavior is research evidence, not production source. +- **Invented hosting provider or public domain:** rejected because neither is approved. + +## Primary references + +- Next.js Content Security Policy guide: https://nextjs.org/docs/app/guides/content-security-policy +- Next.js Proxy convention: https://nextjs.org/docs/app/getting-started/proxy +- Next.js metadata API: https://nextjs.org/docs/app/api-reference/functions/generate-metadata +- Next.js 16.2 release: https://nextjs.org/blog/next-16-2 +- Node.js downloads: https://nodejs.org/en/download/current +- pnpm 11 release: https://pnpm.io/blog/releases/11.0 +- Playwright release notes: https://playwright.dev/docs/release-notes diff --git a/docs/architecture/ADR-0002_PHASE_11_FOUNDATIONS.md b/docs/architecture/ADR-0002_PHASE_11_FOUNDATIONS.md new file mode 100644 index 0000000..54e85f1 --- /dev/null +++ b/docs/architecture/ADR-0002_PHASE_11_FOUNDATIONS.md @@ -0,0 +1,63 @@ +# ADR-0002: Phase 11 Foundation Architecture + +- **Status:** Accepted for implementation; browser evidence pending +- **Date:** 2026-06-25 +- **Scope:** Design tokens, theme, localization, routing, metadata, application shell, and global states +- **Supersedes:** No Phase 9 or Phase 10 product decision + +## Context + +Phase 11 must extend the Phase 10 repository without mutating the immutable Phase 9 contract, weakening CSP, inventing unresolved destinations, or creating a second styling, routing, or localization authority. + +## Decisions + +### Token pipeline + +Keep Phase 9 raw and semantic token files unchanged. Add `src/styles/component-tokens.css` as an additive component-facing layer. Application CSS may not consume raw palette tokens or literal colors. + +### Theme persistence and bootstrap + +Keep `hpc-theme` as the server-readable canonical preference and `hpc.theme.preference` as a client continuity copy. Preference remains distinct from resolved theme. The nonce-bearing head bootstrap resolves before paint. A CSS media-query fallback gives readable system-dark behavior when JavaScript is delayed or unavailable. Same-window theme selectors synchronize through a custom event; cross-tab selectors synchronize through the storage event. + +### Locale routing and negotiation + +The route path remains the active locale authority. Root negotiation uses the locale cookie, then `Accept-Language`, then English. Locale switching resolves the current semantic route ID, preserves only allowlisted campaign parameters, and preserves only hashes approved for that route. + +### Translation loading + +Server components load typed catalogs through `getMessages`. Interaction-only global states use a small client shell-catalog map. Missing-key and type parity remain CI failures. No runtime fallback silently substitutes English for French or Arabic. + +### Formatting + +Centralized `Intl` formatters require an explicit locale and, where relevant, time zone or currency. Language never implies market, country, currency, or jurisdiction. Gregorian dates and Latin digits remain the inherited baseline until product research approves alternatives. + +### Font loading + +Use the pinned local Fontsource variable packages for Inter and Noto Sans Arabic. Arabic receives its own line-height and does not inherit forced Latin metrics. + +### Application shell composition + +The locale layout owns document attributes, theme bootstrap, skip navigation, header, footer, and theme controller. The header is server-rendered except for route-aware navigation, selectors, and the native modal mobile drawer. The drawer uses `` for modal semantics, Escape behavior, background interaction blocking, and focus containment, with explicit focus return. + +### Unresolved destinations + +Authoritative route-manifest paths are generated for login and legal routes, but those pages render localized noindex pending shells. Demo, contact, and login actions do not receive invented production integrations. They remain visibly disabled or lead to an explicit pending route. + +### Metadata + +A single server helper generates canonical URLs, reciprocal `hreflang`, Open Graph locale data, social summary metadata, and release-safe robots behavior from route IDs. No structured organization, review, rating, pricing, or contact data is emitted. + +### CSS organization + +- `tokens.css`: immutable Phase 9 tokens +- `component-tokens.css`: Phase 11 component-facing roles +- `globals.css`: reset, typography, focus, selection, accessibility utilities +- CSS Modules: component and page layout + +### Visual regression + +Playwright Chromium is the canonical snapshot engine. Functional projects remain Chromium, Firefox, WebKit, mobile Chromium, and mobile WebKit. Snapshot generation and approval are blocked until the pinned browser environment can execute. + +## Consequences + +The application foundation is traceable and does not encode unresolved product decisions. The cost is an explicit set of pending route shells and disabled conversion destinations until owners close the inherited gates. Full acceptance still requires Node 24.17.0 CI, Playwright execution, and reviewed visual snapshots. diff --git a/docs/architecture/ADR-0003_PHASE_12_COMPONENT_SYSTEM.md b/docs/architecture/ADR-0003_PHASE_12_COMPONENT_SYSTEM.md new file mode 100644 index 0000000..07135dd --- /dev/null +++ b/docs/architecture/ADR-0003_PHASE_12_COMPONENT_SYSTEM.md @@ -0,0 +1,26 @@ +# ADR-0003: Phase 12 component-system architecture + +- Status: Accepted for implementation; release acceptance remains gated +- Date: 2026-06-25 +- Owners: Frontend architecture, design systems, accessibility + +## Context + +Phase 12 requires a reusable marketing component system without assembling the homepage or inventing unresolved product content. Phase 11 approved semantic CSS modules, native platform behavior, server components by default, and a production shell rather than Storybook. + +## Decision + +1. Keep CSS Modules as the only component styling method and consume only component-facing semantic tokens. +2. Use native HTML primitives where they provide reliable behavior: `button`, `a`, `details`, `progress`, form controls, and `dialog`. +3. Add client boundaries only to controls with state, browser APIs, keyboard roving focus, or overlays. +4. Use a guarded component-lab route as the approved Storybook-equivalent fixture surface. It returns not found unless `COMPONENT_FIXTURES_ENABLED=true`. +5. Implement the icon set as a small, tree-shakeable internal SVG map to avoid adding a second dependency or shipping an entire icon library. +6. Keep unresolved claims, destinations, customer evidence, pricing, CRM submission, and approved media represented as blocked inventory entries or disabled typed states. +7. Add Phase 12 inventory and manifest validators. The package dependency graph remains unchanged. + +## Consequences + +- Phase 13 receives stable import paths and explicit section patterns. +- Browser, accessibility, and visual fixtures are deterministic and cannot be exposed accidentally under the default production environment. +- The internal icon map requires deliberate review when adding icons, which is preferable to casual dependency archaeology. +- Runtime acceptance still depends on executing the pinned Node 24.17.0 and pnpm 11.9.0 suites in an environment with registry and browser access. diff --git a/docs/phase12/ACCESSIBILITY_BEHAVIOR_MATRIX_v1.0.csv b/docs/phase12/ACCESSIBILITY_BEHAVIOR_MATRIX_v1.0.csv new file mode 100644 index 0000000..423d158 --- /dev/null +++ b/docs/phase12/ACCESSIBILITY_BEHAVIOR_MATRIX_v1.0.csv @@ -0,0 +1,61 @@ +Component,Interactive,Name_role_state,Keyboard,Focus,Live_region,Touch_target,Automated_coverage,Manual_status +VisuallyHidden,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +BidiText,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +LiveRegion,No,Semantic HTML and typed accessible labels,N/A,N/A,"Intentional only for Alert, LiveRegion, loading and progress",44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Icon,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Button,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +ActionLink,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +FormField,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +TextInput,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +TextArea,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Select,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Checkbox,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Radio,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Switch,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Fieldset,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +ErrorSummary,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Tabs,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +SegmentedControl,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Accordion,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Pagination,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Dialog,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +DropdownMenu,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Tooltip,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Alert,No,Semantic HTML and typed accessible labels,N/A,N/A,"Intentional only for Alert, LiveRegion, loading and progress",44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Progress,No,Semantic HTML and typed accessible labels,N/A,N/A,"Intentional only for Alert, LiveRegion, loading and progress",44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Spinner,No,Semantic HTML and typed accessible labels,N/A,N/A,"Intentional only for Alert, LiveRegion, loading and progress",44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Skeleton,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +StateMessage,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +StatusBadge,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Card,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Panel,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Callout,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Heading,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Eyebrow,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Text,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Quote,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Breadcrumbs,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +SectionNavigation,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +FooterLinkGroup,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +MediaFrame,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +ResponsiveImage,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +SectionHeader,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +FeatureCard,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +FeatureGrid,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +SplitContent,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +MetricStrip,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +LogoStripShell,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Workflow,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Comparison,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +Metric,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +EvidenceShell,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +CTA,Yes,Semantic HTML and typed accessible labels,Native or documented arrow/Escape behavior,Visible global focus; return/constrain where applicable,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +ProductPreview,No,Semantic HTML and typed accessible labels,N/A,N/A,None,44 CSS px for controls,Representative axe fixture,Pending pinned browser/manual execution +DemoForm,No,Not rendered,N/A,N/A,N/A,N/A,Not applicable,Blocked +Toast,No,Not rendered,N/A,N/A,N/A,N/A,Not applicable,Blocked +PricingCard,No,Not rendered,N/A,N/A,N/A,N/A,Not applicable,Blocked +TestimonialContent,No,Not rendered,N/A,N/A,N/A,N/A,Not applicable,Blocked +CustomerLogoContent,No,Not rendered,N/A,N/A,N/A,N/A,Not applicable,Blocked +ApprovedProductCapture,No,Not rendered,N/A,N/A,N/A,N/A,Not applicable,Blocked +LoginDestination,No,Not rendered,N/A,N/A,N/A,N/A,Not applicable,Blocked +SalesDestination,No,Not rendered,N/A,N/A,N/A,N/A,Not applicable,Blocked diff --git a/docs/phase12/BUNDLE_IMPACT_REPORT_v1.0.md b/docs/phase12/BUNDLE_IMPACT_REPORT_v1.0.md new file mode 100644 index 0000000..1293819 --- /dev/null +++ b/docs/phase12/BUNDLE_IMPACT_REPORT_v1.0.md @@ -0,0 +1,22 @@ +# Phase 12 Bundle Impact Report + +## Measurement scope + +The repository has no dedicated analyzer plugin, so Phase 12 records reproducible source and production-output measurements rather than inventing treemap precision. + +| Measurement | Phase 11 | Phase 12 | Change | +| ----------------------------- | -----------------------------------: | -------: | -------------------: | +| Source files under `src` | 62 | 135 | +73 | +| Source bytes under `src` | 148,035 | 251,655 | +103,620 | +| Component source/style files | 25 | 93 | +68 | +| Production `.next/standalone` | Not measured in Phase 11 environment | 35 MiB | Baseline established | +| Production `.next/static` | Not measured in Phase 11 environment | 1.5 MiB | Baseline established | +| Production `.next/server` | Not measured in Phase 11 environment | 9.7 MiB | Baseline established | + +## Interpretation + +The source increase is expected because Phase 12 adds the reusable component system, fixtures, and documentation surface. No dependency was added. Client boundaries are limited to nine inventory entries, and the component-lab route is environment-gated. The production build completed and preserved route-level code splitting. + +## Follow-up gate + +Run the repository's future bundle analyzer, when configured, against a Phase 11 build produced on the same pinned runtime. Cross-environment directory sizes are not a substitute for JavaScript chunk comparison, despite how tempting that spreadsheet would be. diff --git a/docs/phase12/COMPONENT_CATALOG_v1.0.md b/docs/phase12/COMPONENT_CATALOG_v1.0.md new file mode 100644 index 0000000..dd86e19 --- /dev/null +++ b/docs/phase12/COMPONENT_CATALOG_v1.0.md @@ -0,0 +1,77 @@ +# Phase 12 Component Catalog + +All public components use semantic tokens, logical CSS, one locale-independent DOM tree, and typed semantic variants. The component-lab route is development-only and guarded by `COMPONENT_FIXTURES_ENABLED=true`. + +## Public component reference + +| Component | Import path | Purpose | Variants | Accessibility / RTL / responsive behavior | Do not use when | +| ------------------- | ------------------------------------------- | ----------------------------------------------------- | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | +| `VisuallyHidden` | `@/components/foundation/VisuallyHidden` | Reusable foundational utilities primitive or pattern. | default | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `BidiText` | `@/components/foundation/BidiText` | Reusable foundational utilities primitive or pattern. | default | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `LiveRegion` | `@/components/foundation/LiveRegion` | Reusable foundational utilities primitive or pattern. | polite, assertive | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Icon` | `@/components/foundation/Icon` | Reusable icon system primitive or pattern. | sm, md, lg, fixed, mirror | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Button` | `@/components/actions/Button` | Reusable actions primitive or pattern. | primary, conversion, secondary, tertiary, ghost, destructive, link, icon-only, loading | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `ActionLink` | `@/components/actions/ActionLink` | Reusable actions primitive or pattern. | inline, navigation, standalone, button-primary, button-conversion, muted, disabled | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `FormField` | `@/components/forms/FormField` | Reusable forms primitive or pattern. | required, optional, supporting, error | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `TextInput` | `@/components/forms/TextInput` | Reusable forms primitive or pattern. | text, email, telephone, url, search, invalid, disabled | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `TextArea` | `@/components/forms/TextInput` | Reusable forms primitive or pattern. | default, character-count, invalid, disabled | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Select` | `@/components/forms/TextInput` | Reusable forms primitive or pattern. | default, invalid, disabled | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Checkbox` | `@/components/forms/ChoiceControls` | Reusable forms primitive or pattern. | default, checked, invalid, disabled | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Radio` | `@/components/forms/ChoiceControls` | Reusable forms primitive or pattern. | default, checked, invalid, disabled | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Switch` | `@/components/forms/ChoiceControls` | Reusable forms primitive or pattern. | on, off, disabled | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Fieldset` | `@/components/forms/FormField` | Reusable forms primitive or pattern. | default | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `ErrorSummary` | `@/components/forms/ErrorSummary` | Reusable forms primitive or pattern. | error-list | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Tabs` | `@/components/controls/Tabs` | Reusable selection controls primitive or pattern. | automatic, manual, disabled-tab | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `SegmentedControl` | `@/components/controls/SegmentedControl` | Reusable selection controls primitive or pattern. | selected, disabled | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Accordion` | `@/components/controls/Accordion` | Reusable selection controls primitive or pattern. | open, closed | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Pagination` | `@/components/controls/Pagination` | Reusable selection controls primitive or pattern. | current, previous, next | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Dialog` | `@/components/overlays/Dialog` | Reusable overlays primitive or pattern. | modal, drawer, dismissible, non-dismissible | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `DropdownMenu` | `@/components/overlays/DropdownMenu` | Reusable overlays primitive or pattern. | open, closed, disabled-item, destructive-item | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Tooltip` | `@/components/overlays/Tooltip` | Reusable overlays primitive or pattern. | hover, focus | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Alert` | `@/components/feedback/Alert` | Reusable feedback primitive or pattern. | info, success, warning, error, inline | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Progress` | `@/components/feedback/Progress` | Reusable feedback primitive or pattern. | determinate, indeterminate | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Spinner` | `@/components/feedback/Loading` | Reusable feedback primitive or pattern. | loading | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Skeleton` | `@/components/feedback/Loading` | Reusable feedback primitive or pattern. | single-line, multi-line, reduced-motion | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `StateMessage` | `@/components/feedback/StateMessage` | Reusable feedback primitive or pattern. | empty, error, success, information | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `StatusBadge` | `@/components/foundation/StatusBadge` | Reusable feedback primitive or pattern. | neutral, info, success, warning, error | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Card` | `@/components/surfaces/Card` | Reusable surfaces primitive or pattern. | default, muted, elevated, strong, interactive | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Panel` | `@/components/surfaces/Card` | Reusable surfaces primitive or pattern. | default, muted, elevated, strong | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Callout` | `@/components/surfaces/Callout` | Reusable surfaces primitive or pattern. | information | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Heading` | `@/components/typography/Typography` | Reusable typography primitive or pattern. | display, section, subheading, levels-1-6 | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Eyebrow` | `@/components/typography/Typography` | Reusable typography primitive or pattern. | default | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Text` | `@/components/typography/Typography` | Reusable typography primitive or pattern. | lead, body, supporting, caption, label | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Quote` | `@/components/typography/Typography` | Reusable typography primitive or pattern. | with-citation, without-citation | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Breadcrumbs` | `@/components/navigation/Breadcrumbs` | Reusable navigation primitive or pattern. | current-page | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `SectionNavigation` | `@/components/navigation/SectionNavigation` | Reusable navigation primitive or pattern. | current-location, overflow | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `FooterLinkGroup` | `@/components/navigation/FooterLinkGroup` | Reusable navigation primitive or pattern. | resolved, disabled | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `MediaFrame` | `@/components/media/MediaFrame` | Reusable media primitive or pattern. | square, landscape, wide, portrait, auto, captioned, decorative | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `ResponsiveImage` | `@/components/media/MediaFrame` | Reusable media primitive or pattern. | meaningful, decorative, captioned | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `SectionHeader` | `@/components/marketing/SectionHeader` | Reusable section patterns primitive or pattern. | start, center | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `FeatureCard` | `@/components/marketing/FeatureCard` | Reusable marketing surfaces primitive or pattern. | default, primary, muted | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `FeatureGrid` | `@/components/marketing/SectionPatterns` | Reusable section patterns primitive or pattern. | responsive-grid | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `SplitContent` | `@/components/marketing/SectionPatterns` | Reusable section patterns primitive or pattern. | default, reverse | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `MetricStrip` | `@/components/marketing/SectionPatterns` | Reusable section patterns primitive or pattern. | responsive-strip | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `LogoStripShell` | `@/components/marketing/SectionPatterns` | Reusable section patterns primitive or pattern. | empty-shell, content | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Workflow` | `@/components/marketing/Workflow` | Reusable workflow primitive or pattern. | numbered, icon, stacked, horizontal | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Comparison` | `@/components/marketing/Comparison` | Reusable comparison primitive or pattern. | problem-solution, stacked, two-column | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A simpler native element or layout primitive already provides the required semantics. | +| `Metric` | `@/components/marketing/Evidence` | Reusable evidence primitive or pattern. | approved, pending-review, research-only, prohibited | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A blocked product decision or unsupported claim would be required. | +| `EvidenceShell` | `@/components/marketing/Evidence` | Reusable evidence primitive or pattern. | approved, pending-review, research-only, prohibited | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A blocked product decision or unsupported claim would be required. | +| `CTA` | `@/components/marketing/CTA` | Reusable calls to action primitive or pattern. | inline, card, section, primary-only, dual-action, disabled-destination | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A blocked product decision or unsupported claim would be required. | +| `ProductPreview` | `@/components/marketing/ProductPreview` | Reusable product previews primitive or pattern. | illustrative, empty, responsive-table | Semantic HTML; keyboard support when interactive; visible focus; logical CSS; localized content props; content-driven reflow at compact, medium, and wide gates. | A blocked product decision or unsupported claim would be required. | + +## Representative usage + +```tsx +import { Button } from '@/components/actions/Button'; +import { FeatureCard } from '@/components/marketing/FeatureCard'; + + + +``` + +## Prohibited usage + +- Do not pass raw colors, arbitrary spacing, untranslated fragments, unresolved URLs, or research-only evidence into production rendering. +- Do not use `Card` to turn every layout problem into a rectangle. Humanity has already done enough of that. +- Do not use `InteractiveCard` semantics for containers with multiple independent controls. This system intentionally does not provide that invalid abstraction. +- Do not enable the component-lab route in a public production deployment. diff --git a/docs/phase12/COMPONENT_INVENTORY_v1.0.json b/docs/phase12/COMPONENT_INVENTORY_v1.0.json new file mode 100644 index 0000000..7b38812 --- /dev/null +++ b/docs/phase12/COMPONENT_INVENTORY_v1.0.json @@ -0,0 +1,1439 @@ +{ + "schemaVersion": "1.0", + "phase": 12, + "entries": [ + { + "name": "VisuallyHidden", + "category": "foundational utilities", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": [], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": false, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["global accessibility"] + }, + { + "name": "BidiText", + "category": "foundational utilities", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": [], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["product previews", "metrics", "forms"] + }, + { + "name": "LiveRegion", + "category": "foundational utilities", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["polite", "assertive"], + "interactive": false, + "clientRuntimeRequired": true, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["forms", "status feedback"] + }, + { + "name": "Icon", + "category": "icon system", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["sm", "md", "lg", "fixed", "mirror"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": false, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["all sections"] + }, + { + "name": "Button", + "category": "actions", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": [ + "primary", + "conversion", + "secondary", + "tertiary", + "ghost", + "destructive", + "link", + "icon-only", + "loading" + ], + "interactive": true, + "clientRuntimeRequired": true, + "localizationRequired": false, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": true, + "interaction": true, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["hero", "final CTA", "dialogs", "forms"] + }, + { + "name": "ActionLink", + "category": "actions", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": [ + "inline", + "navigation", + "standalone", + "button-primary", + "button-conversion", + "muted", + "disabled" + ], + "interactive": true, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": true, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["header", "hero", "sections", "footer"] + }, + { + "name": "FormField", + "category": "forms", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["required", "optional", "supporting", "error"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": true, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["demo form", "contact form"] + }, + { + "name": "TextInput", + "category": "forms", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["text", "email", "telephone", "url", "search", "invalid", "disabled"], + "interactive": true, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": true, + "interaction": true, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["demo form", "contact form"] + }, + { + "name": "TextArea", + "category": "forms", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["default", "character-count", "invalid", "disabled"], + "interactive": true, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": true, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["demo form", "contact form"] + }, + { + "name": "Select", + "category": "forms", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["default", "invalid", "disabled"], + "interactive": true, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": true, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["demo form", "filters"] + }, + { + "name": "Checkbox", + "category": "forms", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["default", "checked", "invalid", "disabled"], + "interactive": true, + "clientRuntimeRequired": true, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": true, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["demo form", "consent"] + }, + { + "name": "Radio", + "category": "forms", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["default", "checked", "invalid", "disabled"], + "interactive": true, + "clientRuntimeRequired": true, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": true, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["demo form", "choice groups"] + }, + { + "name": "Switch", + "category": "forms", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["on", "off", "disabled"], + "interactive": true, + "clientRuntimeRequired": true, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": true, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["settings controls"] + }, + { + "name": "Fieldset", + "category": "forms", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["default"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["demo form"] + }, + { + "name": "ErrorSummary", + "category": "forms", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["error-list"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": true, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["demo form", "contact form"] + }, + { + "name": "Tabs", + "category": "selection controls", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["automatic", "manual", "disabled-tab"], + "interactive": true, + "clientRuntimeRequired": true, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": true, + "interaction": true, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["product previews", "capability sections"] + }, + { + "name": "SegmentedControl", + "category": "selection controls", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["selected", "disabled"], + "interactive": true, + "clientRuntimeRequired": true, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": true, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["product preview controls"] + }, + { + "name": "Accordion", + "category": "selection controls", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["open", "closed"], + "interactive": true, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": true, + "interaction": true, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["FAQ"] + }, + { + "name": "Pagination", + "category": "selection controls", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["current", "previous", "next"], + "interactive": true, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["future resource indexes"] + }, + { + "name": "Dialog", + "category": "overlays", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["modal", "drawer", "dismissible", "non-dismissible"], + "interactive": true, + "clientRuntimeRequired": true, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": true, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["product tour", "future forms"] + }, + { + "name": "DropdownMenu", + "category": "overlays", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["open", "closed", "disabled-item", "destructive-item"], + "interactive": true, + "clientRuntimeRequired": true, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": true, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["navigation", "utility actions"] + }, + { + "name": "Tooltip", + "category": "overlays", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["hover", "focus"], + "interactive": true, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": true, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["icon controls"] + }, + { + "name": "Alert", + "category": "feedback", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["info", "success", "warning", "error", "inline"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["forms", "global status"] + }, + { + "name": "Progress", + "category": "feedback", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["determinate", "indeterminate"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["product tour", "forms"] + }, + { + "name": "Spinner", + "category": "feedback", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["loading"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["buttons", "forms"] + }, + { + "name": "Skeleton", + "category": "feedback", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["single-line", "multi-line", "reduced-motion"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["product previews"] + }, + { + "name": "StateMessage", + "category": "feedback", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["empty", "error", "success", "information"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["route states", "product previews"] + }, + { + "name": "StatusBadge", + "category": "feedback", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["neutral", "info", "success", "warning", "error"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["product previews", "evidence"] + }, + { + "name": "Card", + "category": "surfaces", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["default", "muted", "elevated", "strong", "interactive"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["features", "roles", "modules", "metrics"] + }, + { + "name": "Panel", + "category": "surfaces", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["default", "muted", "elevated", "strong"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["product previews", "forms"] + }, + { + "name": "Callout", + "category": "surfaces", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["information"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["security", "pricing notes"] + }, + { + "name": "Heading", + "category": "typography", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["display", "section", "subheading", "levels-1-6"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["all sections"] + }, + { + "name": "Eyebrow", + "category": "typography", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["default"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["hero", "section headers"] + }, + { + "name": "Text", + "category": "typography", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["lead", "body", "supporting", "caption", "label"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["all sections"] + }, + { + "name": "Quote", + "category": "typography", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["with-citation", "without-citation"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["testimonial shell"] + }, + { + "name": "Breadcrumbs", + "category": "navigation", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["current-page"], + "interactive": true, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["secondary routes"] + }, + { + "name": "SectionNavigation", + "category": "navigation", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["current-location", "overflow"], + "interactive": true, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["long marketing routes"] + }, + { + "name": "FooterLinkGroup", + "category": "navigation", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["resolved", "disabled"], + "interactive": true, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["footer"] + }, + { + "name": "MediaFrame", + "category": "media", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["square", "landscape", "wide", "portrait", "auto", "captioned", "decorative"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["hero", "feature sections"] + }, + { + "name": "ResponsiveImage", + "category": "media", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["meaningful", "decorative", "captioned"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["hero", "feature sections"] + }, + { + "name": "SectionHeader", + "category": "section patterns", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["start", "center"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["all homepage sections"] + }, + { + "name": "FeatureCard", + "category": "marketing surfaces", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["default", "primary", "muted"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["roles", "modules", "capabilities"] + }, + { + "name": "FeatureGrid", + "category": "section patterns", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["responsive-grid"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["roles", "modules", "capabilities"] + }, + { + "name": "SplitContent", + "category": "section patterns", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["default", "reverse"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["hero", "alternating features"] + }, + { + "name": "MetricStrip", + "category": "section patterns", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["responsive-strip"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["evidence"] + }, + { + "name": "LogoStripShell", + "category": "section patterns", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["empty-shell", "content"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["trust proof"] + }, + { + "name": "Workflow", + "category": "workflow", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["numbered", "icon", "stacked", "horizontal"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["rental lifecycle"] + }, + { + "name": "Comparison", + "category": "comparison", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["problem-solution", "stacked", "two-column"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["fragmented-versus-connected"] + }, + { + "name": "Metric", + "category": "evidence", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["approved", "pending-review", "research-only", "prohibited"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": true, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["evidence", "operational benefits"] + }, + { + "name": "EvidenceShell", + "category": "evidence", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["approved", "pending-review", "research-only", "prohibited"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": true, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["trust proof", "testimonials"] + }, + { + "name": "CTA", + "category": "calls to action", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": [ + "inline", + "card", + "section", + "primary-only", + "dual-action", + "disabled-destination" + ], + "interactive": true, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": true, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["hero", "final CTA", "contact sales"] + }, + { + "name": "ProductPreview", + "category": "product previews", + "status": "implemented", + "sourceSpecification": [ + "Phase 12 prompt", + "contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md", + "docs/PHASE_12_HANDOFF_v1.0.md" + ], + "variants": ["illustrative", "empty", "responsive-table"], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": true, + "visual": true + }, + "openIssues": [], + "homepageConsumers": ["hero", "product UI previews"] + }, + { + "name": "DemoForm", + "category": "forms", + "status": "blocked", + "sourceSpecification": ["Phase 12 prompt", "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv"], + "variants": [], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": false, + "visual": false + }, + "openIssues": ["P9-002", "P9-003"], + "homepageConsumers": ["hero", "final CTA"] + }, + { + "name": "Toast", + "category": "feedback", + "status": "excluded", + "sourceSpecification": ["Phase 12 prompt", "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv"], + "variants": [], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": false, + "visual": false + }, + "openIssues": [], + "homepageConsumers": ["none; critical information must remain persistent"] + }, + { + "name": "PricingCard", + "category": "surfaces", + "status": "blocked", + "sourceSpecification": ["Phase 12 prompt", "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv"], + "variants": [], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": false, + "visual": false + }, + "openIssues": ["P9-008"], + "homepageConsumers": ["pricing preview"] + }, + { + "name": "TestimonialContent", + "category": "evidence", + "status": "blocked", + "sourceSpecification": ["Phase 12 prompt", "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv"], + "variants": [], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": false, + "visual": false + }, + "openIssues": ["P9-012"], + "homepageConsumers": ["testimonial section"] + }, + { + "name": "CustomerLogoContent", + "category": "evidence", + "status": "blocked", + "sourceSpecification": ["Phase 12 prompt", "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv"], + "variants": [], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": false, + "visual": false + }, + "openIssues": ["P9-012"], + "homepageConsumers": ["trust proof"] + }, + { + "name": "ApprovedProductCapture", + "category": "media", + "status": "blocked", + "sourceSpecification": ["Phase 12 prompt", "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv"], + "variants": [], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": false, + "visual": false + }, + "openIssues": ["P9-006"], + "homepageConsumers": ["hero", "product UI previews"] + }, + { + "name": "LoginDestination", + "category": "actions", + "status": "blocked", + "sourceSpecification": ["Phase 12 prompt", "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv"], + "variants": [], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": false, + "visual": false + }, + "openIssues": ["P9-015"], + "homepageConsumers": ["header", "footer"] + }, + { + "name": "SalesDestination", + "category": "actions", + "status": "blocked", + "sourceSpecification": ["Phase 12 prompt", "docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv"], + "variants": [], + "interactive": false, + "clientRuntimeRequired": false, + "localizationRequired": true, + "rtlReviewed": true, + "accessibilityReviewed": true, + "tests": { + "unit": false, + "interaction": false, + "accessibility": false, + "visual": false + }, + "openIssues": ["P9-016"], + "homepageConsumers": ["hero", "final CTA"] + } + ] +} diff --git a/docs/phase12/COMPONENT_SPECIFICATION_TRACEABILITY_v1.0.csv b/docs/phase12/COMPONENT_SPECIFICATION_TRACEABILITY_v1.0.csv new file mode 100644 index 0000000..163cb1a --- /dev/null +++ b/docs/phase12/COMPONENT_SPECIFICATION_TRACEABILITY_v1.0.csv @@ -0,0 +1,61 @@ +Component,Category,Status,Import_path,Source_specifications,Homepage_consumers,Open_issues +VisuallyHidden,foundational utilities,implemented,@/components/foundation/VisuallyHidden,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,global accessibility, +BidiText,foundational utilities,implemented,@/components/foundation/BidiText,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,product previews; metrics; forms, +LiveRegion,foundational utilities,implemented,@/components/foundation/LiveRegion,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,forms; status feedback, +Icon,icon system,implemented,@/components/foundation/Icon,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,all sections, +Button,actions,implemented,@/components/actions/Button,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,hero; final CTA; dialogs; forms, +ActionLink,actions,implemented,@/components/actions/ActionLink,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,header; hero; sections; footer, +FormField,forms,implemented,@/components/forms/FormField,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,demo form; contact form, +TextInput,forms,implemented,@/components/forms/TextInput,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,demo form; contact form, +TextArea,forms,implemented,@/components/forms/TextInput,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,demo form; contact form, +Select,forms,implemented,@/components/forms/TextInput,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,demo form; filters, +Checkbox,forms,implemented,@/components/forms/ChoiceControls,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,demo form; consent, +Radio,forms,implemented,@/components/forms/ChoiceControls,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,demo form; choice groups, +Switch,forms,implemented,@/components/forms/ChoiceControls,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,settings controls, +Fieldset,forms,implemented,@/components/forms/FormField,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,demo form, +ErrorSummary,forms,implemented,@/components/forms/ErrorSummary,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,demo form; contact form, +Tabs,selection controls,implemented,@/components/controls/Tabs,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,product previews; capability sections, +SegmentedControl,selection controls,implemented,@/components/controls/SegmentedControl,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,product preview controls, +Accordion,selection controls,implemented,@/components/controls/Accordion,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,FAQ, +Pagination,selection controls,implemented,@/components/controls/Pagination,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,future resource indexes, +Dialog,overlays,implemented,@/components/overlays/Dialog,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,product tour; future forms, +DropdownMenu,overlays,implemented,@/components/overlays/DropdownMenu,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,navigation; utility actions, +Tooltip,overlays,implemented,@/components/overlays/Tooltip,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,icon controls, +Alert,feedback,implemented,@/components/feedback/Alert,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,forms; global status, +Progress,feedback,implemented,@/components/feedback/Progress,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,product tour; forms, +Spinner,feedback,implemented,@/components/feedback/Loading,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,buttons; forms, +Skeleton,feedback,implemented,@/components/feedback/Loading,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,product previews, +StateMessage,feedback,implemented,@/components/feedback/StateMessage,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,route states; product previews, +StatusBadge,feedback,implemented,@/components/foundation/StatusBadge,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,product previews; evidence, +Card,surfaces,implemented,@/components/surfaces/Card,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,features; roles; modules; metrics, +Panel,surfaces,implemented,@/components/surfaces/Card,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,product previews; forms, +Callout,surfaces,implemented,@/components/surfaces/Callout,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,security; pricing notes, +Heading,typography,implemented,@/components/typography/Typography,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,all sections, +Eyebrow,typography,implemented,@/components/typography/Typography,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,hero; section headers, +Text,typography,implemented,@/components/typography/Typography,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,all sections, +Quote,typography,implemented,@/components/typography/Typography,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,testimonial shell, +Breadcrumbs,navigation,implemented,@/components/navigation/Breadcrumbs,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,secondary routes, +SectionNavigation,navigation,implemented,@/components/navigation/SectionNavigation,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,long marketing routes, +FooterLinkGroup,navigation,implemented,@/components/navigation/FooterLinkGroup,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,footer, +MediaFrame,media,implemented,@/components/media/MediaFrame,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,hero; feature sections, +ResponsiveImage,media,implemented,@/components/media/MediaFrame,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,hero; feature sections, +SectionHeader,section patterns,implemented,@/components/marketing/SectionHeader,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,all homepage sections, +FeatureCard,marketing surfaces,implemented,@/components/marketing/FeatureCard,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,roles; modules; capabilities, +FeatureGrid,section patterns,implemented,@/components/marketing/SectionPatterns,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,roles; modules; capabilities, +SplitContent,section patterns,implemented,@/components/marketing/SectionPatterns,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,hero; alternating features, +MetricStrip,section patterns,implemented,@/components/marketing/SectionPatterns,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,evidence, +LogoStripShell,section patterns,implemented,@/components/marketing/SectionPatterns,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,trust proof, +Workflow,workflow,implemented,@/components/marketing/Workflow,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,rental lifecycle, +Comparison,comparison,implemented,@/components/marketing/Comparison,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,fragmented-versus-connected, +Metric,evidence,implemented,@/components/marketing/Evidence,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,evidence; operational benefits, +EvidenceShell,evidence,implemented,@/components/marketing/Evidence,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,trust proof; testimonials, +CTA,calls to action,implemented,@/components/marketing/CTA,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,hero; final CTA; contact sales, +ProductPreview,product previews,implemented,@/components/marketing/ProductPreview,Phase 12 prompt; contracts/phase9/components/COMPONENT_CONTRACTS_v1.0.md; docs/PHASE_12_HANDOFF_v1.0.md,hero; product UI previews, +DemoForm,forms,blocked,Not implemented,Phase 12 prompt; docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv,hero; final CTA,P9-002; P9-003 +Toast,feedback,excluded,Not implemented,Phase 12 prompt; docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv,none; critical information must remain persistent, +PricingCard,surfaces,blocked,Not implemented,Phase 12 prompt; docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv,pricing preview,P9-008 +TestimonialContent,evidence,blocked,Not implemented,Phase 12 prompt; docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv,testimonial section,P9-012 +CustomerLogoContent,evidence,blocked,Not implemented,Phase 12 prompt; docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv,trust proof,P9-012 +ApprovedProductCapture,media,blocked,Not implemented,Phase 12 prompt; docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv,hero; product UI previews,P9-006 +LoginDestination,actions,blocked,Not implemented,Phase 12 prompt; docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv,header; footer,P9-015 +SalesDestination,actions,blocked,Not implemented,Phase 12 prompt; docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv,hero; final CTA,P9-016 diff --git a/docs/phase12/DEFINITION_OF_DONE_STATUS_v1.0.md b/docs/phase12/DEFINITION_OF_DONE_STATUS_v1.0.md new file mode 100644 index 0000000..359a54c --- /dev/null +++ b/docs/phase12/DEFINITION_OF_DONE_STATUS_v1.0.md @@ -0,0 +1,22 @@ +# Phase 12 Definition of Done Status + +## Satisfied in this implementation environment + +- Phase 11 static behavior and immutable Phase 9 checks remain intact. +- Formatting, linting, strict TypeScript validation, token/locale/route/RTL/component validation, 22 unit tests, coverage thresholds, production build with an explicit local origin, and standalone locale rendering pass. +- Required component families are implemented or explicitly blocked/excluded. +- Public APIs are typed and documented. +- Components consume semantic tokens and support EN, FR, AR, light/dark/system foundations, document RTL, keyboard semantics, focus states, responsive composition, long content, and deterministic fictional fixtures. +- No unsupported claim, testimonial, metric, logo, final destination, CRM transmission, analytics collection, consent integration, pricing logic, or authentication was introduced. +- Dependency additions: none. +- Component inventory, traceability, behavior matrices, reports, issue records, decision records, handoff, and package manifest are present. + +## Acceptance gates still open + +- P12-001: Browser and automated accessibility execution in an unblocked loopback environment. +- P12-002: Visual baseline generation and design approval. +- P12-003: Full suite on pinned Node 24.17.0. +- P12-004: Frozen pnpm installation and dependency audit with registry access. +- P12-005: Manual keyboard, touch, screen-reader, zoom, reduced-motion, and forced-colors matrix. + +Phase 13 development may proceed. Phase 12 release acceptance may not be declared until these gates close. diff --git a/docs/phase12/DEPENDENCY_CHANGE_REPORT_v1.0.md b/docs/phase12/DEPENDENCY_CHANGE_REPORT_v1.0.md new file mode 100644 index 0000000..ebac7e2 --- /dev/null +++ b/docs/phase12/DEPENDENCY_CHANGE_REPORT_v1.0.md @@ -0,0 +1,25 @@ +# Phase 12 Dependency Change Report + +## Result + +No direct production or development dependency was added, removed, or version-changed in Phase 12. The exact Phase 11 dependency graph and `pnpm-lock.yaml` are retained. + +## Rationale + +- Icons use a reviewed internal SVG map. +- Dialog and drawer behavior use native `dialog` plus existing React utilities. +- Tabs, accordion, segmented controls, menus, tooltips, and form primitives use platform semantics and existing React. +- CSS Modules remain the sole component styling method. +- Existing Vitest, Testing Library, Playwright, and axe packages cover automated tests. + +## Verification + +`scripts/validate-runtime-dependencies.mjs` confirms the exact pinned direct versions remain represented in the lockfile. `npm install --engine-strict=false --ignore-scripts --package-lock=false` was used only as a local fallback after registry failures prevented the required frozen pnpm installation. + +## Blocked gates + +- `pnpm install --frozen-lockfile`: blocked by registry DNS failures. +- `pnpm audit --audit-level low`: blocked by registry DNS failures and timed out after retry scheduling. +- Node 24.17.0 verification: unavailable on this host; Node 22.16.0 was used for local execution. + +These are tracked by P12-003 and P12-004. diff --git a/docs/phase12/RESPONSIVE_VALIDATION_MATRIX_v1.0.csv b/docs/phase12/RESPONSIVE_VALIDATION_MATRIX_v1.0.csv new file mode 100644 index 0000000..ba30f91 --- /dev/null +++ b/docs/phase12/RESPONSIVE_VALIDATION_MATRIX_v1.0.csv @@ -0,0 +1,95 @@ +Component_family,Scenario,Width_css_px,Expected_behavior,Automated_status,Manual_status +actions,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +actions,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +actions,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +actions,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +actions,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +calls to action,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +calls to action,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +calls to action,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +calls to action,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +calls to action,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +comparison,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +comparison,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +comparison,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +comparison,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +comparison,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +evidence,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +evidence,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +evidence,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +evidence,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +evidence,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +feedback,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +feedback,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +feedback,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +feedback,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +feedback,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +forms,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +forms,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +forms,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +forms,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +forms,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +foundational utilities,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +foundational utilities,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +foundational utilities,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +foundational utilities,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +foundational utilities,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +icon system,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +icon system,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +icon system,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +icon system,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +icon system,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +marketing surfaces,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +marketing surfaces,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +marketing surfaces,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +marketing surfaces,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +marketing surfaces,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +media,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +media,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +media,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +media,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +media,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +navigation,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +navigation,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +navigation,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +navigation,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +navigation,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +overlays,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +overlays,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +overlays,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +overlays,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +overlays,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +product previews,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +product previews,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +product previews,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +product previews,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +product previews,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +section patterns,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +section patterns,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +section patterns,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +section patterns,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +section patterns,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +selection controls,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +selection controls,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +selection controls,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +selection controls,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +selection controls,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +surfaces,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +surfaces,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +surfaces,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +surfaces,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +surfaces,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +typography,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +typography,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +typography,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +typography,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +typography,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +workflow,Narrow mobile,320,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +workflow,Mobile,390,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +workflow,Tablet,768,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +workflow,Standard desktop,1024,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +workflow,Wide desktop,1440,No page overflow; content-driven reflow; 44px controls; logical order,Fixture test authored; execution blocked by pnpm/browser availability,Pending +Cross-component,200% zoom,Variable,"No clipped text, hidden actions, or unexpected horizontal page overflow",Risk-based browser test authored where applicable,Pending +Cross-component,400% zoom equivalent at 320 CSS px,Variable,"No clipped text, hidden actions, or unexpected horizontal page overflow",Risk-based browser test authored where applicable,Pending +Cross-component,Reduced viewport height,Variable,"No clipped text, hidden actions, or unexpected horizontal page overflow",Risk-based browser test authored where applicable,Pending +Cross-component,Landscape mobile,Variable,"No clipped text, hidden actions, or unexpected horizontal page overflow",Risk-based browser test authored where applicable,Pending diff --git a/docs/phase12/RTL_BEHAVIOR_MATRIX_UPDATE_v1.0.csv b/docs/phase12/RTL_BEHAVIOR_MATRIX_UPDATE_v1.0.csv new file mode 100644 index 0000000..e611bd5 --- /dev/null +++ b/docs/phase12/RTL_BEHAVIOR_MATRIX_UPDATE_v1.0.csv @@ -0,0 +1,61 @@ +Component,Layout,Content_order,Icon_behavior,Motion,Mixed_direction,Review_status +VisuallyHidden,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,Not applicable,Reviewed +BidiText,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +LiveRegion,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Icon,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,Directional icons mirror; universal/media/brand symbols remain fixed,Direction-aware only where meaning changes,Not applicable,Reviewed +Button,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,Directional icons mirror; universal/media/brand symbols remain fixed,Direction-aware only where meaning changes,Not applicable,Reviewed +ActionLink,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,Directional icons mirror; universal/media/brand symbols remain fixed,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +FormField,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +TextInput,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +TextArea,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Select,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Checkbox,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Radio,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Switch,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Fieldset,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +ErrorSummary,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Tabs,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +SegmentedControl,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Accordion,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,Directional icons mirror; universal/media/brand symbols remain fixed,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Pagination,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,Directional icons mirror; universal/media/brand symbols remain fixed,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Dialog,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +DropdownMenu,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Tooltip,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Alert,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Progress,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Spinner,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Skeleton,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +StateMessage,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +StatusBadge,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Card,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Panel,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Callout,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Heading,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Eyebrow,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Text,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Quote,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Breadcrumbs,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,Directional icons mirror; universal/media/brand symbols remain fixed,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +SectionNavigation,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +FooterLinkGroup,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +MediaFrame,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +ResponsiveImage,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +SectionHeader,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +FeatureCard,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +FeatureGrid,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +SplitContent,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +MetricStrip,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +LogoStripShell,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Workflow,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,Directional icons mirror; universal/media/brand symbols remain fixed,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Comparison,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Metric,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +EvidenceShell,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +CTA,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +ProductPreview,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +DemoForm,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +Toast,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +PricingCard,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +TestimonialContent,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +CustomerLogoContent,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +ApprovedProductCapture,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +LoginDestination,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed +SalesDestination,Logical CSS properties; one DOM tree,Preserve semantic/process order; flex/grid follows document direction only where meaningful,No automatic mirroring,Direction-aware only where meaning changes,"Use BidiText for identifiers, email, phone, URL, plate and model codes",Reviewed diff --git a/docs/phase12/STORY_AND_FIXTURE_INVENTORY_v1.0.csv b/docs/phase12/STORY_AND_FIXTURE_INVENTORY_v1.0.csv new file mode 100644 index 0000000..fd8cb2c --- /dev/null +++ b/docs/phase12/STORY_AND_FIXTURE_INVENTORY_v1.0.csv @@ -0,0 +1,3 @@ +Fixture,Components,Locales,Themes,Widths,States,Location,Production_guard +Core component lab,"Actions, forms, tabs, accordion, dialog, menu, alerts, workflow, comparison, preview, evidence, CTA",en; fr; ar,light; dark; system,320; 390; 768; 1024; 1440,default; focus; disabled; loading; error; long-content; RTL,src/app/[locale]/component-lab,COMPONENT_FIXTURES_ENABLED=true +Deterministic content model,All component-lab copy and fictional IDs,en; fr; ar,N/A,N/A,long French; formal Arabic; mixed identifiers,src/content/development/component-lab.ts,Route guard diff --git a/docs/phase12/TEST_COVERAGE_REPORT_v1.0.csv b/docs/phase12/TEST_COVERAGE_REPORT_v1.0.csv new file mode 100644 index 0000000..56443b6 --- /dev/null +++ b/docs/phase12/TEST_COVERAGE_REPORT_v1.0.csv @@ -0,0 +1,9 @@ +Test_type,Path,Coverage,Artifact_status,Execution_status +Unit,tests/unit/components/actions.test.tsx,Button loading/name; icon-only label; disabled destination,Authored,Not executed: package manager unavailable +Unit,tests/unit/components/controls.test.tsx,Tabs keyboard; accordion semantics,Authored,Not executed +Unit,tests/unit/components/forms.test.tsx,Label/help/error relationships; summary links,Authored,Not executed +Unit,tests/unit/components/evidence.test.tsx,Evidence production suppression,Authored,Not executed +Type-level,tests/types/component-contracts.test-d.tsx,Icon-only label and metric model,Authored,Not executed +Browser,tests/browser/component-system.spec.ts,Locale/RTL/reflow/keyboard/dialog focus,Authored,Not executed +Accessibility,tests/a11y/component-system.a11y.spec.ts,Axe on en/fr/ar fixture,Authored,Not executed +Visual,tests/visual/component-system.visual.spec.ts,"en-light, fr-dark, ar-dark/mobile",Authored,Baselines not generated or approved diff --git a/docs/phase12/VARIANT_INVENTORY_v1.0.csv b/docs/phase12/VARIANT_INVENTORY_v1.0.csv new file mode 100644 index 0000000..21d228e --- /dev/null +++ b/docs/phase12/VARIANT_INVENTORY_v1.0.csv @@ -0,0 +1,177 @@ +Component,Status,Variant,Controlled_by,Production_restriction +VisuallyHidden,implemented,None,N/A,Blocked or excluded; see issue register +BidiText,implemented,None,N/A,Blocked or excluded; see issue register +LiveRegion,implemented,polite,Typed prop or semantic state,No arbitrary color or spacing override +LiveRegion,implemented,assertive,Typed prop or semantic state,No arbitrary color or spacing override +Icon,implemented,sm,Typed prop or semantic state,No arbitrary color or spacing override +Icon,implemented,md,Typed prop or semantic state,No arbitrary color or spacing override +Icon,implemented,lg,Typed prop or semantic state,No arbitrary color or spacing override +Icon,implemented,fixed,Typed prop or semantic state,No arbitrary color or spacing override +Icon,implemented,mirror,Typed prop or semantic state,No arbitrary color or spacing override +Button,implemented,primary,Typed prop or semantic state,No arbitrary color or spacing override +Button,implemented,conversion,Typed prop or semantic state,No arbitrary color or spacing override +Button,implemented,secondary,Typed prop or semantic state,No arbitrary color or spacing override +Button,implemented,tertiary,Typed prop or semantic state,No arbitrary color or spacing override +Button,implemented,ghost,Typed prop or semantic state,No arbitrary color or spacing override +Button,implemented,destructive,Typed prop or semantic state,No arbitrary color or spacing override +Button,implemented,link,Typed prop or semantic state,No arbitrary color or spacing override +Button,implemented,icon-only,Typed prop or semantic state,No arbitrary color or spacing override +Button,implemented,loading,Typed prop or semantic state,No arbitrary color or spacing override +ActionLink,implemented,inline,Typed prop or semantic state,No arbitrary color or spacing override +ActionLink,implemented,navigation,Typed prop or semantic state,No arbitrary color or spacing override +ActionLink,implemented,standalone,Typed prop or semantic state,No arbitrary color or spacing override +ActionLink,implemented,button-primary,Typed prop or semantic state,No arbitrary color or spacing override +ActionLink,implemented,button-conversion,Typed prop or semantic state,No arbitrary color or spacing override +ActionLink,implemented,muted,Typed prop or semantic state,No arbitrary color or spacing override +ActionLink,implemented,disabled,Typed prop or semantic state,No arbitrary color or spacing override +FormField,implemented,required,Typed prop or semantic state,No arbitrary color or spacing override +FormField,implemented,optional,Typed prop or semantic state,No arbitrary color or spacing override +FormField,implemented,supporting,Typed prop or semantic state,No arbitrary color or spacing override +FormField,implemented,error,Typed prop or semantic state,No arbitrary color or spacing override +TextInput,implemented,text,Typed prop or semantic state,No arbitrary color or spacing override +TextInput,implemented,email,Typed prop or semantic state,No arbitrary color or spacing override +TextInput,implemented,telephone,Typed prop or semantic state,No arbitrary color or spacing override +TextInput,implemented,url,Typed prop or semantic state,No arbitrary color or spacing override +TextInput,implemented,search,Typed prop or semantic state,No arbitrary color or spacing override +TextInput,implemented,invalid,Typed prop or semantic state,No arbitrary color or spacing override +TextInput,implemented,disabled,Typed prop or semantic state,No arbitrary color or spacing override +TextArea,implemented,default,Typed prop or semantic state,No arbitrary color or spacing override +TextArea,implemented,character-count,Typed prop or semantic state,No arbitrary color or spacing override +TextArea,implemented,invalid,Typed prop or semantic state,No arbitrary color or spacing override +TextArea,implemented,disabled,Typed prop or semantic state,No arbitrary color or spacing override +Select,implemented,default,Typed prop or semantic state,No arbitrary color or spacing override +Select,implemented,invalid,Typed prop or semantic state,No arbitrary color or spacing override +Select,implemented,disabled,Typed prop or semantic state,No arbitrary color or spacing override +Checkbox,implemented,default,Typed prop or semantic state,No arbitrary color or spacing override +Checkbox,implemented,checked,Typed prop or semantic state,No arbitrary color or spacing override +Checkbox,implemented,invalid,Typed prop or semantic state,No arbitrary color or spacing override +Checkbox,implemented,disabled,Typed prop or semantic state,No arbitrary color or spacing override +Radio,implemented,default,Typed prop or semantic state,No arbitrary color or spacing override +Radio,implemented,checked,Typed prop or semantic state,No arbitrary color or spacing override +Radio,implemented,invalid,Typed prop or semantic state,No arbitrary color or spacing override +Radio,implemented,disabled,Typed prop or semantic state,No arbitrary color or spacing override +Switch,implemented,on,Typed prop or semantic state,No arbitrary color or spacing override +Switch,implemented,off,Typed prop or semantic state,No arbitrary color or spacing override +Switch,implemented,disabled,Typed prop or semantic state,No arbitrary color or spacing override +Fieldset,implemented,default,Typed prop or semantic state,No arbitrary color or spacing override +ErrorSummary,implemented,error-list,Typed prop or semantic state,No arbitrary color or spacing override +Tabs,implemented,automatic,Typed prop or semantic state,No arbitrary color or spacing override +Tabs,implemented,manual,Typed prop or semantic state,No arbitrary color or spacing override +Tabs,implemented,disabled-tab,Typed prop or semantic state,No arbitrary color or spacing override +SegmentedControl,implemented,selected,Typed prop or semantic state,No arbitrary color or spacing override +SegmentedControl,implemented,disabled,Typed prop or semantic state,No arbitrary color or spacing override +Accordion,implemented,open,Typed prop or semantic state,No arbitrary color or spacing override +Accordion,implemented,closed,Typed prop or semantic state,No arbitrary color or spacing override +Pagination,implemented,current,Typed prop or semantic state,No arbitrary color or spacing override +Pagination,implemented,previous,Typed prop or semantic state,No arbitrary color or spacing override +Pagination,implemented,next,Typed prop or semantic state,No arbitrary color or spacing override +Dialog,implemented,modal,Typed prop or semantic state,No arbitrary color or spacing override +Dialog,implemented,drawer,Typed prop or semantic state,No arbitrary color or spacing override +Dialog,implemented,dismissible,Typed prop or semantic state,No arbitrary color or spacing override +Dialog,implemented,non-dismissible,Typed prop or semantic state,No arbitrary color or spacing override +DropdownMenu,implemented,open,Typed prop or semantic state,No arbitrary color or spacing override +DropdownMenu,implemented,closed,Typed prop or semantic state,No arbitrary color or spacing override +DropdownMenu,implemented,disabled-item,Typed prop or semantic state,No arbitrary color or spacing override +DropdownMenu,implemented,destructive-item,Typed prop or semantic state,No arbitrary color or spacing override +Tooltip,implemented,hover,Typed prop or semantic state,No arbitrary color or spacing override +Tooltip,implemented,focus,Typed prop or semantic state,No arbitrary color or spacing override +Alert,implemented,info,Typed prop or semantic state,No arbitrary color or spacing override +Alert,implemented,success,Typed prop or semantic state,No arbitrary color or spacing override +Alert,implemented,warning,Typed prop or semantic state,No arbitrary color or spacing override +Alert,implemented,error,Typed prop or semantic state,No arbitrary color or spacing override +Alert,implemented,inline,Typed prop or semantic state,No arbitrary color or spacing override +Progress,implemented,determinate,Typed prop or semantic state,No arbitrary color or spacing override +Progress,implemented,indeterminate,Typed prop or semantic state,No arbitrary color or spacing override +Spinner,implemented,loading,Typed prop or semantic state,No arbitrary color or spacing override +Skeleton,implemented,single-line,Typed prop or semantic state,No arbitrary color or spacing override +Skeleton,implemented,multi-line,Typed prop or semantic state,No arbitrary color or spacing override +Skeleton,implemented,reduced-motion,Typed prop or semantic state,No arbitrary color or spacing override +StateMessage,implemented,empty,Typed prop or semantic state,No arbitrary color or spacing override +StateMessage,implemented,error,Typed prop or semantic state,No arbitrary color or spacing override +StateMessage,implemented,success,Typed prop or semantic state,No arbitrary color or spacing override +StateMessage,implemented,information,Typed prop or semantic state,No arbitrary color or spacing override +StatusBadge,implemented,neutral,Typed prop or semantic state,No arbitrary color or spacing override +StatusBadge,implemented,info,Typed prop or semantic state,No arbitrary color or spacing override +StatusBadge,implemented,success,Typed prop or semantic state,No arbitrary color or spacing override +StatusBadge,implemented,warning,Typed prop or semantic state,No arbitrary color or spacing override +StatusBadge,implemented,error,Typed prop or semantic state,No arbitrary color or spacing override +Card,implemented,default,Typed prop or semantic state,No arbitrary color or spacing override +Card,implemented,muted,Typed prop or semantic state,No arbitrary color or spacing override +Card,implemented,elevated,Typed prop or semantic state,No arbitrary color or spacing override +Card,implemented,strong,Typed prop or semantic state,No arbitrary color or spacing override +Card,implemented,interactive,Typed prop or semantic state,No arbitrary color or spacing override +Panel,implemented,default,Typed prop or semantic state,No arbitrary color or spacing override +Panel,implemented,muted,Typed prop or semantic state,No arbitrary color or spacing override +Panel,implemented,elevated,Typed prop or semantic state,No arbitrary color or spacing override +Panel,implemented,strong,Typed prop or semantic state,No arbitrary color or spacing override +Callout,implemented,information,Typed prop or semantic state,No arbitrary color or spacing override +Heading,implemented,display,Typed prop or semantic state,No arbitrary color or spacing override +Heading,implemented,section,Typed prop or semantic state,No arbitrary color or spacing override +Heading,implemented,subheading,Typed prop or semantic state,No arbitrary color or spacing override +Heading,implemented,levels-1-6,Typed prop or semantic state,No arbitrary color or spacing override +Eyebrow,implemented,default,Typed prop or semantic state,No arbitrary color or spacing override +Text,implemented,lead,Typed prop or semantic state,No arbitrary color or spacing override +Text,implemented,body,Typed prop or semantic state,No arbitrary color or spacing override +Text,implemented,supporting,Typed prop or semantic state,No arbitrary color or spacing override +Text,implemented,caption,Typed prop or semantic state,No arbitrary color or spacing override +Text,implemented,label,Typed prop or semantic state,No arbitrary color or spacing override +Quote,implemented,with-citation,Typed prop or semantic state,No arbitrary color or spacing override +Quote,implemented,without-citation,Typed prop or semantic state,No arbitrary color or spacing override +Breadcrumbs,implemented,current-page,Typed prop or semantic state,No arbitrary color or spacing override +SectionNavigation,implemented,current-location,Typed prop or semantic state,No arbitrary color or spacing override +SectionNavigation,implemented,overflow,Typed prop or semantic state,No arbitrary color or spacing override +FooterLinkGroup,implemented,resolved,Typed prop or semantic state,No arbitrary color or spacing override +FooterLinkGroup,implemented,disabled,Typed prop or semantic state,No arbitrary color or spacing override +MediaFrame,implemented,square,Typed prop or semantic state,No arbitrary color or spacing override +MediaFrame,implemented,landscape,Typed prop or semantic state,No arbitrary color or spacing override +MediaFrame,implemented,wide,Typed prop or semantic state,No arbitrary color or spacing override +MediaFrame,implemented,portrait,Typed prop or semantic state,No arbitrary color or spacing override +MediaFrame,implemented,auto,Typed prop or semantic state,No arbitrary color or spacing override +MediaFrame,implemented,captioned,Typed prop or semantic state,No arbitrary color or spacing override +MediaFrame,implemented,decorative,Typed prop or semantic state,No arbitrary color or spacing override +ResponsiveImage,implemented,meaningful,Typed prop or semantic state,No arbitrary color or spacing override +ResponsiveImage,implemented,decorative,Typed prop or semantic state,No arbitrary color or spacing override +ResponsiveImage,implemented,captioned,Typed prop or semantic state,No arbitrary color or spacing override +SectionHeader,implemented,start,Typed prop or semantic state,No arbitrary color or spacing override +SectionHeader,implemented,center,Typed prop or semantic state,No arbitrary color or spacing override +FeatureCard,implemented,default,Typed prop or semantic state,No arbitrary color or spacing override +FeatureCard,implemented,primary,Typed prop or semantic state,No arbitrary color or spacing override +FeatureCard,implemented,muted,Typed prop or semantic state,No arbitrary color or spacing override +FeatureGrid,implemented,responsive-grid,Typed prop or semantic state,No arbitrary color or spacing override +SplitContent,implemented,default,Typed prop or semantic state,No arbitrary color or spacing override +SplitContent,implemented,reverse,Typed prop or semantic state,No arbitrary color or spacing override +MetricStrip,implemented,responsive-strip,Typed prop or semantic state,No arbitrary color or spacing override +LogoStripShell,implemented,empty-shell,Typed prop or semantic state,No arbitrary color or spacing override +LogoStripShell,implemented,content,Typed prop or semantic state,No arbitrary color or spacing override +Workflow,implemented,numbered,Typed prop or semantic state,No arbitrary color or spacing override +Workflow,implemented,icon,Typed prop or semantic state,No arbitrary color or spacing override +Workflow,implemented,stacked,Typed prop or semantic state,No arbitrary color or spacing override +Workflow,implemented,horizontal,Typed prop or semantic state,No arbitrary color or spacing override +Comparison,implemented,problem-solution,Typed prop or semantic state,No arbitrary color or spacing override +Comparison,implemented,stacked,Typed prop or semantic state,No arbitrary color or spacing override +Comparison,implemented,two-column,Typed prop or semantic state,No arbitrary color or spacing override +Metric,implemented,approved,Typed prop or semantic state,No arbitrary color or spacing override +Metric,implemented,pending-review,Typed prop or semantic state,No arbitrary color or spacing override +Metric,implemented,research-only,Typed prop or semantic state,No arbitrary color or spacing override +Metric,implemented,prohibited,Typed prop or semantic state,No arbitrary color or spacing override +EvidenceShell,implemented,approved,Typed prop or semantic state,No arbitrary color or spacing override +EvidenceShell,implemented,pending-review,Typed prop or semantic state,No arbitrary color or spacing override +EvidenceShell,implemented,research-only,Typed prop or semantic state,No arbitrary color or spacing override +EvidenceShell,implemented,prohibited,Typed prop or semantic state,No arbitrary color or spacing override +CTA,implemented,inline,Typed prop or semantic state,No arbitrary color or spacing override +CTA,implemented,card,Typed prop or semantic state,No arbitrary color or spacing override +CTA,implemented,section,Typed prop or semantic state,No arbitrary color or spacing override +CTA,implemented,primary-only,Typed prop or semantic state,No arbitrary color or spacing override +CTA,implemented,dual-action,Typed prop or semantic state,No arbitrary color or spacing override +CTA,implemented,disabled-destination,Typed prop or semantic state,No arbitrary color or spacing override +ProductPreview,implemented,illustrative,Typed prop or semantic state,No arbitrary color or spacing override +ProductPreview,implemented,empty,Typed prop or semantic state,No arbitrary color or spacing override +ProductPreview,implemented,responsive-table,Typed prop or semantic state,No arbitrary color or spacing override +DemoForm,blocked,None,N/A,Blocked or excluded; see issue register +Toast,excluded,None,N/A,Blocked or excluded; see issue register +PricingCard,blocked,None,N/A,Blocked or excluded; see issue register +TestimonialContent,blocked,None,N/A,Blocked or excluded; see issue register +CustomerLogoContent,blocked,None,N/A,Blocked or excluded; see issue register +ApprovedProductCapture,blocked,None,N/A,Blocked or excluded; see issue register +LoginDestination,blocked,None,N/A,Blocked or excluded; see issue register +SalesDestination,blocked,None,N/A,Blocked or excluded; see issue register diff --git a/docs/phase13/COMPONENT_VARIANT_UPDATE_v1.0.md b/docs/phase13/COMPONENT_VARIANT_UPDATE_v1.0.md new file mode 100644 index 0000000..13c8ad3 --- /dev/null +++ b/docs/phase13/COMPONENT_VARIANT_UPDATE_v1.0.md @@ -0,0 +1,7 @@ +# Phase 13 Component Variant Update + +## ProductPreview semantic heading level + +`ProductPreview` now accepts an optional `headingLevel` prop using the existing `HeadingLevel` type. The default remains level 3, preserving all Phase 12 consumers. Phase 13 passes level 2 in the hero so the document outline moves from the page level-1 heading to the preview heading without skipping a semantic level. + +This is a backward-compatible semantic variant. It does not add styling, raw tokens, duplicate components, or page-specific behavior to the component. diff --git a/docs/phase13/HOMEPAGE_CONTENT_MODEL_v1.0.md b/docs/phase13/HOMEPAGE_CONTENT_MODEL_v1.0.md new file mode 100644 index 0000000..99e20a5 --- /dev/null +++ b/docs/phase13/HOMEPAGE_CONTENT_MODEL_v1.0.md @@ -0,0 +1,39 @@ +# Phase 13 Homepage Content Model + +## Purpose + +`src/content/homepage-model.ts` converts each locale catalog into one typed route-level object. The route consumes component semantics rather than translation-array positions or presentation-only flags. + +## Inputs + +- `src/content/locales/{en,fr,ar}/homepage.json` +- `src/content/locales/{en,fr,ar}/shell.json` +- Phase 12 component contracts for icons, preview rows, actions, cards, workflow, comparison, and CTA behavior + +## Main types + +- `HomepageContent`: complete route composition contract. +- `HomepageAction`: action label plus mandatory unavailable reason for unresolved destinations. +- `TitledDescription`: stable ID, title, description, and optional approved icon. +- `HomepageWorkflowStep`: stable ID, ordinal, title, and description. +- `HomepageFaqItem`: stable ID, question, and answer. + +## Content transformation rules + +1. Catalog messages remain complete localized strings. No runtime concatenation creates translatable sentences. +2. Pair and triple helpers fail closed when required tuple content is absent. +3. Product preview rows use fictional operational fixtures already present in locale catalogs. +4. Vehicle identifiers remain separate `secondary` fields so `ProductPreview` isolates them with `BidiText`. +5. Demo, tour, pricing, and sales actions remain disabled and carry localized reasons from the shell contract. +6. Outcome metrics are represented as measurement definitions and methodology, not invented numeric values. +7. Integrations, security certifications, pricing values, customer names, logos, and testimonials remain absent until governed approval exists. + +## Route responsibilities + +`src/app/[locale]/page.tsx` owns section order, headings, anchors, and composition. Components remain content-independent. Locale prefixes are generated with `localizedPath`; raw or guessed destinations are not permitted. + +## Validation + +- `tests/unit/homepage-content.test.ts` verifies locale completeness, unresolved destination behavior, and identifier isolation. +- `scripts/validate-phase13-homepage.mjs` verifies approved composition, anchors, semantic tokens, route helpers, and required test artifacts. +- Browser, accessibility, and visual scenarios are authored under `tests/browser`, `tests/a11y`, and `tests/visual`. diff --git a/docs/phase13/HOMEPAGE_SECTION_MATRIX_v1.0.csv b/docs/phase13/HOMEPAGE_SECTION_MATRIX_v1.0.csv new file mode 100644 index 0000000..c860825 --- /dev/null +++ b/docs/phase13/HOMEPAGE_SECTION_MATRIX_v1.0.csv @@ -0,0 +1,13 @@ +Order,Section,Anchor,Primary_components,Content_source,Evidence_policy,Destination_policy,Responsive_notes,Status +1,Hero,product,"Heading; Text; ActionLink; ProductPreview",homepage.hero and homepage.preview,Illustrative preview only; no production capture,Demo and tour actions disabled until approved,"Two-column to single-column; 320px safe",Implemented +2,Operational coverage,,"SectionHeader; FeatureGrid; FeatureCard",homepage.trust,Describes workflow coverage; not customer proof,None,"Four-card responsive grid",Implemented +3,Fragmented versus connected,,"SectionHeader; Comparison",homepage.comparison,No quantified claims,None,"Two columns stack below 768px",Implemented +4,Rental workflow,workflow,"SectionHeader; Workflow",homepage.workflow,No performance claims,None,"Horizontal adaptive workflow; stacked mobile",Implemented +5,Operating roles,,"SectionHeader; FeatureGrid; FeatureCard",homepage.roles,No market-size claim,None,"Four-card responsive grid",Implemented +6,Product modules,modules,"SectionHeader; FeatureGrid; FeatureCard",homepage.modules,Capability wording remains subject to product approval,None,"Six-card responsive grid",Implemented +7,Measurement framework,,"SectionHeader; FeatureGrid; FeatureCard; Callout",homepage.results,Definitions and methodology only; no outcome values,None,"Cards reflow; methodology remains readable",Implemented +8,Integrations,,"SectionHeader; Card; Icon list",homepage.integrations,Named partners suppressed until verified,None,"Two-column split to single-column",Implemented +9,Security evaluation,,"SectionHeader; FeatureGrid; FeatureCard",homepage.security,No certification or SLA claims,None,"Four-card responsive grid",Implemented +10,Pricing preview,pricing,"SectionHeader; Card; ActionLink",homepage.pricing,No public prices or discounts,Request-pricing action disabled until destination approval,"Two-column split to single-column",Implemented +11,FAQ,faq,"SectionHeader; Accordion",homepage.faq,Answers preserve open qualification language,None,"Native details disclosures; reading-width container",Implemented +12,Final CTA,,CTA,homepage.final,No unsupported conversion promise,Demo and sales actions disabled until approved,"Actions stack full-width on mobile",Implemented diff --git a/docs/quality/MANUAL_QA_RESULTS_v1.0.csv b/docs/quality/MANUAL_QA_RESULTS_v1.0.csv new file mode 100644 index 0000000..f34217f --- /dev/null +++ b/docs/quality/MANUAL_QA_RESULTS_v1.0.csv @@ -0,0 +1,18 @@ +Test_ID,Area,Environment,Viewport,Locale,Theme,Result,Evidence_or_blocker +P11-MAN-001,Clean first load,Local Node 22.16.0,N/A,en,system,Blocked,"Pinned pnpm could not be downloaded; application server could not be built or started." +P11-MAN-002,Theme persistence,Unblocked browser required,Desktop,en,light/dark/system,Blocked,"Covered by automated test code; execution requires installed dependencies and browser." +P11-MAN-003,System theme response,Unblocked browser required,Desktop,en,system,Blocked,"CSP bootstrap and CSS fallback reviewed statically; browser execution pending." +P11-MAN-004,Locale switching,Unblocked browser required,Desktop,fr,light,Blocked,"Semantic route-switch test authored; execution pending." +P11-MAN-005,Direct localized routes,Static repository review,N/A,en/fr/ar,N/A,Pass,"Route manifest and runtime catch-all verified by node scripts/run-validations.mjs." +P11-MAN-006,JavaScript delayed or unavailable,Unblocked browser required,Mobile,ar,system,Blocked,"No-JavaScript Playwright test authored; execution pending." +P11-MAN-007,Keyboard-only navigation,Unblocked browser required,Desktop,en,light,Blocked,"Skip-link and drawer keyboard tests authored; execution pending." +P11-MAN-008,Screen-reader landmarks,Assistive technology environment required,Desktop,en,light,Blocked,"Semantic landmarks and names reviewed; manual announcement test pending." +P11-MAN-009,Zoom 200 and 400 percent,Unblocked browser required,320 CSS px,en/fr/ar,light/dark,Blocked,"Reflow tests authored at approved widths; manual browser zoom pending." +P11-MAN-010,Arabic reading order,Static source review,All,ar,light/dark,Pass,"Server document dir is rtl; logical CSS validator passes 12 CSS files." +P11-MAN-011,Mixed Arabic and Latin identifiers,Static unit design,N/A,ar,N/A,Pass,"BidiText primitive and identifier preservation utility implemented; browser announcement pending." +P11-MAN-012,Forced colors,Unblocked Windows browser required,Desktop,en,light,Blocked,"Forced-colors CSS exists; manual Windows verification pending." +P11-MAN-013,Reduced motion,Static source review,All,en/fr/ar,light/dark,Pass,"Global and skeleton reduced-motion rules are present and validator-clean." +P11-MAN-014,Mobile navigation,Unblocked browser required,390 px,ar,dark,Blocked,"Native dialog, Escape, focus return, and background lock test authored; execution pending." +P11-MAN-015,Long French and Arabic labels,Static content review,320 px,fr/ar,light/dark,Pass,"Content-driven layouts, wrapping, and no fixed text heights; browser overflow execution pending." +P11-MAN-016,Back and forward navigation,Unblocked browser required,Desktop,en/fr,light,Blocked,"Browser execution pending." +P11-MAN-017,Production build,Node 24.17.0 and pnpm 11.9.0 required,N/A,en/fr/ar,light/dark,Blocked,"Current host Node is 22.16.0 and registry fetch failed." diff --git a/docs/quality/PHASE_11_COMMAND_LOG_v1.0.txt b/docs/quality/PHASE_11_COMMAND_LOG_v1.0.txt new file mode 100644 index 0000000..8e0d53f --- /dev/null +++ b/docs/quality/PHASE_11_COMMAND_LOG_v1.0.txt @@ -0,0 +1,47 @@ +$ node --version +v22.16.0 + +$ corepack --version +0.32.0 + +$ corepack prepare pnpm@11.9.0 --activate +Preparing pnpm@11.9.0 for immediate activation... +Internal Error: Error when performing the request to https://registry.npmjs.org/pnpm/-/pnpm-11.9.0.tgz; for troubleshooting help, see https://github.com/nodejs/corepack#troubleshooting + at fetch (/opt/nvm/versions/node/v22.16.0/lib/node_modules/corepack/dist/lib/corepack.cjs:22051:11) + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) + at async fetchUrlStream (/opt/nvm/versions/node/v22.16.0/lib/node_modules/corepack/dist/lib/corepack.cjs:22081:20) + at async download (/opt/nvm/versions/node/v22.16.0/lib/node_modules/corepack/dist/lib/corepack.cjs:22204:18) + at async installVersion (/opt/nvm/versions/node/v22.16.0/lib/node_modules/corepack/dist/lib/corepack.cjs:22296:55) + at async Engine.ensurePackageManager (/opt/nvm/versions/node/v22.16.0/lib/node_modules/corepack/dist/lib/corepack.cjs:22847:32) + at async PrepareCommand.execute (/opt/nvm/versions/node/v22.16.0/lib/node_modules/corepack/dist/lib/corepack.cjs:23567:27) + at async PrepareCommand.validateAndExecute (/opt/nvm/versions/node/v22.16.0/lib/node_modules/corepack/dist/lib/corepack.cjs:20258:22) + at async _Cli.run (/opt/nvm/versions/node/v22.16.0/lib/node_modules/corepack/dist/lib/corepack.cjs:21195:18) + at async Object.runMain (/opt/nvm/versions/node/v22.16.0/lib/node_modules/corepack/dist/lib/corepack.cjs:23642:19) +exit=1 + +$ node scripts/run-validations.mjs +PASS: Phase 9 contract package is immutable and 61 payload checksums match. +PASS: Pinned Node 24.17.0, pnpm 11.9.0, and 25 exact direct dependency versions match the lockfile. +PASS: English, French, and Arabic catalogs have exact key parity and valid direction metadata. +PASS: 5 route IDs have complete locale, runtime, hash, query, and hreflang contracts. +PASS: Phase 9 semantic tokens are unchanged and application styles contain no raw palette colors. +PASS: Phase 11 component tokens, theme fallback, and application-shell foundations are present. +PASS: 12 CSS files use direction-safe logical declarations. +PASS: Runtime source contains no placeholder destination, simulated submission, or research-only backdoor. +PASS: Localized canonical, hreflang, Open Graph, social, and robots foundations are present. +exit=0 + +$ for f in scripts/*.mjs; do node --check "$f"; done +checked=17 failures=0 + +$ JSON parse scan +parsed=27 failures=0 + +$ TypeScript transpileModule syntax scan +transpiled=62 compiler=5.8.3 syntax_failures=0 + +$ node scripts/generate-phase11-manifest.mjs +Generated Phase 11 manifest for 201 files. + +$ node scripts/validate-phase11-manifest.mjs +PASS: Phase 11 package manifest verifies 201 repository files with no extras. diff --git a/docs/quality/PHASE_11_FILE_CHANGES_v1.0.txt b/docs/quality/PHASE_11_FILE_CHANGES_v1.0.txt new file mode 100644 index 0000000..171bba5 --- /dev/null +++ b/docs/quality/PHASE_11_FILE_CHANGES_v1.0.txt @@ -0,0 +1,89 @@ +# Phase 11 repository delta against the authoritative Phase 10 ZIP +added=55 +modified=24 +removed=0 + +[ADDED] +CONTRIBUTING.md +PHASE_11_PACKAGE_MANIFEST_v1.0.json +docs/IMPLEMENTATION_ISSUE_REGISTER_v1.1.csv +docs/PHASE_11_IMPLEMENTATION_REPORT_v1.0.md +docs/PHASE_12_HANDOFF_v1.0.md +docs/TOKEN_IMPLEMENTATION_v1.0.md +docs/architecture/ADR-0002_PHASE_11_FOUNDATIONS.md +docs/quality/MANUAL_QA_RESULTS_v1.0.csv +docs/quality/PHASE_11_COMMAND_LOG_v1.0.txt +docs/quality/PHASE_11_FILE_CHANGES_v1.0.txt +docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.json +docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.md +docs/quality/VISUAL_REGRESSION_RESULTS_v1.0.json +scripts/generate-phase11-manifest.mjs +scripts/validate-metadata.mjs +scripts/validate-phase11-foundation.mjs +scripts/validate-phase11-manifest.mjs +scripts/validate-runtime-dependencies.mjs +src/app/[locale]/[slug]/page.tsx +src/app/[locale]/error.tsx +src/app/[locale]/loading.tsx +src/app/[locale]/not-found.tsx +src/components/app-shell/BrandLink.tsx +src/components/app-shell/Controls.module.css +src/components/app-shell/DisabledAction.tsx +src/components/app-shell/HeaderNavigation.tsx +src/components/app-shell/LocalizedLoading.tsx +src/components/app-shell/LocalizedNotFound.tsx +src/components/app-shell/MobileNavigation.tsx +src/components/app-shell/SiteFooter.module.css +src/components/app-shell/SiteFooter.tsx +src/components/app-shell/StateShell.module.css +src/components/app-shell/StateShell.tsx +src/components/foundation/AccessibleIcon.tsx +src/components/foundation/BidiText.module.css +src/components/foundation/BidiText.tsx +src/components/foundation/LiveRegion.module.css +src/components/foundation/LiveRegion.tsx +src/components/foundation/StatusBadge.module.css +src/components/foundation/StatusBadge.tsx +src/components/layout/LayoutPrimitives.module.css +src/components/layout/LayoutPrimitives.tsx +src/lib/localization/client-messages.ts +src/lib/localization/client.ts +src/lib/localization/format.ts +src/lib/metadata/build-metadata.ts +src/styles/component-tokens.css +tests/browser/navigation.spec.ts +tests/browser/no-javascript.spec.ts +tests/browser/responsive.spec.ts +tests/browser/text-expansion.spec.ts +tests/fixtures/README.md +tests/fixtures/foundation-matrix.json +tests/unit/format.test.ts +tests/visual/README.md + +[MODIFIED] +.github/workflows/ci.yml +README.md +package.json +scripts/run-validations.mjs +scripts/validate-prohibited-content.mjs +scripts/validate-routes.mjs +src/app/[locale]/layout.tsx +src/app/[locale]/page.module.css +src/app/[locale]/page.tsx +src/components/app-shell/LocaleSelector.tsx +src/components/app-shell/SiteHeader.module.css +src/components/app-shell/SiteHeader.tsx +src/components/app-shell/ThemeSelector.tsx +src/content/locales/ar/shell.json +src/content/locales/en/shell.json +src/content/locales/fr/shell.json +src/lib/localization/config.ts +src/lib/theme/client.ts +src/proxy.ts +src/styles/globals.css +tests/browser/shell.spec.ts +tests/browser/theme-csp.spec.ts +tests/unit/localization.test.ts +tests/visual/shell.visual.spec.ts + +[REMOVED] diff --git a/docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.json b/docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.json new file mode 100644 index 0000000..023af35 --- /dev/null +++ b/docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.json @@ -0,0 +1,50 @@ +{ + "phase": 11, + "date": "2026-06-25", + "host_runtime": { + "node": "22.16.0", + "required_node": "24.17.0", + "required_pnpm": "11.9.0" + }, + "passed": [ + { + "command": "node scripts/run-validations.mjs", + "gates": 9 + }, + { + "command": "for f in scripts/*.mjs; do node --check \"$f\"; done", + "files": 17 + }, + { + "command": "JSON parse scan", + "files": 27 + }, + { + "command": "TypeScript transpileModule syntax scan", + "files": 62, + "compiler": "5.8.3" + }, + { + "command": "Phase 9 package validator", + "checksums": 61 + }, + { + "command": "node scripts/validate-phase11-manifest.mjs", + "files": 201, + "unlisted_extras": 0 + } + ], + "blocked": [ + "pnpm install --frozen-lockfile", + "pnpm format:check", + "pnpm lint", + "pnpm typecheck", + "pnpm test:unit", + "pnpm build", + "pnpm test:e2e", + "pnpm test:visual:update --project=chromium", + "pnpm audit --audit-level low" + ], + "blocker": "corepack prepare pnpm@11.9.0 --activate failed while fetching the pnpm tarball from registry.npmjs.org", + "all_tests_passed_claimed": false +} diff --git a/docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.md b/docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.md new file mode 100644 index 0000000..ebd42ea --- /dev/null +++ b/docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.md @@ -0,0 +1,62 @@ +# Phase 11 Validation Results + +## Environment + +- Date: 2026-06-25 +- Host Node.js: `22.16.0` +- Required Node.js: `24.17.0` +- Required pnpm: `11.9.0` + +## Executed successfully + +### Repository validation + +```bash +node scripts/run-validations.mjs +``` + +Result: **9 of 9 static gates passed**. + +1. Immutable Phase 9 contract: 61 payload checksums matched. +2. Runtime and dependencies: Node 24.17.0, pnpm 11.9.0, and 25 exact direct versions match the lockfile. +3. Locale catalogs: exact English, French, and Arabic key parity and direction metadata. +4. Routes: 5 route IDs with locale, runtime, hash, query, and `hreflang` coverage. +5. Phase 9 tokens: source unchanged and no raw palette literals introduced. +6. Phase 11 foundations: required component tokens, CSS system fallback, and shell files present. +7. Logical CSS: 12 CSS files passed physical-direction rejection. +8. Prohibited content: no placeholder destination, simulated submission, or research backdoor. +9. Metadata: canonical, reciprocal `hreflang`, Open Graph, social, and release-safe robots foundations present. + +### TypeScript syntax scan + +All 62 repository `.ts` and `.tsx` implementation/test files were transpiled with the host global TypeScript compiler using `transpileModule`. Result: **syntax passed**. + +This is not a substitute for the repository’s strict TypeScript 6.0.3 project check. + +## Blocked commands + +The following command was attempted: + +```bash +corepack prepare pnpm@11.9.0 --activate +``` + +It failed while fetching `https://registry.npmjs.org/pnpm/-/pnpm-11.9.0.tgz`. Therefore dependency installation was unavailable and these gates were not executed: + +```bash +pnpm install --frozen-lockfile +pnpm format:check +pnpm lint +pnpm typecheck +pnpm test:unit +SITE_ORIGIN=http://127.0.0.1:3000 PUBLIC_RELEASE_APPROVED=false pnpm build +pnpm audit --audit-level low +pnpm test:e2e +pnpm test:visual:update --project=chromium +``` + +No claim is made that those tests passed. P11-001, P11-002, and P11-003 remain release gates. + +## Raw command evidence + +Exact local command output is preserved in `docs/quality/PHASE_11_COMMAND_LOG_v1.0.txt`. The generated Phase 11 manifest was also verified successfully against 201 repository payload files with no unlisted extras. diff --git a/docs/quality/PHASE_12_COMMAND_LOG_v1.0.txt b/docs/quality/PHASE_12_COMMAND_LOG_v1.0.txt new file mode 100644 index 0000000..9aebd70 --- /dev/null +++ b/docs/quality/PHASE_12_COMMAND_LOG_v1.0.txt @@ -0,0 +1,76 @@ +Phase 12 command log +Date: 2026-06-25 +Executed host: Node 22.16.0; target: Node 24.17.0; pnpm 11.9.0 + +COMMAND: pnpm install --frozen-lockfile +STATUS: environment-blocked +EXIT: N/A +EVIDENCE: docs/quality/logs/pnpm-install-frozen.log +WARNINGS: registry DNS EAI_AGAIN; process terminated after retries + +COMMAND: npm install --engine-strict=false --ignore-scripts --package-lock=false --no-audit --no-fund +STATUS: fallback-pass +EXIT: 0 +EVIDENCE: docs/quality/logs/npm-install-fallback.log +WARNINGS: Node engine mismatch; does not satisfy frozen pnpm gate + +COMMAND: npm run validate +STATUS: pass +EXIT: 0 +EVIDENCE: docs/quality/logs/validate.log + +COMMAND: npm run format:check +STATUS: pass +EXIT: 0 +EVIDENCE: docs/quality/logs/format-check.log + +COMMAND: npm run lint +STATUS: pass +EXIT: 0 +EVIDENCE: docs/quality/logs/lint.log + +COMMAND: npm run typecheck +STATUS: pass +EXIT: 0 +EVIDENCE: docs/quality/logs/typecheck.log + +COMMAND: npm run test:unit +STATUS: pass +EXIT: 0 +EVIDENCE: docs/quality/logs/unit.log + +COMMAND: npm run build (without SITE_ORIGIN) +STATUS: expected-fail-closed +EXIT: 1 +EVIDENCE: docs/quality/logs/build-missing-site-origin.log +WARNINGS: Production metadata rejected the missing canonical origin as designed. + +COMMAND: SITE_ORIGIN=http://127.0.0.1:3000 PUBLIC_RELEASE_APPROVED=false npm run build +STATUS: pass +EXIT: 0 +EVIDENCE: docs/quality/logs/build.log +WARNINGS: Local evidence origin only; production origin remains P10-001. + +COMMAND: standalone server + curl locale/component-lab matrix +STATUS: pass +EXIT: 0 +EVIDENCE: docs/quality/PHASE_12_HTTP_ROUTE_RESULTS_v1.0.json + +COMMAND: playwright test tests/browser tests/a11y --project=chromium +STATUS: environment-blocked +EXIT: N/A +EVIDENCE: docs/quality/logs/playwright-browser-a11y.log +WARNINGS: Chromium rejected loopback navigation with net::ERR_BLOCKED_BY_ADMINISTRATOR + +COMMAND: playwright test tests/visual --project=chromium --update-snapshots +STATUS: not-run-after-shared-blocker +EXIT: N/A +EVIDENCE: docs/quality/PHASE_12_VISUAL_REGRESSION_RESULTS_v1.0.json +WARNINGS: Same loopback policy blocks image capture + +COMMAND: pnpm audit --audit-level low +STATUS: environment-blocked +EXIT: 124 +EVIDENCE: docs/quality/logs/pnpm-audit.log +WARNINGS: registry DNS EAI_AGAIN; timed out during retry delay + diff --git a/docs/quality/PHASE_12_FILE_CHANGES_v1.0.txt b/docs/quality/PHASE_12_FILE_CHANGES_v1.0.txt new file mode 100644 index 0000000..84fd713 --- /dev/null +++ b/docs/quality/PHASE_12_FILE_CHANGES_v1.0.txt @@ -0,0 +1,61 @@ +Phase 11 to Phase 12 repository comparison + +Files /tmp/phase11_original/RentalDriveGo/README.md and /mnt/data/phase12_work/RentalDriveGo/README.md differ +Only in /mnt/data/phase12_work/RentalDriveGo/docs: DECISION_LOG_v12.0.md +Only in /mnt/data/phase12_work/RentalDriveGo/docs: IMPLEMENTATION_ISSUE_REGISTER_v1.2.csv +Only in /mnt/data/phase12_work/RentalDriveGo/docs: PHASE_12_IMPLEMENTATION_REPORT_v1.0.md +Only in /mnt/data/phase12_work/RentalDriveGo/docs: PHASE_13_HANDOFF_v1.0.md +Only in /mnt/data/phase12_work/RentalDriveGo/docs/architecture: ADR-0003_PHASE_12_COMPONENT_SYSTEM.md +Only in /mnt/data/phase12_work/RentalDriveGo/docs: phase12 +Only in /mnt/data/phase12_work/RentalDriveGo/docs/quality: PHASE_12_COMMAND_LOG_v1.0.txt +Only in /mnt/data/phase12_work/RentalDriveGo/docs/quality: PHASE_12_HTTP_ROUTE_RESULTS_v1.0.json +Only in /mnt/data/phase12_work/RentalDriveGo/docs/quality: PHASE_12_MANUAL_QA_RESULTS_v1.0.csv +Only in /mnt/data/phase12_work/RentalDriveGo/docs/quality: PHASE_12_VALIDATION_RESULTS_v1.0.json +Only in /mnt/data/phase12_work/RentalDriveGo/docs/quality: PHASE_12_VALIDATION_RESULTS_v1.0.md +Only in /mnt/data/phase12_work/RentalDriveGo/docs/quality: PHASE_12_VISUAL_REGRESSION_RESULTS_v1.0.json +Only in /mnt/data/phase12_work/RentalDriveGo/docs/quality: logs +Files /tmp/phase11_original/RentalDriveGo/package.json and /mnt/data/phase12_work/RentalDriveGo/package.json differ +Files /tmp/phase11_original/RentalDriveGo/playwright.config.ts and /mnt/data/phase12_work/RentalDriveGo/playwright.config.ts differ +Only in /mnt/data/phase12_work/RentalDriveGo/scripts: generate-phase12-manifest.mjs +Files /tmp/phase11_original/RentalDriveGo/scripts/run-validations.mjs and /mnt/data/phase12_work/RentalDriveGo/scripts/run-validations.mjs differ +Only in /mnt/data/phase12_work/RentalDriveGo/scripts: validate-phase12-components.mjs +Only in /mnt/data/phase12_work/RentalDriveGo/scripts: validate-phase12-manifest.mjs +Files /tmp/phase11_original/RentalDriveGo/scripts/validate-runtime-dependencies.mjs and /mnt/data/phase12_work/RentalDriveGo/scripts/validate-runtime-dependencies.mjs differ +Only in /mnt/data/phase12_work/RentalDriveGo/src/app/[locale]: component-lab +Files /tmp/phase11_original/RentalDriveGo/src/app/[locale]/layout.tsx and /mnt/data/phase12_work/RentalDriveGo/src/app/[locale]/layout.tsx differ +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: actions +Files /tmp/phase11_original/RentalDriveGo/src/components/app-shell/SiteHeader.tsx and /mnt/data/phase12_work/RentalDriveGo/src/components/app-shell/SiteHeader.tsx differ +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: controls +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: feedback +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: forms +Files /tmp/phase11_original/RentalDriveGo/src/components/foundation/BidiText.tsx and /mnt/data/phase12_work/RentalDriveGo/src/components/foundation/BidiText.tsx differ +Only in /mnt/data/phase12_work/RentalDriveGo/src/components/foundation: Icon.module.css +Only in /mnt/data/phase12_work/RentalDriveGo/src/components/foundation: Icon.tsx +Files /tmp/phase11_original/RentalDriveGo/src/components/foundation/StatusBadge.module.css and /mnt/data/phase12_work/RentalDriveGo/src/components/foundation/StatusBadge.module.css differ +Files /tmp/phase11_original/RentalDriveGo/src/components/foundation/StatusBadge.tsx and /mnt/data/phase12_work/RentalDriveGo/src/components/foundation/StatusBadge.tsx differ +Only in /mnt/data/phase12_work/RentalDriveGo/src/components/foundation: VisuallyHidden.tsx +Only in /mnt/data/phase12_work/RentalDriveGo/src/components/foundation: client-hooks.ts +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: marketing +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: media +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: navigation +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: overlays +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: surfaces +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: typography +Only in /mnt/data/phase12_work/RentalDriveGo/src/content: development +Files /tmp/phase11_original/RentalDriveGo/src/content/locales/ar/shell.json and /mnt/data/phase12_work/RentalDriveGo/src/content/locales/ar/shell.json differ +Files /tmp/phase11_original/RentalDriveGo/src/content/locales/en/shell.json and /mnt/data/phase12_work/RentalDriveGo/src/content/locales/en/shell.json differ +Files /tmp/phase11_original/RentalDriveGo/src/content/locales/fr/shell.json and /mnt/data/phase12_work/RentalDriveGo/src/content/locales/fr/shell.json differ +Only in /mnt/data/phase12_work/RentalDriveGo/src/lib: components +Files /tmp/phase11_original/RentalDriveGo/src/lib/localization/client.ts and /mnt/data/phase12_work/RentalDriveGo/src/lib/localization/client.ts differ +Only in /mnt/data/phase12_work/RentalDriveGo/tests/a11y: component-system.a11y.spec.ts +Only in /mnt/data/phase12_work/RentalDriveGo/tests/browser: component-system.spec.ts +Files /tmp/phase11_original/RentalDriveGo/tests/browser/responsive.spec.ts and /mnt/data/phase12_work/RentalDriveGo/tests/browser/responsive.spec.ts differ +Files /tmp/phase11_original/RentalDriveGo/tests/browser/text-expansion.spec.ts and /mnt/data/phase12_work/RentalDriveGo/tests/browser/text-expansion.spec.ts differ +Files /tmp/phase11_original/RentalDriveGo/tests/browser/theme-csp.spec.ts and /mnt/data/phase12_work/RentalDriveGo/tests/browser/theme-csp.spec.ts differ +Only in /mnt/data/phase12_work/RentalDriveGo/tests/fixtures: component-system +Files /tmp/phase11_original/RentalDriveGo/tests/fixtures/foundation-matrix.json and /mnt/data/phase12_work/RentalDriveGo/tests/fixtures/foundation-matrix.json differ +Only in /mnt/data/phase12_work/RentalDriveGo/tests: types +Only in /mnt/data/phase12_work/RentalDriveGo/tests/unit: components +Only in /mnt/data/phase12_work/RentalDriveGo/tests/visual: component-system.visual.spec.ts +Files /tmp/phase11_original/RentalDriveGo/tsconfig.json and /mnt/data/phase12_work/RentalDriveGo/tsconfig.json differ +Only in /mnt/data/phase12_work/RentalDriveGo: tsconfig.tsbuildinfo diff --git a/docs/quality/PHASE_12_HTTP_ROUTE_RESULTS_v1.0.json b/docs/quality/PHASE_12_HTTP_ROUTE_RESULTS_v1.0.json new file mode 100644 index 0000000..3045365 --- /dev/null +++ b/docs/quality/PHASE_12_HTTP_ROUTE_RESULTS_v1.0.json @@ -0,0 +1,56 @@ +[ + { + "route": "/en", + "curl_exit": 0, + "status": "200", + "lang": "en", + "dir": "ltr", + "bytes": 41826, + "contains_error_page": false + }, + { + "route": "/fr", + "curl_exit": 0, + "status": "200", + "lang": "fr", + "dir": "ltr", + "bytes": 45433, + "contains_error_page": false + }, + { + "route": "/ar", + "curl_exit": 0, + "status": "200", + "lang": "ar", + "dir": "rtl", + "bytes": 48540, + "contains_error_page": false + }, + { + "route": "/en/component-lab", + "curl_exit": 0, + "status": "200", + "lang": "en", + "dir": "ltr", + "bytes": 68056, + "contains_error_page": false + }, + { + "route": "/fr/component-lab", + "curl_exit": 0, + "status": "200", + "lang": "fr", + "dir": "ltr", + "bytes": 71005, + "contains_error_page": false + }, + { + "route": "/ar/component-lab", + "curl_exit": 0, + "status": "200", + "lang": "ar", + "dir": "rtl", + "bytes": 74483, + "contains_error_page": false + } +] diff --git a/docs/quality/PHASE_12_MANUAL_QA_RESULTS_v1.0.csv b/docs/quality/PHASE_12_MANUAL_QA_RESULTS_v1.0.csv new file mode 100644 index 0000000..a0caf59 --- /dev/null +++ b/docs/quality/PHASE_12_MANUAL_QA_RESULTS_v1.0.csv @@ -0,0 +1,21 @@ +Test_ID,Area,Environment,Viewport,Locale,Theme,Result,Evidence_or_blocker +P12-MAN-001,Buttons and links,Source review + Vitest,N/A,en/fr/ar,light/dark,Pass,"Native semantics, loading protection, accessible icon-only labels, disabled destinations, and directional icon behavior covered by source and unit tests." +P12-MAN-002,Form controls,Source review + Vitest,N/A,en/fr/ar,light/dark,Pass,"Programmatic labels, required state, help/error descriptions, invalid state, and field grouping pass unit assertions." +P12-MAN-003,Tabs,Source review + Vitest,N/A,en/ar,light/dark,Pass,Roving selection and direction-aware arrow behavior pass unit interaction tests. +P12-MAN-004,Accordion,Source review + Vitest,N/A,en/fr/ar,light/dark,Pass,Native details/summary semantics and expanded state verified. +P12-MAN-005,Dialog and drawer,Chromium required,Desktop/mobile,en/fr/ar,light/dark,Blocked,"Focus trap, Escape, inert background, scroll lock, and focus return tests are authored; Chromium loopback navigation is administrator-blocked." +P12-MAN-006,Dropdown menu and tooltip,Chromium required,Desktop/mobile,en/fr/ar,light/dark,Blocked,Keyboard/pointer/touch and announcement observations require an unblocked browser. +P12-MAN-007,Alerts and loading,Source review,All,en/fr/ar,light/dark,Pass,Live-region behavior is explicit; decorative loading is not repeatedly announced; reduced-motion CSS is present. +P12-MAN-008,Interactive cards,Source review,All,en/fr/ar,light/dark,Pass,Valid link/button semantics enforced; nested interactive usage prohibited in documentation. +P12-MAN-009,Workflow pattern,Source review + server HTML,All,en/fr/ar,light/dark,Pass,DOM and reading order remain chronological; connectors are decorative and logical-property based. +P12-MAN-010,Comparison pattern,Source review + server HTML,All,en/fr/ar,light/dark,Pass,Semantic list structure remains understandable without color; mobile order is explicit. +P12-MAN-011,Product preview tables,Source review + server HTML,All,en/fr/ar,light/dark,Pass,"Fictional deterministic fixtures, captions, responsive wrapper, and bidi isolation are present." +P12-MAN-012,CTA patterns,Source review + server HTML,All,en/fr/ar,light/dark,Pass,"One dominant action, disabled unresolved destinations, stacked layout, and localized content inputs verified." +P12-MAN-013,Localized route rendering,Standalone server + curl,Server,en/fr/ar,N/A,Pass,Six routes returned HTTP 200 with correct lang and dir; Arabic returned document-level rtl. +P12-MAN-014,Keyboard-only full flow,Chromium + human operator required,Desktop/mobile,en/fr/ar,light/dark,Blocked,"Automated scenarios exist, but browser navigation is rejected before page load." +P12-MAN-015,Screen-reader review,NVDA/JAWS/VoiceOver required,Desktop/mobile,en/fr/ar,light/dark,Blocked,Manual announcements and virtual-cursor reading order remain P12-005. +P12-MAN-016,Touch simulation,Chromium/WebKit required,Mobile,en/fr/ar,light/dark,Blocked,Browser matrix could not reach loopback pages. +P12-MAN-017,200 percent zoom,Browser required,320 CSS px,en/fr/ar,light/dark,Blocked,Reflow scenario authored; browser execution blocked. +P12-MAN-018,400 percent zoom,Browser + human operator required,320 CSS px,en/fr/ar,light/dark,Blocked,Manual acceptance remains P12-005. +P12-MAN-019,Reduced motion,Static CSS + source review,All,en/fr/ar,light/dark,Pass,Transitions and loading treatments respect prefers-reduced-motion. +P12-MAN-020,Forced colors,Windows high-contrast environment required,Desktop,en/fr/ar,light/dark,Blocked,Focus and border fallbacks are authored; manual Windows verification remains open. diff --git a/docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.json b/docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.json new file mode 100644 index 0000000..1bc7576 --- /dev/null +++ b/docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.json @@ -0,0 +1,162 @@ +{ + "phase": 12, + "date": "2026-06-25", + "runtime": { + "executedNode": "22.16.0", + "targetNode": "24.17.0", + "pnpm": "11.9.0" + }, + "commands": [ + { + "command": "pnpm install --frozen-lockfile", + "exitCode": null, + "status": "environment-blocked", + "testCount": 0, + "passCount": 0, + "failureCount": 0, + "skippedCount": 0, + "warnings": ["registry DNS EAI_AGAIN; process terminated after retries"], + "evidence": "docs/quality/logs/pnpm-install-frozen.log" + }, + { + "command": "npm install --engine-strict=false --ignore-scripts --package-lock=false --no-audit --no-fund", + "exitCode": 0, + "status": "fallback-pass", + "testCount": 0, + "passCount": 0, + "failureCount": 0, + "skippedCount": 0, + "warnings": ["Node engine mismatch; does not satisfy frozen pnpm gate"], + "evidence": "docs/quality/logs/npm-install-fallback.log" + }, + { + "command": "npm run validate", + "exitCode": 0, + "status": "pass", + "testCount": 10, + "passCount": 10, + "failureCount": 0, + "skippedCount": 0, + "warnings": [], + "evidence": "docs/quality/logs/validate.log" + }, + { + "command": "npm run format:check", + "exitCode": 0, + "status": "pass", + "testCount": 1, + "passCount": 1, + "failureCount": 0, + "skippedCount": 0, + "warnings": [], + "evidence": "docs/quality/logs/format-check.log" + }, + { + "command": "npm run lint", + "exitCode": 0, + "status": "pass", + "testCount": 1, + "passCount": 1, + "failureCount": 0, + "skippedCount": 0, + "warnings": [], + "evidence": "docs/quality/logs/lint.log" + }, + { + "command": "npm run typecheck", + "exitCode": 0, + "status": "pass", + "testCount": 1, + "passCount": 1, + "failureCount": 0, + "skippedCount": 0, + "warnings": [], + "evidence": "docs/quality/logs/typecheck.log" + }, + { + "command": "npm run test:unit", + "exitCode": 0, + "status": "pass", + "testCount": 22, + "passCount": 22, + "failureCount": 0, + "skippedCount": 0, + "warnings": [], + "evidence": "docs/quality/logs/unit.log" + }, + { + "command": "npm run build (without SITE_ORIGIN)", + "exitCode": 1, + "status": "expected-fail-closed", + "testCount": 1, + "passCount": 1, + "failureCount": 0, + "skippedCount": 0, + "warnings": ["Production metadata rejected the missing canonical origin as designed."], + "evidence": "docs/quality/logs/build-missing-site-origin.log" + }, + { + "command": "SITE_ORIGIN=http://127.0.0.1:3000 PUBLIC_RELEASE_APPROVED=false npm run build", + "exitCode": 0, + "status": "pass", + "testCount": 1, + "passCount": 1, + "failureCount": 0, + "skippedCount": 0, + "warnings": ["Local evidence origin only; production origin remains P10-001."], + "evidence": "docs/quality/logs/build.log" + }, + { + "command": "standalone server + curl locale/component-lab matrix", + "exitCode": 0, + "status": "pass", + "testCount": 6, + "passCount": 6, + "failureCount": 0, + "skippedCount": 0, + "warnings": [], + "evidence": "docs/quality/PHASE_12_HTTP_ROUTE_RESULTS_v1.0.json" + }, + { + "command": "playwright test tests/browser tests/a11y --project=chromium", + "exitCode": null, + "status": "environment-blocked", + "testCount": 44, + "passCount": 0, + "failureCount": 0, + "skippedCount": 44, + "warnings": ["Chromium rejected loopback navigation with net::ERR_BLOCKED_BY_ADMINISTRATOR"], + "evidence": "docs/quality/logs/playwright-browser-a11y.log" + }, + { + "command": "playwright test tests/visual --project=chromium --update-snapshots", + "exitCode": null, + "status": "not-run-after-shared-blocker", + "testCount": 0, + "passCount": 0, + "failureCount": 0, + "skippedCount": 0, + "warnings": ["Same loopback policy blocks image capture"], + "evidence": "docs/quality/PHASE_12_VISUAL_REGRESSION_RESULTS_v1.0.json" + }, + { + "command": "pnpm audit --audit-level low", + "exitCode": 124, + "status": "environment-blocked", + "testCount": 0, + "passCount": 0, + "failureCount": 0, + "skippedCount": 0, + "warnings": ["registry DNS EAI_AGAIN; timed out during retry delay"], + "evidence": "docs/quality/logs/pnpm-audit.log" + } + ], + "unitCoverage": { + "statements": 92.4, + "branches": 86.04, + "functions": 95.45, + "lines": 92.64 + }, + "releaseAcceptance": "blocked", + "blockingIssues": ["P12-001", "P12-002", "P12-003", "P12-004", "P12-005"] +} diff --git a/docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.md b/docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.md new file mode 100644 index 0000000..9d6e73b --- /dev/null +++ b/docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.md @@ -0,0 +1,23 @@ +# Phase 12 Validation Results + +Date: 2026-06-25 + +| Command | Status | Exit | Tests | Passed | Failed | Skipped | Evidence | +| ---------------------------------------------------------------------------------------------- | ---------------------------- | ---: | ----: | -----: | -----: | ------: | ----------------------------------------------------------- | +| `pnpm install --frozen-lockfile` | environment-blocked | N/A | 0 | 0 | 0 | 0 | `docs/quality/logs/pnpm-install-frozen.log` | +| `npm install --engine-strict=false --ignore-scripts --package-lock=false --no-audit --no-fund` | fallback-pass | 0 | 0 | 0 | 0 | 0 | `docs/quality/logs/npm-install-fallback.log` | +| `npm run validate` | pass | 0 | 10 | 10 | 0 | 0 | `docs/quality/logs/validate.log` | +| `npm run format:check` | pass | 0 | 1 | 1 | 0 | 0 | `docs/quality/logs/format-check.log` | +| `npm run lint` | pass | 0 | 1 | 1 | 0 | 0 | `docs/quality/logs/lint.log` | +| `npm run typecheck` | pass | 0 | 1 | 1 | 0 | 0 | `docs/quality/logs/typecheck.log` | +| `npm run test:unit` | pass | 0 | 22 | 22 | 0 | 0 | `docs/quality/logs/unit.log` | +| `npm run build (without SITE_ORIGIN)` | expected-fail-closed | 1 | 1 | 1 | 0 | 0 | `docs/quality/logs/build-missing-site-origin.log` | +| `SITE_ORIGIN=http://127.0.0.1:3000 PUBLIC_RELEASE_APPROVED=false npm run build` | pass | 0 | 1 | 1 | 0 | 0 | `docs/quality/logs/build.log` | +| `standalone server + curl locale/component-lab matrix` | pass | 0 | 6 | 6 | 0 | 0 | `docs/quality/PHASE_12_HTTP_ROUTE_RESULTS_v1.0.json` | +| `playwright test tests/browser tests/a11y --project=chromium` | environment-blocked | N/A | 44 | 0 | 0 | 44 | `docs/quality/logs/playwright-browser-a11y.log` | +| `playwright test tests/visual --project=chromium --update-snapshots` | not-run-after-shared-blocker | N/A | 0 | 0 | 0 | 0 | `docs/quality/PHASE_12_VISUAL_REGRESSION_RESULTS_v1.0.json` | +| `pnpm audit --audit-level low` | environment-blocked | 124 | 0 | 0 | 0 | 0 | `docs/quality/logs/pnpm-audit.log` | + +Unit coverage: 92.40% statements, 86.04% branches, 95.45% functions, and 92.64% lines. + +The production build intentionally fails without `SITE_ORIGIN`; the successful local evidence build used `http://127.0.0.1:3000`. Release acceptance remains blocked by P12-001 through P12-005. The source implementation is ready for Phase 13 development, but browser, visual, target-runtime, audit, and manual assistive-technology evidence still requires an unblocked pinned environment. diff --git a/docs/quality/PHASE_12_VISUAL_REGRESSION_RESULTS_v1.0.json b/docs/quality/PHASE_12_VISUAL_REGRESSION_RESULTS_v1.0.json new file mode 100644 index 0000000..516a449 --- /dev/null +++ b/docs/quality/PHASE_12_VISUAL_REGRESSION_RESULTS_v1.0.json @@ -0,0 +1,23 @@ +{ + "phase": 12, + "date": "2026-06-25", + "status": "environment-blocked", + "authoredScenarios": [ + "component variants", + "light and dark", + "English French Arabic", + "desktop and mobile", + "focus-visible", + "error", + "long content", + "RTL arrangements" + ], + "execution": { + "attempted": true, + "browser": "system Chromium", + "result": "blocked", + "error": "net::ERR_BLOCKED_BY_ADMINISTRATOR for loopback navigation" + }, + "baselinesGenerated": false, + "issue": "P12-002" +} diff --git a/docs/quality/PHASE_13_COMMAND_LOG_v1.0.txt b/docs/quality/PHASE_13_COMMAND_LOG_v1.0.txt new file mode 100644 index 0000000..3177564 --- /dev/null +++ b/docs/quality/PHASE_13_COMMAND_LOG_v1.0.txt @@ -0,0 +1,14 @@ +2026-06-25 | node --version | PASS | v22.16.0; target 24.17.0 remains unverified +2026-06-25 | npx --yes pnpm@11.9.0 --version | PASS | 11.9.0 +2026-06-25 | pnpm install --frozen-lockfile --config.engine-strict=false | BLOCKED | lockfile current; registry EAI_AGAIN prevented completion +2026-06-25 | npm run validate | PASS | Phase 9-13 static controls passed +2026-06-25 | npm run format:check | PASS | all files formatted +2026-06-25 | npm run lint | PASS | zero warnings +2026-06-25 | npm run typecheck | PASS | strict TypeScript passed +2026-06-25 | npm run test:unit | PASS | 27 tests, 9 files, thresholds passed +2026-06-25 | SITE_ORIGIN=https://approved.invalid npm run build | PASS | production build and standalone preparation passed +2026-06-25 | Playwright homepage Chromium suite | BLOCKED | net::ERR_BLOCKED_BY_ADMINISTRATOR for loopback navigation +2026-06-25 | standalone HTTP EN/FR/AR checks | PASS | HTTP 200, correct lang/dir, localized hero payload present +2026-06-25 | pnpm audit --audit-level low | BLOCKED | registry connectivity did not permit completion +2026-06-25 | npm run manifest:generate | PASS | Phase 13 manifest generated +2026-06-25 | npm run validate:package | PASS | manifest verified with no extras diff --git a/docs/quality/PHASE_13_FILE_CHANGES_v1.0.txt b/docs/quality/PHASE_13_FILE_CHANGES_v1.0.txt new file mode 100644 index 0000000..9c3523f --- /dev/null +++ b/docs/quality/PHASE_13_FILE_CHANGES_v1.0.txt @@ -0,0 +1,26 @@ +A PHASE_13_PACKAGE_MANIFEST_v1.0.json +A docs/DECISION_LOG_v13.0.md +A docs/IMPLEMENTATION_ISSUE_REGISTER_v1.3.csv +A docs/PHASE_13_IMPLEMENTATION_REPORT_v1.0.md +A docs/phase13/COMPONENT_VARIANT_UPDATE_v1.0.md +A docs/phase13/HOMEPAGE_CONTENT_MODEL_v1.0.md +A docs/phase13/HOMEPAGE_SECTION_MATRIX_v1.0.csv +A docs/quality/PHASE_13_COMMAND_LOG_v1.0.txt +A docs/quality/PHASE_13_FILE_CHANGES_v1.0.txt +A docs/quality/PHASE_13_HTTP_ROUTE_RESULTS_v1.0.json +A docs/quality/PHASE_13_MANUAL_QA_RESULTS_v1.0.csv +A docs/quality/PHASE_13_VALIDATION_RESULTS_v1.0.json +A docs/quality/PHASE_13_VALIDATION_RESULTS_v1.0.md +A scripts/generate-phase13-manifest.mjs +A scripts/validate-phase13-homepage.mjs +A scripts/validate-phase13-manifest.mjs +A src/content/homepage-model.ts +A tests/a11y/homepage.a11y.spec.ts +A tests/browser/homepage.spec.ts +A tests/unit/homepage-content.test.ts +A tests/visual/homepage.visual.spec.ts +M package.json +M scripts/run-validations.mjs +M src/app/[locale]/page.module.css +M src/app/[locale]/page.tsx +M src/components/marketing/ProductPreview.tsx diff --git a/docs/quality/PHASE_13_HTTP_ROUTE_RESULTS_v1.0.json b/docs/quality/PHASE_13_HTTP_ROUTE_RESULTS_v1.0.json new file mode 100644 index 0000000..b9d032e --- /dev/null +++ b/docs/quality/PHASE_13_HTTP_ROUTE_RESULTS_v1.0.json @@ -0,0 +1,30 @@ +{ + "generated_at": "2026-06-25", + "origin": "http://127.0.0.1:3100", + "results": [ + { + "locale": "en", + "status": 200, + "lang": "en", + "dir": "ltr", + "hero_payload_present": true, + "bytes": 152405 + }, + { + "locale": "fr", + "status": 200, + "lang": "fr", + "dir": "ltr", + "hero_payload_present": true, + "bytes": 157175 + }, + { + "locale": "ar", + "status": 200, + "lang": "ar", + "dir": "rtl", + "hero_payload_present": true, + "bytes": 165377 + } + ] +} diff --git a/docs/quality/PHASE_13_MANUAL_QA_RESULTS_v1.0.csv b/docs/quality/PHASE_13_MANUAL_QA_RESULTS_v1.0.csv new file mode 100644 index 0000000..ffd7e8a --- /dev/null +++ b/docs/quality/PHASE_13_MANUAL_QA_RESULTS_v1.0.csv @@ -0,0 +1,11 @@ +Check_ID,Area,Scenario,Status,Evidence,Exit_criteria +P13-M01,Keyboard,Desktop EN/FR/AR full route navigation,Blocked,Chromium loopback navigation rejected by administrator,Complete keyboard path with visible focus and logical order +P13-M02,Screen reader,Landmarks headings disclosures disabled actions,Not run,Requires human assistive-technology session,Record NVDA VoiceOver or approved equivalent observations +P13-M03,Zoom,200 percent zoom at 640 CSS pixels,Not run,Browser execution blocked,No horizontal page overflow and all controls operable +P13-M04,Reflow,400 percent reflow at 320 CSS pixels,Not run,Browser execution blocked,Single-direction scrolling except explicit component overflow +P13-M05,Touch,390 and 320 CSS pixel mobile interactions,Not run,Browser execution blocked,Targets and disclosures operable without overlap +P13-M06,Themes,Light dark and system in all locales,Not run,Browser execution blocked,No unreadable contrast or flash regressions +P13-M07,RTL,Arabic desktop tablet and mobile,Not run,Browser execution blocked,True RTL with fixed media and isolated identifiers +P13-M08,Forced colors,Homepage and disabled actions,Not run,Browser execution blocked,Meaning and focus remain visible +P13-M09,Reduced motion,Decorative preview treatment and scrolling,Static pass,Source review confirms transforms are removed and smooth scrolling disabled,Confirm in browser environment +P13-M10,Content expansion,Long French and Arabic copy,Automated scenario authored,tests/browser/text-expansion.spec.ts,Execute in unblocked browser and confirm no overflow diff --git a/docs/quality/PHASE_13_VALIDATION_RESULTS_v1.0.json b/docs/quality/PHASE_13_VALIDATION_RESULTS_v1.0.json new file mode 100644 index 0000000..8fdd50a --- /dev/null +++ b/docs/quality/PHASE_13_VALIDATION_RESULTS_v1.0.json @@ -0,0 +1,85 @@ +{ + "phase": 13, + "date": "2026-06-25", + "environment": { + "node": "22.16.0", + "target_node": "24.17.0", + "pnpm": "11.9.0 via npx", + "target_pnpm": "11.9.0", + "browser": "System Chromium", + "browser_constraint": "Loopback navigation rejected with net::ERR_BLOCKED_BY_ADMINISTRATOR" + }, + "results": [ + { + "gate": "pnpm install --frozen-lockfile", + "status": "blocked", + "detail": "Lockfile verification completed; registry requests failed with EAI_AGAIN before installation completed." + }, + { + "gate": "pnpm validate", + "status": "passed", + "detail": "Phase 9 through Phase 13 static validators passed." + }, + { + "gate": "pnpm format:check", + "status": "passed", + "detail": "All tracked source and documentation files matched Prettier formatting." + }, + { "gate": "pnpm lint", "status": "passed", "detail": "ESLint completed with zero warnings." }, + { + "gate": "pnpm typecheck", + "status": "passed", + "detail": "Strict TypeScript validation completed without errors." + }, + { + "gate": "pnpm test:unit", + "status": "passed", + "detail": "27 tests passed across 9 files; configured coverage thresholds passed." + }, + { + "gate": "pnpm test:browser", + "status": "blocked", + "detail": "Homepage scenarios were invoked with video disabled and system Chromium; all navigation attempts were rejected before application response." + }, + { + "gate": "pnpm test:a11y", + "status": "blocked", + "detail": "Authored axe scenarios require the same blocked loopback browser navigation." + }, + { + "gate": "pnpm test:visual", + "status": "blocked", + "detail": "Authored visual scenarios and baseline generation require the same blocked loopback browser navigation." + }, + { + "gate": "SITE_ORIGIN=https://approved.invalid pnpm build", + "status": "passed", + "detail": "Next.js production build, strict type phase, route generation, and standalone preparation passed." + }, + { + "gate": "standalone HTTP locale checks", + "status": "passed", + "detail": "EN, FR, and AR returned HTTP 200 with correct lang and dir and localized hero content in the response payload." + }, + { + "gate": "pnpm audit", + "status": "blocked", + "detail": "Registry connectivity did not permit completion of the pnpm audit request." + }, + { + "gate": "pnpm manifest:generate", + "status": "passed", + "detail": "Phase 13 checksum manifest generated." + }, + { + "gate": "pnpm validate:package", + "status": "passed", + "detail": "Phase 13 checksum manifest verified with no unlisted repository files." + }, + { + "gate": "manual accessibility and responsive matrix", + "status": "open", + "detail": "Keyboard, touch, screen-reader, zoom, forced-colors, and human visual review are documented but not fabricated." + } + ] +} diff --git a/docs/quality/PHASE_13_VALIDATION_RESULTS_v1.0.md b/docs/quality/PHASE_13_VALIDATION_RESULTS_v1.0.md new file mode 100644 index 0000000..b7598b1 --- /dev/null +++ b/docs/quality/PHASE_13_VALIDATION_RESULTS_v1.0.md @@ -0,0 +1,41 @@ +# Phase 13 Validation Results + +Date: 2026-06-25 + +## Environment + +- Available runtime: Node.js 22.16.0. +- Required runtime: Node.js 24.17.0. +- Exact pnpm CLI used for attempted frozen installation: 11.9.0 through `npx`. +- Browser: system Chromium. +- Browser restriction: every loopback navigation was rejected with `net::ERR_BLOCKED_BY_ADMINISTRATOR` before an application response. + +## Results + +| Gate | Result | Evidence | +| ------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Frozen pnpm installation | Blocked | Lockfile verification completed, then registry requests failed with `EAI_AGAIN`. | +| Static validation | Passed | Phase 9 contract, runtime pins, locale parity, routes, tokens, CSS, prohibited content, metadata, Phase 12 components, and Phase 13 homepage controls passed. | +| Formatting | Passed | Prettier reported all files formatted. | +| Lint | Passed | ESLint completed with zero warnings. | +| Strict type checking | Passed | TypeScript completed without errors. | +| Unit tests | Passed | 27 tests in 9 files passed; line, statement, branch, and function thresholds passed. | +| Production build | Passed | Next.js 16.2.9 compiled, type-checked, generated route data, and prepared standalone assets. | +| Standalone HTTP checks | Passed | EN, FR, and AR returned 200, correct `lang` and `dir`, and localized hero payloads. | +| Homepage browser tests | Blocked | Nine authored scenarios could not navigate to loopback because Chromium returned the administrator policy error. | +| Axe tests | Blocked | Four authored homepage scenarios depend on the same browser navigation. | +| Visual tests | Blocked | Seven authored homepage baselines depend on the same browser navigation. | +| Dependency audit | Blocked | Registry connectivity prevented a completed pnpm audit. | +| Package manifest | Passed | Phase 13 manifest generated and verified after repository cleanup. | +| Manual QA | Open | Keyboard, touch, screen-reader, 200/400 percent zoom, reduced motion, forced colors, themes, RTL, and content expansion require human execution. | + +## Coverage summary + +- Statements: 92.4 percent. +- Branches: 86.04 percent. +- Functions: 95.45 percent. +- Lines: 92.64 percent. + +## Acceptance statement + +The implemented source is statically valid, typed, unit-tested, buildable, and directly servable in all three locales. Formal Phase 13 acceptance remains blocked by P12-001 through P12-005 and P13-001 through P13-003. Browser and human accessibility evidence cannot be replaced by source inspection, even when source inspection is substantially less annoying. diff --git a/docs/quality/VALIDATION_RESULTS_v1.0.json b/docs/quality/VALIDATION_RESULTS_v1.0.json new file mode 100644 index 0000000..df79cc3 --- /dev/null +++ b/docs/quality/VALIDATION_RESULTS_v1.0.json @@ -0,0 +1,32 @@ +{ + "schema_version": "1.0", + "project": "RentalDriveGo", + "executed_at": "2026-06-25", + "target_runtime": { "node": "24.17.0", "pnpm": "11.9.0" }, + "execution_runtime": { "node": "22.16.0", "pnpm": "11.9.0" }, + "results": [ + { "id": "phase9-validator", "status": "passed", "checks": 38, "targets": 19 }, + { "id": "phase9-manifest", "status": "passed", "manifested_files": 61, "extracted_files": 62 }, + { "id": "repository-validations", "status": "passed", "validators": 7 }, + { "id": "phase10-manifest", "status": "passed", "manifested_files": 146 }, + { "id": "format", "status": "passed" }, + { "id": "lint", "status": "passed", "warnings": 0 }, + { "id": "typecheck", "status": "passed" }, + { + "id": "unit-tests", + "status": "passed", + "files": 3, + "tests": 9, + "coverage": { "statements": 95.31, "branches": 89.18, "functions": 100, "lines": 94.64 } + }, + { "id": "production-build", "status": "passed" }, + { "id": "package-audit", "status": "passed", "known_vulnerabilities": 0 }, + { "id": "http-smoke", "status": "passed" }, + { + "id": "browser-tests", + "status": "environment_blocked", + "reason": "Managed system Chromium URLBlocklist blocks all navigation and Playwright CDN DNS resolution fails." + }, + { "id": "target-node-runtime", "status": "environment_blocked", "available_node": "22.16.0" } + ] +} diff --git a/docs/quality/VALIDATION_RESULTS_v1.0.md b/docs/quality/VALIDATION_RESULTS_v1.0.md new file mode 100644 index 0000000..6e743ea --- /dev/null +++ b/docs/quality/VALIDATION_RESULTS_v1.0.md @@ -0,0 +1,33 @@ +# Phase 10 Validation Results + +- **Execution date:** 2026-06-25 +- **Execution environment:** Linux container, Node.js 22.16.0 available; repository target is Node.js 24.17.0 +- **Package manager:** pnpm 11.9.0 + +| Check | Result | Evidence / notes | +| ------------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------- | +| Phase 9 supplied validator | PASS | 38 checks across 19 validator targets | +| Phase 9 manifest checksums and sizes | PASS | 61 manifested payload files matched exactly; manifest itself makes 62 extracted files | +| Contract immutability validator | PASS | Source manifest and supplied validator executed from `contracts/phase9` | +| Locale parity and direction validator | PASS | EN, FR, AR key parity, locale mapping, and implementation brand checks | +| Route parity validator | PASS | Locale paths, canonical alternates, query preservation allowlist, and hash rules | +| Token integrity validator | PASS | `src/styles/tokens.css` is byte-identical to the Phase 9 token source | +| CSS logical-property validator | PASS | No prohibited physical left/right declarations in implementation CSS | +| Prohibited-content validator | PASS | No placeholder destinations, research backdoors, simulated production success, or prohibited source behavior | +| Prettier check | PASS | Repository formatting accepted | +| ESLint | PASS | Zero warnings permitted | +| TypeScript | PASS | Strict `tsc --noEmit` | +| Unit tests | PASS | 3 files, 9 tests; 95.31% statements, 89.18% branches, 100% functions, 94.64% lines | +| Production build | PASS | Next.js dynamic locale route, static robots and not-found routes, standalone output prepared | +| Package audit | PASS | `pnpm audit --audit-level low`: no known vulnerabilities | +| Server HTTP smoke check | PASS | `/en` returned 200 with `lang`, `dir`, CSP nonce, noindex, canonical, and all `hreflang` links in server HTML | +| Browser functional suite | BLOCKED BY ENVIRONMENT | System Chromium has an administrator `URLBlocklist: ["*"]`; navigation returns `ERR_BLOCKED_BY_ADMINISTRATOR` | +| Browser installation fallback | BLOCKED BY ENVIRONMENT | Playwright CDN resolution failed with `EAI_AGAIN cdn.playwright.dev` | +| Accessibility browser suite | NOT EXECUTED LOCALLY | Configured and required in CI; depends on an unblocked Playwright browser | +| Visual regression baselines | NOT GENERATED LOCALLY | Must be generated and reviewed in approved CI/browser environment, not fabricated from failed navigation | +| Firefox/WebKit/mobile matrix | NOT EXECUTED LOCALLY | CI installs and runs configured engines; support policy owner remains unresolved under P9-011 | +| Exact target-runtime execution | NOT EXECUTED LOCALLY | Host exposes Node.js 22.16.0 only; CI and OCI image are pinned to 24.17.0 | + +## Interpretation + +The source, static validators, unit suite, audit, and production build are green. Browser-dependent evidence is not green; it is unavailable in this host. The CI browser job remains a required release gate and must run successfully before Phase 11 implementation is accepted. diff --git a/docs/quality/VISUAL_REGRESSION_RESULTS_v1.0.json b/docs/quality/VISUAL_REGRESSION_RESULTS_v1.0.json new file mode 100644 index 0000000..846a942 --- /dev/null +++ b/docs/quality/VISUAL_REGRESSION_RESULTS_v1.0.json @@ -0,0 +1,20 @@ +{ + "phase": 11, + "status": "blocked", + "canonical_engine": "Playwright Chromium 1.61.1 pinned browser", + "reason": "The local environment could not install pnpm 11.9.0 or the repository dependencies, so the application and Playwright snapshot runner could not execute.", + "scenarios_defined": [ + "desktop-en-light", + "desktop-en-dark", + "tablet-fr-light", + "tablet-fr-dark", + "mobile-ar-light", + "mobile-ar-dark", + "mobile-ar-dark-navigation-open", + "desktop-en-light-focus" + ], + "baselines_generated": 0, + "fabricated_baselines": false, + "command": "pnpm test:visual:update --project=chromium", + "release_gate": "P11-002" +} diff --git a/docs/quality/logs/build-initial.log b/docs/quality/logs/build-initial.log new file mode 100644 index 0000000..949357d --- /dev/null +++ b/docs/quality/logs/build-initial.log @@ -0,0 +1,29 @@ + +> rentaldrivego-web@0.3.0 build +> next build && node scripts/prepare-standalone.mjs + +▲ Next.js 16.2.9 (Turbopack) + + Creating an optimized production build ... +✓ Compiled successfully in 11.6s + Running TypeScript ... + Finished TypeScript in 7.9s ... + Collecting page data using 7 workers ... + Generating static pages using 7 workers (0/3) ... +✓ Generating static pages using 7 workers (3/3) in 691ms + Finalizing page optimization ... + +Route (app) +┌ ○ /_not-found +├ ƒ /[locale] +├ ƒ /[locale]/[slug] +├ ƒ /[locale]/component-lab +└ ○ /robots.txt + + +ƒ Proxy (Middleware) + +○ (Static) prerendered as static content +ƒ (Dynamic) server-rendered on demand + +Prepared standalone server assets. diff --git a/docs/quality/logs/build-missing-site-origin.exit b/docs/quality/logs/build-missing-site-origin.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/docs/quality/logs/build-missing-site-origin.exit @@ -0,0 +1 @@ +1 diff --git a/docs/quality/logs/build-missing-site-origin.log b/docs/quality/logs/build-missing-site-origin.log new file mode 100644 index 0000000..e60eb39 --- /dev/null +++ b/docs/quality/logs/build-missing-site-origin.log @@ -0,0 +1,19 @@ + +> rentaldrivego-web@0.3.0 build +> next build && node scripts/prepare-standalone.mjs + +▲ Next.js 16.2.9 (Turbopack) + + Creating an optimized production build ... +✓ Compiled successfully in 11.6s + Running TypeScript ... + Finished TypeScript in 8.6s ... + Collecting page data using 7 workers ... + Generating static pages using 7 workers (0/3) ... +Error occurred prerendering page "/robots.txt". Read more: https://nextjs.org/docs/messages/prerender-error +Error: SITE_ORIGIN is required in production. No canonical domain is approved yet. + at (.next/server/chunks/[root-of-the-server]__14j6iib._.js:26:33652) + at tT (.next/server/chunks/[root-of-the-server]__14j6iib._.js:26:33966) + at tA (.next/server/chunks/[root-of-the-server]__14j6iib._.js:26:34173) +Export encountered an error on /robots.txt/route: /robots.txt, exiting the build. +⨯ Next.js build worker exited with code: 1 and signal: null diff --git a/docs/quality/logs/build.exit b/docs/quality/logs/build.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/quality/logs/build.exit @@ -0,0 +1 @@ +0 diff --git a/docs/quality/logs/build.log b/docs/quality/logs/build.log new file mode 100644 index 0000000..2f63212 --- /dev/null +++ b/docs/quality/logs/build.log @@ -0,0 +1,29 @@ + +> rentaldrivego-web@0.3.0 build +> next build && node scripts/prepare-standalone.mjs + +▲ Next.js 16.2.9 (Turbopack) + + Creating an optimized production build ... +✓ Compiled successfully in 11.4s + Running TypeScript ... + Finished TypeScript in 8.2s ... + Collecting page data using 7 workers ... + Generating static pages using 7 workers (0/3) ... +✓ Generating static pages using 7 workers (3/3) in 566ms + Finalizing page optimization ... + +Route (app) +┌ ○ /_not-found +├ ƒ /[locale] +├ ƒ /[locale]/[slug] +├ ƒ /[locale]/component-lab +└ ○ /robots.txt + + +ƒ Proxy (Middleware) + +○ (Static) prerendered as static content +ƒ (Dynamic) server-rendered on demand + +Prepared standalone server assets. diff --git a/docs/quality/logs/file-diff-summary.log b/docs/quality/logs/file-diff-summary.log new file mode 100644 index 0000000..d81962a --- /dev/null +++ b/docs/quality/logs/file-diff-summary.log @@ -0,0 +1,47 @@ +Only in /mnt/data/phase12_work/RentalDriveGo/docs/architecture: ADR-0003_PHASE_12_COMPONENT_SYSTEM.md +Only in /mnt/data/phase12_work/RentalDriveGo/docs: phase12 +Files /tmp/phase11_original/RentalDriveGo/package.json and /mnt/data/phase12_work/RentalDriveGo/package.json differ +Files /tmp/phase11_original/RentalDriveGo/playwright.config.ts and /mnt/data/phase12_work/RentalDriveGo/playwright.config.ts differ +Only in /mnt/data/phase12_work/RentalDriveGo/scripts: generate-phase12-manifest.mjs +Files /tmp/phase11_original/RentalDriveGo/scripts/run-validations.mjs and /mnt/data/phase12_work/RentalDriveGo/scripts/run-validations.mjs differ +Only in /mnt/data/phase12_work/RentalDriveGo/scripts: validate-phase12-components.mjs +Only in /mnt/data/phase12_work/RentalDriveGo/scripts: validate-phase12-manifest.mjs +Files /tmp/phase11_original/RentalDriveGo/scripts/validate-runtime-dependencies.mjs and /mnt/data/phase12_work/RentalDriveGo/scripts/validate-runtime-dependencies.mjs differ +Only in /mnt/data/phase12_work/RentalDriveGo/src/app/[locale]: component-lab +Files /tmp/phase11_original/RentalDriveGo/src/app/[locale]/layout.tsx and /mnt/data/phase12_work/RentalDriveGo/src/app/[locale]/layout.tsx differ +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: actions +Files /tmp/phase11_original/RentalDriveGo/src/components/app-shell/SiteHeader.tsx and /mnt/data/phase12_work/RentalDriveGo/src/components/app-shell/SiteHeader.tsx differ +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: controls +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: feedback +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: forms +Files /tmp/phase11_original/RentalDriveGo/src/components/foundation/BidiText.tsx and /mnt/data/phase12_work/RentalDriveGo/src/components/foundation/BidiText.tsx differ +Only in /mnt/data/phase12_work/RentalDriveGo/src/components/foundation: Icon.module.css +Only in /mnt/data/phase12_work/RentalDriveGo/src/components/foundation: Icon.tsx +Files /tmp/phase11_original/RentalDriveGo/src/components/foundation/StatusBadge.module.css and /mnt/data/phase12_work/RentalDriveGo/src/components/foundation/StatusBadge.module.css differ +Files /tmp/phase11_original/RentalDriveGo/src/components/foundation/StatusBadge.tsx and /mnt/data/phase12_work/RentalDriveGo/src/components/foundation/StatusBadge.tsx differ +Only in /mnt/data/phase12_work/RentalDriveGo/src/components/foundation: VisuallyHidden.tsx +Only in /mnt/data/phase12_work/RentalDriveGo/src/components/foundation: client-hooks.ts +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: marketing +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: media +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: navigation +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: overlays +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: surfaces +Only in /mnt/data/phase12_work/RentalDriveGo/src/components: typography +Only in /mnt/data/phase12_work/RentalDriveGo/src/content: development +Files /tmp/phase11_original/RentalDriveGo/src/content/locales/ar/shell.json and /mnt/data/phase12_work/RentalDriveGo/src/content/locales/ar/shell.json differ +Files /tmp/phase11_original/RentalDriveGo/src/content/locales/en/shell.json and /mnt/data/phase12_work/RentalDriveGo/src/content/locales/en/shell.json differ +Files /tmp/phase11_original/RentalDriveGo/src/content/locales/fr/shell.json and /mnt/data/phase12_work/RentalDriveGo/src/content/locales/fr/shell.json differ +Only in /mnt/data/phase12_work/RentalDriveGo/src/lib: components +Files /tmp/phase11_original/RentalDriveGo/src/lib/localization/client.ts and /mnt/data/phase12_work/RentalDriveGo/src/lib/localization/client.ts differ +Only in /mnt/data/phase12_work/RentalDriveGo/tests/a11y: component-system.a11y.spec.ts +Only in /mnt/data/phase12_work/RentalDriveGo/tests/browser: component-system.spec.ts +Files /tmp/phase11_original/RentalDriveGo/tests/browser/responsive.spec.ts and /mnt/data/phase12_work/RentalDriveGo/tests/browser/responsive.spec.ts differ +Files /tmp/phase11_original/RentalDriveGo/tests/browser/text-expansion.spec.ts and /mnt/data/phase12_work/RentalDriveGo/tests/browser/text-expansion.spec.ts differ +Files /tmp/phase11_original/RentalDriveGo/tests/browser/theme-csp.spec.ts and /mnt/data/phase12_work/RentalDriveGo/tests/browser/theme-csp.spec.ts differ +Only in /mnt/data/phase12_work/RentalDriveGo/tests/fixtures: component-system +Files /tmp/phase11_original/RentalDriveGo/tests/fixtures/foundation-matrix.json and /mnt/data/phase12_work/RentalDriveGo/tests/fixtures/foundation-matrix.json differ +Only in /mnt/data/phase12_work/RentalDriveGo/tests: types +Only in /mnt/data/phase12_work/RentalDriveGo/tests/unit: components +Only in /mnt/data/phase12_work/RentalDriveGo/tests/visual: component-system.visual.spec.ts +Files /tmp/phase11_original/RentalDriveGo/tsconfig.json and /mnt/data/phase12_work/RentalDriveGo/tsconfig.json differ +Only in /mnt/data/phase12_work/RentalDriveGo: tsconfig.tsbuildinfo diff --git a/docs/quality/logs/format-check.exit b/docs/quality/logs/format-check.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/quality/logs/format-check.exit @@ -0,0 +1 @@ +0 diff --git a/docs/quality/logs/format-check.log b/docs/quality/logs/format-check.log new file mode 100644 index 0000000..7a48bd4 --- /dev/null +++ b/docs/quality/logs/format-check.log @@ -0,0 +1,6 @@ + +> rentaldrivego-web@0.3.0 format:check +> prettier --check . + +Checking formatting... +All matched files use Prettier code style! diff --git a/docs/quality/logs/format-write.exit b/docs/quality/logs/format-write.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/quality/logs/format-write.exit @@ -0,0 +1 @@ +0 diff --git a/docs/quality/logs/format-write.log b/docs/quality/logs/format-write.log new file mode 100644 index 0000000..89eb932 --- /dev/null +++ b/docs/quality/logs/format-write.log @@ -0,0 +1,222 @@ + +> rentaldrivego-web@0.3.0 format +> prettier --write . + +.github/dependabot.yml 20ms (unchanged) +.github/workflows/ci.yml 12ms (unchanged) +CONTRIBUTING.md 27ms (unchanged) +docs/architecture/ADR-0001_REPOSITORY_FOUNDATION.md 34ms (unchanged) +docs/architecture/ADR-0002_PHASE_11_FOUNDATIONS.md 17ms (unchanged) +docs/architecture/ADR-0003_PHASE_12_COMPONENT_SYSTEM.md 4ms (unchanged) +docs/BRAND_MIGRATION_v1.0.md 5ms (unchanged) +docs/DECISION_LOG_v12.0.md 7ms (unchanged) +docs/DEPENDENCY_MANIFEST_v1.0.md 9ms (unchanged) +docs/PHASE_10_HANDOFF_v1.0.md 8ms (unchanged) +docs/PHASE_10_IMPLEMENTATION_REPORT_v1.0.md 18ms (unchanged) +docs/PHASE_11_IMPLEMENTATION_REPORT_v1.0.md 37ms (unchanged) +docs/PHASE_12_HANDOFF_v1.0.md 17ms (unchanged) +docs/PHASE_12_IMPLEMENTATION_REPORT_v1.0.md 24ms (unchanged) +docs/PHASE_13_HANDOFF_v1.0.md 26ms +docs/phase12/BUNDLE_IMPACT_REPORT_v1.0.md 5ms +docs/phase12/COMPONENT_CATALOG_v1.0.md 70ms (unchanged) +docs/phase12/COMPONENT_INVENTORY_v1.0.json 68ms (unchanged) +docs/phase12/DEPENDENCY_CHANGE_REPORT_v1.0.md 3ms (unchanged) +docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.json 2ms (unchanged) +docs/quality/PHASE_11_VALIDATION_RESULTS_v1.0.md 5ms (unchanged) +docs/quality/PHASE_12_HTTP_ROUTE_RESULTS_v1.0.json 2ms (unchanged) +docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.json 4ms +docs/quality/PHASE_12_VALIDATION_RESULTS_v1.0.md 5ms +docs/quality/PHASE_12_VISUAL_REGRESSION_RESULTS_v1.0.json 1ms (unchanged) +docs/quality/VALIDATION_RESULTS_v1.0.json 2ms (unchanged) +docs/quality/VALIDATION_RESULTS_v1.0.md 7ms (unchanged) +docs/quality/VISUAL_REGRESSION_RESULTS_v1.0.json 1ms (unchanged) +docs/TOKEN_IMPLEMENTATION_v1.0.md 4ms (unchanged) +eslint.config.mjs 10ms (unchanged) +next.config.ts 10ms (unchanged) +package.json 2ms (unchanged) +PHASE_10_PACKAGE_MANIFEST_v1.0.json 24ms (unchanged) +PHASE_11_PACKAGE_MANIFEST_v1.0.json 17ms (unchanged) +playwright.config.ts 12ms (unchanged) +pnpm-workspace.yaml 2ms (unchanged) +prettier.config.mjs 4ms (unchanged) +README.md 6ms (unchanged) +scripts/generate-phase10-manifest.mjs 14ms (unchanged) +scripts/generate-phase11-manifest.mjs 7ms (unchanged) +scripts/generate-phase12-manifest.mjs 6ms (unchanged) +scripts/lib.mjs 6ms (unchanged) +scripts/prepare-standalone.mjs 3ms (unchanged) +scripts/run-checks.mjs 2ms (unchanged) +scripts/run-validations.mjs 2ms (unchanged) +scripts/validate-css-logical.mjs 3ms (unchanged) +scripts/validate-locales.mjs 5ms (unchanged) +scripts/validate-metadata.mjs 2ms (unchanged) +scripts/validate-phase10-manifest.mjs 2ms (unchanged) +scripts/validate-phase11-foundation.mjs 4ms (unchanged) +scripts/validate-phase11-manifest.mjs 5ms (unchanged) +scripts/validate-phase12-components.mjs 5ms (unchanged) +scripts/validate-phase12-manifest.mjs 6ms (unchanged) +scripts/validate-phase9-contract.mjs 2ms (unchanged) +scripts/validate-prohibited-content.mjs 2ms (unchanged) +scripts/validate-routes.mjs 3ms (unchanged) +scripts/validate-runtime-dependencies.mjs 4ms (unchanged) +scripts/validate-tokens.mjs 3ms (unchanged) +src/app/[locale]/[slug]/page.tsx 16ms (unchanged) +src/app/[locale]/component-lab/ComponentLabInteractive.tsx 11ms (unchanged) +src/app/[locale]/component-lab/page.module.css 19ms (unchanged) +src/app/[locale]/component-lab/page.tsx 10ms (unchanged) +src/app/[locale]/error.tsx 5ms (unchanged) +src/app/[locale]/layout.tsx 6ms (unchanged) +src/app/[locale]/loading.tsx 2ms (unchanged) +src/app/[locale]/not-found.tsx 1ms (unchanged) +src/app/[locale]/page.module.css 8ms (unchanged) +src/app/[locale]/page.tsx 12ms (unchanged) +src/app/robots.ts 2ms (unchanged) +src/components/actions/ActionLink.module.css 4ms (unchanged) +src/components/actions/ActionLink.tsx 8ms (unchanged) +src/components/actions/Button.module.css 14ms (unchanged) +src/components/actions/Button.tsx 11ms (unchanged) +src/components/app-shell/BrandLink.tsx 4ms (unchanged) +src/components/app-shell/Controls.module.css 3ms (unchanged) +src/components/app-shell/DisabledAction.tsx 3ms (unchanged) +src/components/app-shell/HeaderNavigation.tsx 5ms (unchanged) +src/components/app-shell/LocaleSelector.tsx 4ms (unchanged) +src/components/app-shell/LocalizedLoading.tsx 2ms (unchanged) +src/components/app-shell/LocalizedNotFound.tsx 2ms (unchanged) +src/components/app-shell/MobileNavigation.tsx 9ms (unchanged) +src/components/app-shell/SiteFooter.module.css 6ms (unchanged) +src/components/app-shell/SiteFooter.tsx 11ms (unchanged) +src/components/app-shell/SiteHeader.module.css 11ms (unchanged) +src/components/app-shell/SiteHeader.tsx 4ms (unchanged) +src/components/app-shell/StateShell.module.css 5ms (unchanged) +src/components/app-shell/StateShell.tsx 4ms (unchanged) +src/components/app-shell/ThemeController.tsx 4ms (unchanged) +src/components/app-shell/ThemeSelector.tsx 5ms (unchanged) +src/components/controls/Accordion.module.css 3ms (unchanged) +src/components/controls/Accordion.tsx 3ms (unchanged) +src/components/controls/Pagination.module.css 2ms (unchanged) +src/components/controls/Pagination.tsx 4ms (unchanged) +src/components/controls/SegmentedControl.module.css 2ms (unchanged) +src/components/controls/SegmentedControl.tsx 3ms (unchanged) +src/components/controls/Tabs.module.css 2ms (unchanged) +src/components/controls/Tabs.tsx 10ms (unchanged) +src/components/feedback/Alert.module.css 2ms (unchanged) +src/components/feedback/Alert.tsx 4ms (unchanged) +src/components/feedback/Loading.module.css 4ms (unchanged) +src/components/feedback/Loading.tsx 3ms (unchanged) +src/components/feedback/Progress.module.css 1ms (unchanged) +src/components/feedback/Progress.tsx 3ms (unchanged) +src/components/feedback/StateMessage.module.css 1ms (unchanged) +src/components/feedback/StateMessage.tsx 3ms (unchanged) +src/components/forms/ChoiceControls.module.css 4ms (unchanged) +src/components/forms/ChoiceControls.tsx 5ms (unchanged) +src/components/forms/ErrorSummary.module.css 2ms (unchanged) +src/components/forms/ErrorSummary.tsx 3ms (unchanged) +src/components/forms/FormField.module.css 3ms (unchanged) +src/components/forms/FormField.tsx 4ms (unchanged) +src/components/forms/TextInput.module.css 3ms (unchanged) +src/components/forms/TextInput.tsx 5ms (unchanged) +src/components/foundation/AccessibleIcon.tsx 2ms (unchanged) +src/components/foundation/BidiText.module.css 1ms (unchanged) +src/components/foundation/BidiText.tsx 2ms (unchanged) +src/components/foundation/client-hooks.ts 6ms (unchanged) +src/components/foundation/Icon.module.css 2ms (unchanged) +src/components/foundation/Icon.tsx 7ms (unchanged) +src/components/foundation/LiveRegion.module.css 1ms (unchanged) +src/components/foundation/LiveRegion.tsx 3ms (unchanged) +src/components/foundation/StatusBadge.module.css 2ms (unchanged) +src/components/foundation/StatusBadge.tsx 2ms (unchanged) +src/components/foundation/VisuallyHidden.tsx 2ms (unchanged) +src/components/layout/LayoutPrimitives.module.css 6ms (unchanged) +src/components/layout/LayoutPrimitives.tsx 5ms (unchanged) +src/components/marketing/Comparison.module.css 2ms (unchanged) +src/components/marketing/Comparison.tsx 6ms (unchanged) +src/components/marketing/CTA.module.css 2ms (unchanged) +src/components/marketing/CTA.tsx 4ms (unchanged) +src/components/marketing/Evidence.module.css 1ms (unchanged) +src/components/marketing/Evidence.tsx 4ms (unchanged) +src/components/marketing/FeatureCard.module.css 1ms (unchanged) +src/components/marketing/FeatureCard.tsx 3ms (unchanged) +src/components/marketing/ProductPreview.module.css 4ms (unchanged) +src/components/marketing/ProductPreview.tsx 4ms (unchanged) +src/components/marketing/SectionHeader.module.css 1ms (unchanged) +src/components/marketing/SectionHeader.tsx 2ms (unchanged) +src/components/marketing/SectionPatterns.module.css 4ms (unchanged) +src/components/marketing/SectionPatterns.tsx 3ms (unchanged) +src/components/marketing/Workflow.module.css 3ms (unchanged) +src/components/marketing/Workflow.tsx 4ms (unchanged) +src/components/media/MediaFrame.module.css 2ms (unchanged) +src/components/media/MediaFrame.tsx 3ms (unchanged) +src/components/navigation/Breadcrumbs.module.css 1ms (unchanged) +src/components/navigation/Breadcrumbs.tsx 4ms (unchanged) +src/components/navigation/FooterLinkGroup.module.css 1ms (unchanged) +src/components/navigation/FooterLinkGroup.tsx 2ms (unchanged) +src/components/navigation/SectionNavigation.module.css 2ms (unchanged) +src/components/navigation/SectionNavigation.tsx 2ms (unchanged) +src/components/overlays/Dialog.module.css 4ms (unchanged) +src/components/overlays/Dialog.tsx 6ms (unchanged) +src/components/overlays/DropdownMenu.module.css 3ms (unchanged) +src/components/overlays/DropdownMenu.tsx 6ms (unchanged) +src/components/overlays/Tooltip.module.css 4ms (unchanged) +src/components/overlays/Tooltip.tsx 1ms (unchanged) +src/components/surfaces/Callout.module.css 1ms (unchanged) +src/components/surfaces/Callout.tsx 1ms (unchanged) +src/components/surfaces/Card.module.css 2ms (unchanged) +src/components/surfaces/Card.tsx 3ms (unchanged) +src/components/typography/Typography.module.css 3ms (unchanged) +src/components/typography/Typography.tsx 3ms (unchanged) +src/content/development/component-lab.ts 19ms (unchanged) +src/content/locales/ar/homepage.json 6ms (unchanged) +src/content/locales/ar/shell.json 2ms (unchanged) +src/content/locales/en/homepage.json 4ms (unchanged) +src/content/locales/en/shell.json 2ms (unchanged) +src/content/locales/fr/homepage.json 6ms (unchanged) +src/content/locales/fr/shell.json 1ms (unchanged) +src/contracts/phase9/analytics-contract.ts 2ms (unchanged) +src/contracts/phase9/component-contracts.ts 6ms (unchanged) +src/contracts/phase9/demo-form-contract.ts 2ms (unchanged) +src/contracts/phase9/design-tokens.json 2ms (unchanged) +src/contracts/phase9/performance-budgets.json 1ms (unchanged) +src/contracts/phase9/route-manifest.json 1ms (unchanged) +src/contracts/phase9/visual-regression-scenarios.json 2ms (unchanged) +src/lib/components/classNames.ts 1ms (unchanged) +src/lib/localization/client-messages.ts 3ms (unchanged) +src/lib/localization/client.ts 3ms (unchanged) +src/lib/localization/config.ts 14ms (unchanged) +src/lib/localization/format.ts 5ms (unchanged) +src/lib/localization/messages.ts 2ms (unchanged) +src/lib/localization/site-origin.ts 3ms (unchanged) +src/lib/metadata/build-metadata.ts 3ms (unchanged) +src/lib/security/csp.ts 2ms (unchanged) +src/lib/theme/bootstrap-script.ts 1ms (unchanged) +src/lib/theme/client.ts 5ms (unchanged) +src/lib/theme/config.ts 3ms (unchanged) +src/proxy.ts 6ms (unchanged) +src/styles/component-tokens.css 10ms (unchanged) +src/styles/globals.css 6ms (unchanged) +tests/a11y/component-system.a11y.spec.ts 2ms (unchanged) +tests/a11y/shell.a11y.spec.ts 3ms (unchanged) +tests/browser/component-system.spec.ts 5ms (unchanged) +tests/browser/navigation.spec.ts 3ms (unchanged) +tests/browser/no-javascript.spec.ts 2ms (unchanged) +tests/browser/responsive.spec.ts 5ms (unchanged) +tests/browser/shell.spec.ts 14ms (unchanged) +tests/browser/text-expansion.spec.ts 4ms (unchanged) +tests/browser/theme-csp.spec.ts 12ms (unchanged) +tests/fixtures/component-system/component-matrix.json 1ms (unchanged) +tests/fixtures/foundation-matrix.json 3ms (unchanged) +tests/fixtures/README.md 5ms (unchanged) +tests/setup.ts 1ms (unchanged) +tests/types/component-contracts.test-d.tsx 2ms (unchanged) +tests/unit/components/actions.test.tsx 3ms (unchanged) +tests/unit/components/controls.test.tsx 4ms (unchanged) +tests/unit/components/evidence.test.tsx 3ms (unchanged) +tests/unit/components/forms.test.tsx 3ms (unchanged) +tests/unit/csp.test.ts 2ms (unchanged) +tests/unit/format.test.ts 3ms (unchanged) +tests/unit/localization.test.ts 4ms (unchanged) +tests/unit/theme.test.ts 2ms (unchanged) +tests/visual/component-system.visual.spec.ts 3ms (unchanged) +tests/visual/README.md 2ms (unchanged) +tests/visual/shell.visual.spec.ts 6ms (unchanged) +tsconfig.json 1ms (unchanged) +vitest.config.ts 2ms (unchanged) diff --git a/docs/quality/logs/lint.exit b/docs/quality/logs/lint.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/quality/logs/lint.exit @@ -0,0 +1 @@ +0 diff --git a/docs/quality/logs/lint.log b/docs/quality/logs/lint.log new file mode 100644 index 0000000..0d48927 --- /dev/null +++ b/docs/quality/logs/lint.log @@ -0,0 +1,4 @@ + +> rentaldrivego-web@0.3.0 lint +> eslint . --max-warnings=0 + diff --git a/docs/quality/logs/next-typegen.exit b/docs/quality/logs/next-typegen.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/quality/logs/next-typegen.exit @@ -0,0 +1 @@ +0 diff --git a/docs/quality/logs/next-typegen.log b/docs/quality/logs/next-typegen.log new file mode 100644 index 0000000..7bab5fc --- /dev/null +++ b/docs/quality/logs/next-typegen.log @@ -0,0 +1,2 @@ +Generating route types... +✓ Types generated successfully diff --git a/docs/quality/logs/npm-install-fallback.log b/docs/quality/logs/npm-install-fallback.log new file mode 100644 index 0000000..a4c700a --- /dev/null +++ b/docs/quality/logs/npm-install-fallback.log @@ -0,0 +1,7 @@ +npm warn EBADENGINE Unsupported engine { +npm warn EBADENGINE package: 'rentaldrivego-web@0.3.0', +npm warn EBADENGINE required: { node: '24.17.0', pnpm: '11.9.0' }, +npm warn EBADENGINE current: { node: 'v22.16.0', npm: '10.9.2' } +npm warn EBADENGINE } + +added 462 packages in 30s diff --git a/docs/quality/logs/playwright-browser-a11y.log b/docs/quality/logs/playwright-browser-a11y.log new file mode 100644 index 0000000..80c31fe --- /dev/null +++ b/docs/quality/logs/playwright-browser-a11y.log @@ -0,0 +1,57 @@ + +Running 44 tests using 2 workers +××××F::error file=tests/a11y/component-system.a11y.spec.ts,title=[chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › en component fixture has no detectable accessibility violations,line=8,col=16:: 1) [chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › en component fixture has no detectable accessibility violations %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en/component-lab", waiting until "load"%0A%0A%0A 6 | page,%0A 7 | }) => {%0A > 8 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 9 | const results = await new AxeBuilder({ page }).analyze();%0A 10 | expect(results.violations).toEqual([]);%0A 11 | });%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/component-system.a11y.spec.ts:8:16 +::error file=tests/a11y/component-system.a11y.spec.ts,title=[chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › en component fixture has no detectable accessibility violations,line=8,col=16:: 1) [chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › en component fixture has no detectable accessibility violations %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en/component-lab", waiting until "load"%0A%0A%0A 6 | page,%0A 7 | }) => {%0A > 8 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 9 | const results = await new AxeBuilder({ page }).analyze();%0A 10 | expect(results.violations).toEqual([]);%0A 11 | });%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/component-system.a11y.spec.ts:8:16 +::error file=tests/a11y/component-system.a11y.spec.ts,title=[chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › en component fixture has no detectable accessibility violations,line=8,col=16:: 1) [chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › en component fixture has no detectable accessibility violations %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en/component-lab", waiting until "load"%0A%0A%0A 6 | page,%0A 7 | }) => {%0A > 8 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 9 | const results = await new AxeBuilder({ page }).analyze();%0A 10 | expect(results.violations).toEqual([]);%0A 11 | });%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/component-system.a11y.spec.ts:8:16 +F::error file=tests/a11y/component-system.a11y.spec.ts,title=[chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › fr component fixture has no detectable accessibility violations,line=8,col=16:: 2) [chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › fr component fixture has no detectable accessibility violations %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/fr/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/fr/component-lab", waiting until "load"%0A%0A%0A 6 | page,%0A 7 | }) => {%0A > 8 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 9 | const results = await new AxeBuilder({ page }).analyze();%0A 10 | expect(results.violations).toEqual([]);%0A 11 | });%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/component-system.a11y.spec.ts:8:16 +::error file=tests/a11y/component-system.a11y.spec.ts,title=[chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › fr component fixture has no detectable accessibility violations,line=8,col=16:: 2) [chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › fr component fixture has no detectable accessibility violations %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/fr/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/fr/component-lab", waiting until "load"%0A%0A%0A 6 | page,%0A 7 | }) => {%0A > 8 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 9 | const results = await new AxeBuilder({ page }).analyze();%0A 10 | expect(results.violations).toEqual([]);%0A 11 | });%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/component-system.a11y.spec.ts:8:16 +::error file=tests/a11y/component-system.a11y.spec.ts,title=[chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › fr component fixture has no detectable accessibility violations,line=8,col=16:: 2) [chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › fr component fixture has no detectable accessibility violations %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/fr/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/fr/component-lab", waiting until "load"%0A%0A%0A 6 | page,%0A 7 | }) => {%0A > 8 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 9 | const results = await new AxeBuilder({ page }).analyze();%0A 10 | expect(results.violations).toEqual([]);%0A 11 | });%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/component-system.a11y.spec.ts:8:16 +××××F::error file=tests/a11y/component-system.a11y.spec.ts,title=[chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › ar component fixture has no detectable accessibility violations,line=8,col=16:: 3) [chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › ar component fixture has no detectable accessibility violations %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/ar/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/ar/component-lab", waiting until "load"%0A%0A%0A 6 | page,%0A 7 | }) => {%0A > 8 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 9 | const results = await new AxeBuilder({ page }).analyze();%0A 10 | expect(results.violations).toEqual([]);%0A 11 | });%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/component-system.a11y.spec.ts:8:16 +::error file=tests/a11y/component-system.a11y.spec.ts,title=[chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › ar component fixture has no detectable accessibility violations,line=8,col=16:: 3) [chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › ar component fixture has no detectable accessibility violations %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/ar/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/ar/component-lab", waiting until "load"%0A%0A%0A 6 | page,%0A 7 | }) => {%0A > 8 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 9 | const results = await new AxeBuilder({ page }).analyze();%0A 10 | expect(results.violations).toEqual([]);%0A 11 | });%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/component-system.a11y.spec.ts:8:16 +::error file=tests/a11y/component-system.a11y.spec.ts,title=[chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › ar component fixture has no detectable accessibility violations,line=8,col=16:: 3) [chromium] › tests/a11y/component-system.a11y.spec.ts:5:7 › ar component fixture has no detectable accessibility violations %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/ar/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/ar/component-lab", waiting until "load"%0A%0A%0A 6 | page,%0A 7 | }) => {%0A > 8 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 9 | const results = await new AxeBuilder({ page }).analyze();%0A 10 | expect(results.violations).toEqual([]);%0A 11 | });%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/component-system.a11y.spec.ts:8:16 +F::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › en light shell has no detectable WCAG A/AA violations,line=20,col=18:: 4) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › en light shell has no detectable WCAG A/AA violations %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › en light shell has no detectable WCAG A/AA violations,line=20,col=18:: 4) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › en light shell has no detectable WCAG A/AA violations %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › en light shell has no detectable WCAG A/AA violations,line=20,col=18:: 4) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › en light shell has no detectable WCAG A/AA violations %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +××××F::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › en dark shell has no detectable WCAG A/AA violations,line=20,col=18:: 5) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › en dark shell has no detectable WCAG A/AA violations %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › en dark shell has no detectable WCAG A/AA violations,line=20,col=18:: 5) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › en dark shell has no detectable WCAG A/AA violations %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › en dark shell has no detectable WCAG A/AA violations,line=20,col=18:: 5) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › en dark shell has no detectable WCAG A/AA violations %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +F::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › fr light shell has no detectable WCAG A/AA violations,line=20,col=18:: 6) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › fr light shell has no detectable WCAG A/AA violations %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/fr%0A Call log:%0A - navigating to "http://127.0.0.1:3000/fr", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › fr light shell has no detectable WCAG A/AA violations,line=20,col=18:: 6) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › fr light shell has no detectable WCAG A/AA violations %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/fr%0A Call log:%0A - navigating to "http://127.0.0.1:3000/fr", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › fr light shell has no detectable WCAG A/AA violations,line=20,col=18:: 6) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › fr light shell has no detectable WCAG A/AA violations %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/fr%0A Call log:%0A - navigating to "http://127.0.0.1:3000/fr", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +××××F::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › fr dark shell has no detectable WCAG A/AA violations,line=20,col=18:: 7) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › fr dark shell has no detectable WCAG A/AA violations %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/fr%0A Call log:%0A - navigating to "http://127.0.0.1:3000/fr", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › fr dark shell has no detectable WCAG A/AA violations,line=20,col=18:: 7) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › fr dark shell has no detectable WCAG A/AA violations %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/fr%0A Call log:%0A - navigating to "http://127.0.0.1:3000/fr", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › fr dark shell has no detectable WCAG A/AA violations,line=20,col=18:: 7) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › fr dark shell has no detectable WCAG A/AA violations %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/fr%0A Call log:%0A - navigating to "http://127.0.0.1:3000/fr", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +F::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › ar light shell has no detectable WCAG A/AA violations,line=20,col=18:: 8) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › ar light shell has no detectable WCAG A/AA violations %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/ar%0A Call log:%0A - navigating to "http://127.0.0.1:3000/ar", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › ar light shell has no detectable WCAG A/AA violations,line=20,col=18:: 8) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › ar light shell has no detectable WCAG A/AA violations %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/ar%0A Call log:%0A - navigating to "http://127.0.0.1:3000/ar", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › ar light shell has no detectable WCAG A/AA violations,line=20,col=18:: 8) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › ar light shell has no detectable WCAG A/AA violations %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/ar%0A Call log:%0A - navigating to "http://127.0.0.1:3000/ar", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +××××F::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › ar dark shell has no detectable WCAG A/AA violations,line=20,col=18:: 9) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › ar dark shell has no detectable WCAG A/AA violations %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/ar%0A Call log:%0A - navigating to "http://127.0.0.1:3000/ar", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › ar dark shell has no detectable WCAG A/AA violations,line=20,col=18:: 9) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › ar dark shell has no detectable WCAG A/AA violations %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/ar%0A Call log:%0A - navigating to "http://127.0.0.1:3000/ar", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +::error file=tests/a11y/shell.a11y.spec.ts,title=[chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › ar dark shell has no detectable WCAG A/AA violations,line=20,col=18:: 9) [chromium] › tests/a11y/shell.a11y.spec.ts:6:9 › ar dark shell has no detectable WCAG A/AA violations %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/ar%0A Call log:%0A - navigating to "http://127.0.0.1:3000/ar", waiting until "load"%0A%0A%0A 18 | },%0A 19 | ]);%0A > 20 | await page.goto(`/${locale}`);%0A | ^%0A 21 | const results = await new AxeBuilder({ page })%0A 22 | .withTags(['wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'])%0A 23 | .analyze();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/a11y/shell.a11y.spec.ts:20:18 +F::error file=tests/browser/component-system.spec.ts,title=[chromium] › tests/browser/component-system.spec.ts:4:7 › en component fixture renders without horizontal overflow,line=5,col=16:: 10) [chromium] › tests/browser/component-system.spec.ts:4:7 › en component fixture renders without horizontal overflow %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en/component-lab", waiting until "load"%0A%0A%0A 3 | for (const locale of ['en', 'fr', 'ar'] as const) {%0A 4 | test(`${locale} component fixture renders without horizontal overflow`, async ({ page }) => {%0A > 5 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 6 | await expect(page.locator('h1')).toBeVisible();%0A 7 | const overflow = await page.evaluate(%0A 8 | () => document.documentElement.scrollWidth > document.documentElement.clientWidth,%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/component-system.spec.ts:5:16 +::error file=tests/browser/component-system.spec.ts,title=[chromium] › tests/browser/component-system.spec.ts:4:7 › en component fixture renders without horizontal overflow,line=5,col=16:: 10) [chromium] › tests/browser/component-system.spec.ts:4:7 › en component fixture renders without horizontal overflow %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en/component-lab", waiting until "load"%0A%0A%0A 3 | for (const locale of ['en', 'fr', 'ar'] as const) {%0A 4 | test(`${locale} component fixture renders without horizontal overflow`, async ({ page }) => {%0A > 5 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 6 | await expect(page.locator('h1')).toBeVisible();%0A 7 | const overflow = await page.evaluate(%0A 8 | () => document.documentElement.scrollWidth > document.documentElement.clientWidth,%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/component-system.spec.ts:5:16 +::error file=tests/browser/component-system.spec.ts,title=[chromium] › tests/browser/component-system.spec.ts:4:7 › en component fixture renders without horizontal overflow,line=5,col=16:: 10) [chromium] › tests/browser/component-system.spec.ts:4:7 › en component fixture renders without horizontal overflow %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en/component-lab", waiting until "load"%0A%0A%0A 3 | for (const locale of ['en', 'fr', 'ar'] as const) {%0A 4 | test(`${locale} component fixture renders without horizontal overflow`, async ({ page }) => {%0A > 5 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 6 | await expect(page.locator('h1')).toBeVisible();%0A 7 | const overflow = await page.evaluate(%0A 8 | () => document.documentElement.scrollWidth > document.documentElement.clientWidth,%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/component-system.spec.ts:5:16 +××××F::error file=tests/browser/component-system.spec.ts,title=[chromium] › tests/browser/component-system.spec.ts:4:7 › fr component fixture renders without horizontal overflow,line=5,col=16:: 11) [chromium] › tests/browser/component-system.spec.ts:4:7 › fr component fixture renders without horizontal overflow %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/fr/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/fr/component-lab", waiting until "load"%0A%0A%0A 3 | for (const locale of ['en', 'fr', 'ar'] as const) {%0A 4 | test(`${locale} component fixture renders without horizontal overflow`, async ({ page }) => {%0A > 5 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 6 | await expect(page.locator('h1')).toBeVisible();%0A 7 | const overflow = await page.evaluate(%0A 8 | () => document.documentElement.scrollWidth > document.documentElement.clientWidth,%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/component-system.spec.ts:5:16 +::error file=tests/browser/component-system.spec.ts,title=[chromium] › tests/browser/component-system.spec.ts:4:7 › fr component fixture renders without horizontal overflow,line=5,col=16:: 11) [chromium] › tests/browser/component-system.spec.ts:4:7 › fr component fixture renders without horizontal overflow %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/fr/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/fr/component-lab", waiting until "load"%0A%0A%0A 3 | for (const locale of ['en', 'fr', 'ar'] as const) {%0A 4 | test(`${locale} component fixture renders without horizontal overflow`, async ({ page }) => {%0A > 5 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 6 | await expect(page.locator('h1')).toBeVisible();%0A 7 | const overflow = await page.evaluate(%0A 8 | () => document.documentElement.scrollWidth > document.documentElement.clientWidth,%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/component-system.spec.ts:5:16 +::error file=tests/browser/component-system.spec.ts,title=[chromium] › tests/browser/component-system.spec.ts:4:7 › fr component fixture renders without horizontal overflow,line=5,col=16:: 11) [chromium] › tests/browser/component-system.spec.ts:4:7 › fr component fixture renders without horizontal overflow %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/fr/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/fr/component-lab", waiting until "load"%0A%0A%0A 3 | for (const locale of ['en', 'fr', 'ar'] as const) {%0A 4 | test(`${locale} component fixture renders without horizontal overflow`, async ({ page }) => {%0A > 5 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 6 | await expect(page.locator('h1')).toBeVisible();%0A 7 | const overflow = await page.evaluate(%0A 8 | () => document.documentElement.scrollWidth > document.documentElement.clientWidth,%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/component-system.spec.ts:5:16 +F::error file=tests/browser/component-system.spec.ts,title=[chromium] › tests/browser/component-system.spec.ts:4:7 › ar component fixture renders without horizontal overflow,line=5,col=16:: 12) [chromium] › tests/browser/component-system.spec.ts:4:7 › ar component fixture renders without horizontal overflow %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/ar/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/ar/component-lab", waiting until "load"%0A%0A%0A 3 | for (const locale of ['en', 'fr', 'ar'] as const) {%0A 4 | test(`${locale} component fixture renders without horizontal overflow`, async ({ page }) => {%0A > 5 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 6 | await expect(page.locator('h1')).toBeVisible();%0A 7 | const overflow = await page.evaluate(%0A 8 | () => document.documentElement.scrollWidth > document.documentElement.clientWidth,%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/component-system.spec.ts:5:16 +::error file=tests/browser/component-system.spec.ts,title=[chromium] › tests/browser/component-system.spec.ts:4:7 › ar component fixture renders without horizontal overflow,line=5,col=16:: 12) [chromium] › tests/browser/component-system.spec.ts:4:7 › ar component fixture renders without horizontal overflow %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/ar/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/ar/component-lab", waiting until "load"%0A%0A%0A 3 | for (const locale of ['en', 'fr', 'ar'] as const) {%0A 4 | test(`${locale} component fixture renders without horizontal overflow`, async ({ page }) => {%0A > 5 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 6 | await expect(page.locator('h1')).toBeVisible();%0A 7 | const overflow = await page.evaluate(%0A 8 | () => document.documentElement.scrollWidth > document.documentElement.clientWidth,%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/component-system.spec.ts:5:16 +::error file=tests/browser/component-system.spec.ts,title=[chromium] › tests/browser/component-system.spec.ts:4:7 › ar component fixture renders without horizontal overflow,line=5,col=16:: 12) [chromium] › tests/browser/component-system.spec.ts:4:7 › ar component fixture renders without horizontal overflow %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/ar/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/ar/component-lab", waiting until "load"%0A%0A%0A 3 | for (const locale of ['en', 'fr', 'ar'] as const) {%0A 4 | test(`${locale} component fixture renders without horizontal overflow`, async ({ page }) => {%0A > 5 | await page.goto(`/${locale}/component-lab`);%0A | ^%0A 6 | await expect(page.locator('h1')).toBeVisible();%0A 7 | const overflow = await page.evaluate(%0A 8 | () => document.documentElement.scrollWidth > document.documentElement.clientWidth,%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/component-system.spec.ts:5:16 +××××F::error file=tests/browser/component-system.spec.ts,title=[chromium] › tests/browser/component-system.spec.ts:15:5 › component controls support keyboard interaction and dialog focus return,line=18,col=14:: 13) [chromium] › tests/browser/component-system.spec.ts:15:5 › component controls support keyboard interaction and dialog focus return %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en/component-lab", waiting until "load"%0A%0A%0A 16 | page,%0A 17 | }) => {%0A > 18 | await page.goto('/en/component-lab');%0A | ^%0A 19 | const firstTab = page.getByRole('tab', { name: 'Reservations' });%0A 20 | await firstTab.focus();%0A 21 | await page.keyboard.press('ArrowRight');%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/component-system.spec.ts:18:14 +::error file=tests/browser/component-system.spec.ts,title=[chromium] › tests/browser/component-system.spec.ts:15:5 › component controls support keyboard interaction and dialog focus return,line=18,col=14:: 13) [chromium] › tests/browser/component-system.spec.ts:15:5 › component controls support keyboard interaction and dialog focus return %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en/component-lab", waiting until "load"%0A%0A%0A 16 | page,%0A 17 | }) => {%0A > 18 | await page.goto('/en/component-lab');%0A | ^%0A 19 | const firstTab = page.getByRole('tab', { name: 'Reservations' });%0A 20 | await firstTab.focus();%0A 21 | await page.keyboard.press('ArrowRight');%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/component-system.spec.ts:18:14 +::error file=tests/browser/component-system.spec.ts,title=[chromium] › tests/browser/component-system.spec.ts:15:5 › component controls support keyboard interaction and dialog focus return,line=18,col=14:: 13) [chromium] › tests/browser/component-system.spec.ts:15:5 › component controls support keyboard interaction and dialog focus return %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en/component-lab", waiting until "load"%0A%0A%0A 16 | page,%0A 17 | }) => {%0A > 18 | await page.goto('/en/component-lab');%0A | ^%0A 19 | const firstTab = page.getByRole('tab', { name: 'Reservations' });%0A 20 | await firstTab.focus();%0A 21 | await page.keyboard.press('ArrowRight');%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/component-system.spec.ts:18:14 +F::error file=tests/browser/component-system.spec.ts,title=[chromium] › tests/browser/component-system.spec.ts:35:5 › component fixture reflows at narrow mobile and 200 percent zoom equivalent,line=39,col=14:: 14) [chromium] › tests/browser/component-system.spec.ts:35:5 › component fixture reflows at narrow mobile and 200 percent zoom equivalent %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/fr/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/fr/component-lab", waiting until "load"%0A%0A%0A 37 | }) => {%0A 38 | await page.setViewportSize({ width: 320, height: 800 });%0A > 39 | await page.goto('/fr/component-lab');%0A | ^%0A 40 | await page.evaluate(() => (document.body.style.zoom = '2'));%0A 41 | const overflow = await page.evaluate(%0A 42 | () => document.documentElement.scrollWidth > document.documentElement.clientWidth + 1,%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/component-system.spec.ts:39:14 +::error file=tests/browser/component-system.spec.ts,title=[chromium] › tests/browser/component-system.spec.ts:35:5 › component fixture reflows at narrow mobile and 200 percent zoom equivalent,line=39,col=14:: 14) [chromium] › tests/browser/component-system.spec.ts:35:5 › component fixture reflows at narrow mobile and 200 percent zoom equivalent %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/fr/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/fr/component-lab", waiting until "load"%0A%0A%0A 37 | }) => {%0A 38 | await page.setViewportSize({ width: 320, height: 800 });%0A > 39 | await page.goto('/fr/component-lab');%0A | ^%0A 40 | await page.evaluate(() => (document.body.style.zoom = '2'));%0A 41 | const overflow = await page.evaluate(%0A 42 | () => document.documentElement.scrollWidth > document.documentElement.clientWidth + 1,%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/component-system.spec.ts:39:14 +::error file=tests/browser/component-system.spec.ts,title=[chromium] › tests/browser/component-system.spec.ts:35:5 › component fixture reflows at narrow mobile and 200 percent zoom equivalent,line=39,col=14:: 14) [chromium] › tests/browser/component-system.spec.ts:35:5 › component fixture reflows at narrow mobile and 200 percent zoom equivalent %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/fr/component-lab%0A Call log:%0A - navigating to "http://127.0.0.1:3000/fr/component-lab", waiting until "load"%0A%0A%0A 37 | }) => {%0A 38 | await page.setViewportSize({ width: 320, height: 800 });%0A > 39 | await page.goto('/fr/component-lab');%0A | ^%0A 40 | await page.evaluate(() => (document.body.style.zoom = '2'));%0A 41 | const overflow = await page.evaluate(%0A 42 | () => document.documentElement.scrollWidth > document.documentElement.clientWidth + 1,%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/component-system.spec.ts:39:14 +××××F::error file=tests/browser/navigation.spec.ts,title=[chromium] › tests/browser/navigation.spec.ts:5:5 › mobile navigation opens modally, closes with Escape, and returns focus,line=6,col=14:: 15) [chromium] › tests/browser/navigation.spec.ts:5:5 › mobile navigation opens modally, closes with Escape, and returns focus %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en", waiting until "load"%0A%0A%0A 4 |%0A 5 | test('mobile navigation opens modally, closes with Escape, and returns focus', async ({ page }) => {%0A > 6 | await page.goto('/en');%0A | ^%0A 7 | const trigger = page.getByRole('button', { name: 'Open navigation menu' });%0A 8 | await trigger.focus();%0A 9 | await trigger.click();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/navigation.spec.ts:6:14 +::error file=tests/browser/navigation.spec.ts,title=[chromium] › tests/browser/navigation.spec.ts:5:5 › mobile navigation opens modally, closes with Escape, and returns focus,line=6,col=14:: 15) [chromium] › tests/browser/navigation.spec.ts:5:5 › mobile navigation opens modally, closes with Escape, and returns focus %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en", waiting until "load"%0A%0A%0A 4 |%0A 5 | test('mobile navigation opens modally, closes with Escape, and returns focus', async ({ page }) => {%0A > 6 | await page.goto('/en');%0A | ^%0A 7 | const trigger = page.getByRole('button', { name: 'Open navigation menu' });%0A 8 | await trigger.focus();%0A 9 | await trigger.click();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/navigation.spec.ts:6:14 +::error file=tests/browser/navigation.spec.ts,title=[chromium] › tests/browser/navigation.spec.ts:5:5 › mobile navigation opens modally, closes with Escape, and returns focus,line=6,col=14:: 15) [chromium] › tests/browser/navigation.spec.ts:5:5 › mobile navigation opens modally, closes with Escape, and returns focus %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en", waiting until "load"%0A%0A%0A 4 |%0A 5 | test('mobile navigation opens modally, closes with Escape, and returns focus', async ({ page }) => {%0A > 6 | await page.goto('/en');%0A | ^%0A 7 | const trigger = page.getByRole('button', { name: 'Open navigation menu' });%0A 8 | await trigger.focus();%0A 9 | await trigger.click();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/navigation.spec.ts:6:14 +F::error file=tests/browser/navigation.spec.ts,title=[chromium] › tests/browser/navigation.spec.ts:21:5 › skip navigation moves focus to the main landmark,line=22,col=14:: 16) [chromium] › tests/browser/navigation.spec.ts:21:5 › skip navigation moves focus to the main landmark %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en", waiting until "load"%0A%0A%0A 20 |%0A 21 | test('skip navigation moves focus to the main landmark', async ({ page }) => {%0A > 22 | await page.goto('/en');%0A | ^%0A 23 | await page.keyboard.press('Tab');%0A 24 | const skip = page.getByRole('link', { name: 'Skip to main content' });%0A 25 | await expect(skip).toBeFocused();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/navigation.spec.ts:22:14 +::error file=tests/browser/navigation.spec.ts,title=[chromium] › tests/browser/navigation.spec.ts:21:5 › skip navigation moves focus to the main landmark,line=22,col=14:: 16) [chromium] › tests/browser/navigation.spec.ts:21:5 › skip navigation moves focus to the main landmark %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en", waiting until "load"%0A%0A%0A 20 |%0A 21 | test('skip navigation moves focus to the main landmark', async ({ page }) => {%0A > 22 | await page.goto('/en');%0A | ^%0A 23 | await page.keyboard.press('Tab');%0A 24 | const skip = page.getByRole('link', { name: 'Skip to main content' });%0A 25 | await expect(skip).toBeFocused();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/navigation.spec.ts:22:14 +::error file=tests/browser/navigation.spec.ts,title=[chromium] › tests/browser/navigation.spec.ts:21:5 › skip navigation moves focus to the main landmark,line=22,col=14:: 16) [chromium] › tests/browser/navigation.spec.ts:21:5 › skip navigation moves focus to the main landmark %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en", waiting until "load"%0A%0A%0A 20 |%0A 21 | test('skip navigation moves focus to the main landmark', async ({ page }) => {%0A > 22 | await page.goto('/en');%0A | ^%0A 23 | await page.keyboard.press('Tab');%0A 24 | const skip = page.getByRole('link', { name: 'Skip to main content' });%0A 25 | await expect(skip).toBeFocused();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/navigation.spec.ts:22:14 +××××F::error file=tests/browser/no-javascript.spec.ts,title=[chromium] › tests/browser/no-javascript.spec.ts:3:5 › server shell remains readable with JavaScript disabled,line=6,col=14:: 17) [chromium] › tests/browser/no-javascript.spec.ts:3:5 › server shell remains readable with JavaScript disabled %0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/ar%0A Call log:%0A - navigating to "http://127.0.0.1:3000/ar", waiting until "load"%0A%0A%0A 4 | const context = await browser.newContext({ javaScriptEnabled: false, colorScheme: 'dark' });%0A 5 | const page = await context.newPage();%0A > 6 | await page.goto('/ar');%0A | ^%0A 7 | await expect(page.locator('html')).toHaveAttribute('lang', 'ar');%0A 8 | await expect(page.locator('html')).toHaveAttribute('dir', 'rtl');%0A 9 | await expect(page.locator('h1')).toBeVisible();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/no-javascript.spec.ts:6:14 +::error file=tests/browser/no-javascript.spec.ts,title=[chromium] › tests/browser/no-javascript.spec.ts:3:5 › server shell remains readable with JavaScript disabled,line=6,col=14:: 17) [chromium] › tests/browser/no-javascript.spec.ts:3:5 › server shell remains readable with JavaScript disabled %0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/ar%0A Call log:%0A - navigating to "http://127.0.0.1:3000/ar", waiting until "load"%0A%0A%0A 4 | const context = await browser.newContext({ javaScriptEnabled: false, colorScheme: 'dark' });%0A 5 | const page = await context.newPage();%0A > 6 | await page.goto('/ar');%0A | ^%0A 7 | await expect(page.locator('html')).toHaveAttribute('lang', 'ar');%0A 8 | await expect(page.locator('html')).toHaveAttribute('dir', 'rtl');%0A 9 | await expect(page.locator('h1')).toBeVisible();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/no-javascript.spec.ts:6:14 +::error file=tests/browser/no-javascript.spec.ts,title=[chromium] › tests/browser/no-javascript.spec.ts:3:5 › server shell remains readable with JavaScript disabled,line=6,col=14:: 17) [chromium] › tests/browser/no-javascript.spec.ts:3:5 › server shell remains readable with JavaScript disabled %0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/ar%0A Call log:%0A - navigating to "http://127.0.0.1:3000/ar", waiting until "load"%0A%0A%0A 4 | const context = await browser.newContext({ javaScriptEnabled: false, colorScheme: 'dark' });%0A 5 | const page = await context.newPage();%0A > 6 | await page.goto('/ar');%0A | ^%0A 7 | await expect(page.locator('html')).toHaveAttribute('lang', 'ar');%0A 8 | await expect(page.locator('html')).toHaveAttribute('dir', 'rtl');%0A 9 | await expect(page.locator('h1')).toBeVisible();%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/no-javascript.spec.ts:6:14 +F::error file=tests/browser/responsive.spec.ts,title=[chromium] › tests/browser/responsive.spec.ts:7:9 › en has no horizontal overflow at 320px,line=9,col=18:: 18) [chromium] › tests/browser/responsive.spec.ts:7:9 › en has no horizontal overflow at 320px ───%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en", waiting until "load"%0A%0A%0A 7 | test(`${locale} has no horizontal overflow at ${width}px`, async ({ page }) => {%0A 8 | await page.setViewportSize({ width, height: 900 });%0A > 9 | await page.goto(`/${locale}`);%0A | ^%0A 10 | const overflow = await page.evaluate(%0A 11 | () => document.documentElement.scrollWidth - document.documentElement.clientWidth,%0A 12 | );%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/responsive.spec.ts:9:18 +::error file=tests/browser/responsive.spec.ts,title=[chromium] › tests/browser/responsive.spec.ts:7:9 › en has no horizontal overflow at 320px,line=9,col=18:: 18) [chromium] › tests/browser/responsive.spec.ts:7:9 › en has no horizontal overflow at 320px ───%0A%0A Retry #1 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en", waiting until "load"%0A%0A%0A 7 | test(`${locale} has no horizontal overflow at ${width}px`, async ({ page }) => {%0A 8 | await page.setViewportSize({ width, height: 900 });%0A > 9 | await page.goto(`/${locale}`);%0A | ^%0A 10 | const overflow = await page.evaluate(%0A 11 | () => document.documentElement.scrollWidth - document.documentElement.clientWidth,%0A 12 | );%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/responsive.spec.ts:9:18 +::error file=tests/browser/responsive.spec.ts,title=[chromium] › tests/browser/responsive.spec.ts:7:9 › en has no horizontal overflow at 320px,line=9,col=18:: 18) [chromium] › tests/browser/responsive.spec.ts:7:9 › en has no horizontal overflow at 320px ───%0A%0A Retry #2 ───────────────────────────────────────────────────────────────────────────────────────%0A Error: page.goto: net::ERR_BLOCKED_BY_ADMINISTRATOR at http://127.0.0.1:3000/en%0A Call log:%0A - navigating to "http://127.0.0.1:3000/en", waiting until "load"%0A%0A%0A 7 | test(`${locale} has no horizontal overflow at ${width}px`, async ({ page }) => {%0A 8 | await page.setViewportSize({ width, height: 900 });%0A > 9 | await page.goto(`/${locale}`);%0A | ^%0A 10 | const overflow = await page.evaluate(%0A 11 | () => document.documentElement.scrollWidth - document.documentElement.clientWidth,%0A 12 | );%0A at /mnt/data/phase12_work/RentalDriveGo/tests/browser/responsive.spec.ts:9:18 +×××× \ No newline at end of file diff --git a/docs/quality/logs/playwright-test-inventory.log b/docs/quality/logs/playwright-test-inventory.log new file mode 100644 index 0000000..8b27a78 --- /dev/null +++ b/docs/quality/logs/playwright-test-inventory.log @@ -0,0 +1,47 @@ +Listing tests: + [chromium] › a11y/component-system.a11y.spec.ts:5:7 › en component fixture has no detectable accessibility violations + [chromium] › a11y/component-system.a11y.spec.ts:5:7 › fr component fixture has no detectable accessibility violations + [chromium] › a11y/component-system.a11y.spec.ts:5:7 › ar component fixture has no detectable accessibility violations + [chromium] › a11y/shell.a11y.spec.ts:6:9 › en light shell has no detectable WCAG A/AA violations + [chromium] › a11y/shell.a11y.spec.ts:6:9 › en dark shell has no detectable WCAG A/AA violations + [chromium] › a11y/shell.a11y.spec.ts:6:9 › fr light shell has no detectable WCAG A/AA violations + [chromium] › a11y/shell.a11y.spec.ts:6:9 › fr dark shell has no detectable WCAG A/AA violations + [chromium] › a11y/shell.a11y.spec.ts:6:9 › ar light shell has no detectable WCAG A/AA violations + [chromium] › a11y/shell.a11y.spec.ts:6:9 › ar dark shell has no detectable WCAG A/AA violations + [chromium] › browser/component-system.spec.ts:4:7 › en component fixture renders without horizontal overflow + [chromium] › browser/component-system.spec.ts:4:7 › fr component fixture renders without horizontal overflow + [chromium] › browser/component-system.spec.ts:4:7 › ar component fixture renders without horizontal overflow + [chromium] › browser/component-system.spec.ts:15:5 › component controls support keyboard interaction and dialog focus return + [chromium] › browser/component-system.spec.ts:35:5 › component fixture reflows at narrow mobile and 200 percent zoom equivalent + [chromium] › browser/navigation.spec.ts:5:5 › mobile navigation opens modally, closes with Escape, and returns focus + [chromium] › browser/navigation.spec.ts:21:5 › skip navigation moves focus to the main landmark + [chromium] › browser/no-javascript.spec.ts:3:5 › server shell remains readable with JavaScript disabled + [chromium] › browser/responsive.spec.ts:7:9 › en has no horizontal overflow at 320px + [chromium] › browser/responsive.spec.ts:7:9 › en has no horizontal overflow at 390px + [chromium] › browser/responsive.spec.ts:7:9 › en has no horizontal overflow at 768px + [chromium] › browser/responsive.spec.ts:7:9 › en has no horizontal overflow at 1024px + [chromium] › browser/responsive.spec.ts:7:9 › en has no horizontal overflow at 1440px + [chromium] › browser/responsive.spec.ts:7:9 › fr has no horizontal overflow at 320px + [chromium] › browser/responsive.spec.ts:7:9 › fr has no horizontal overflow at 390px + [chromium] › browser/responsive.spec.ts:7:9 › fr has no horizontal overflow at 768px + [chromium] › browser/responsive.spec.ts:7:9 › fr has no horizontal overflow at 1024px + [chromium] › browser/responsive.spec.ts:7:9 › fr has no horizontal overflow at 1440px + [chromium] › browser/responsive.spec.ts:7:9 › ar has no horizontal overflow at 320px + [chromium] › browser/responsive.spec.ts:7:9 › ar has no horizontal overflow at 390px + [chromium] › browser/responsive.spec.ts:7:9 › ar has no horizontal overflow at 768px + [chromium] › browser/responsive.spec.ts:7:9 › ar has no horizontal overflow at 1024px + [chromium] › browser/responsive.spec.ts:7:9 › ar has no horizontal overflow at 1440px + [chromium] › browser/responsive.spec.ts:18:5 › shell remains operable at a 320 CSS pixel reflow equivalent to 200 percent zoom + [chromium] › browser/shell.spec.ts:8:7 › en shell is server rendered + [chromium] › browser/shell.spec.ts:8:7 › fr shell is server rendered + [chromium] › browser/shell.spec.ts:8:7 › ar shell is server rendered + [chromium] › browser/shell.spec.ts:38:5 › root locale detection honors Accept-Language + [chromium] › browser/shell.spec.ts:48:5 › locale switching keeps the semantic route and approved campaign state + [chromium] › browser/shell.spec.ts:54:5 › pending route shells are localized and noindex + [chromium] › browser/text-expansion.spec.ts:4:7 › fr shell tolerates long content expansion + [chromium] › browser/text-expansion.spec.ts:4:7 › ar shell tolerates long content expansion + [chromium] › browser/theme-csp.spec.ts:3:5 › explicit dark theme is present on the server-rendered root + [chromium] › browser/theme-csp.spec.ts:27:5 › system preference resolves before interaction + [chromium] › browser/theme-csp.spec.ts:36:5 › system follows operating-system changes while explicit preferences ignore them +Total: 44 tests in 9 files +::notice title=🎭 Playwright Run Summary:: 44 did not run diff --git a/docs/quality/logs/pnpm-audit.log b/docs/quality/logs/pnpm-audit.log new file mode 100644 index 0000000..d8f28d5 --- /dev/null +++ b/docs/quality/logs/pnpm-audit.log @@ -0,0 +1,3 @@ +[WARN] Unsupported engine: wanted: {"node":"24.17.0"} (current: {"node":"v22.16.0","pnpm":"11.9.0"}) +[WARN] POST https://registry.npmjs.org/-/npm/v1/security/advisories/bulk error (EAI_AGAIN). Will retry in 10 seconds. 2 retries left. +[WARN] POST https://registry.npmjs.org/-/npm/v1/security/advisories/bulk error (EAI_AGAIN). Will retry in 1 minute. 1 retries left. diff --git a/docs/quality/logs/pnpm-install-frozen.log b/docs/quality/logs/pnpm-install-frozen.log new file mode 100644 index 0000000..f38bbdd --- /dev/null +++ b/docs/quality/logs/pnpm-install-frozen.log @@ -0,0 +1,30 @@ +[WARN] Unsupported engine: wanted: {"node":"24.17.0"} (current: {"node":"v22.16.0","pnpm":"11.9.0"}) +? Verifying lockfile against supply-chain policies (533 entries)... +Lockfile is up to date, resolution step is skipped +[WARN] GET https://registry.npmjs.org/@adobe%2Fcss-tools error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@asamuzakjp%2Fcss-color error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@asamuzakjp%2Fdom-selector error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +Progress: resolved 1, reused 0, downloaded 0, added 0 +Packages: +449 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Progress: resolved 449, reused 0, downloaded 0, added 0 +[WARN] GET https://registry.npmjs.org/@asamuzakjp%2Fgenerational-cache error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@axe-core%2Fplaywright error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@asamuzakjp%2Fnwsapi error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Fcode-frame error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Fcompat-data error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Fgenerator error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Fcore error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Fhelper-globals error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Fhelper-compilation-targets error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Fhelper-module-imports error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Fhelper-module-transforms error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Fhelper-string-parser error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Fhelper-validator-identifier error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Fhelper-validator-option error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Fhelpers error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Fparser error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Fruntime error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Ftemplate error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Ftraverse error (EAI_AGAIN). Will retry in 1 second. 4 retries left. +[WARN] GET https://registry.npmjs.org/@babel%2Ftypes error (EAI_AGAIN). Will retry in 1 second. 4 retries left. diff --git a/docs/quality/logs/standalone-server.log b/docs/quality/logs/standalone-server.log new file mode 100644 index 0000000..f084adf --- /dev/null +++ b/docs/quality/logs/standalone-server.log @@ -0,0 +1,4 @@ +▲ Next.js 16.2.9 +- Local: http://127.0.0.1:3100 +- Network: http://127.0.0.1:3100 +✓ Ready in 0ms diff --git a/docs/quality/logs/typecheck.exit b/docs/quality/logs/typecheck.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/quality/logs/typecheck.exit @@ -0,0 +1 @@ +0 diff --git a/docs/quality/logs/typecheck.log b/docs/quality/logs/typecheck.log new file mode 100644 index 0000000..3a797b1 --- /dev/null +++ b/docs/quality/logs/typecheck.log @@ -0,0 +1,4 @@ + +> rentaldrivego-web@0.3.0 typecheck +> tsc --noEmit + diff --git a/docs/quality/logs/unit.exit b/docs/quality/logs/unit.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/quality/logs/unit.exit @@ -0,0 +1 @@ +0 diff --git a/docs/quality/logs/unit.log b/docs/quality/logs/unit.log new file mode 100644 index 0000000..608d84e --- /dev/null +++ b/docs/quality/logs/unit.log @@ -0,0 +1,34 @@ + +> rentaldrivego-web@0.3.0 test:unit +> vitest run --coverage + + + RUN  v4.1.9 /mnt/data/phase12_work/RentalDriveGo + Coverage enabled with v8 + + ✓ tests/unit/theme.test.ts (2 tests) 4ms + ✓ tests/unit/csp.test.ts (2 tests) 6ms + ✓ tests/unit/format.test.ts (3 tests) 79ms + ✓ tests/unit/localization.test.ts (5 tests) 9ms + ✓ tests/unit/components/actions.test.tsx (3 tests) 234ms + ✓ tests/unit/components/evidence.test.tsx (3 tests) 217ms + ✓ tests/unit/components/forms.test.tsx (2 tests) 224ms + ✓ tests/unit/components/controls.test.tsx (2 tests) 297ms + + Test Files  8 passed (8) + Tests  22 passed (22) + Start at  22:37:18 + Duration  9.12s (transform 2.44s, setup 7.11s, import 3.02s, tests 1.07s, environment 48.19s) + + % Coverage report from v8 +--------------|---------|----------|---------|---------|------------------- +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s +--------------|---------|----------|---------|---------|------------------- +All files | 92.4 | 86.04 | 95.45 | 92.64 | + localization | 90.9 | 82.75 | 94.11 | 91.07 | + config.ts | 90.9 | 82.75 | 94.11 | 91.07 | 58,67,89,112,127 + security | 100 | 100 | 100 | 100 | + csp.ts | 100 | 100 | 100 | 100 | + theme | 100 | 87.5 | 100 | 100 | + config.ts | 100 | 87.5 | 100 | 100 | 18 +--------------|---------|----------|---------|---------|------------------- diff --git a/docs/quality/logs/validate.exit b/docs/quality/logs/validate.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/docs/quality/logs/validate.exit @@ -0,0 +1 @@ +0 diff --git a/docs/quality/logs/validate.log b/docs/quality/logs/validate.log new file mode 100644 index 0000000..5f447b2 --- /dev/null +++ b/docs/quality/logs/validate.log @@ -0,0 +1,14 @@ + +> rentaldrivego-web@0.3.0 validate +> node scripts/run-validations.mjs + +PASS: Phase 9 contract package is immutable and 61 payload checksums match. +PASS: Pinned Node 24.17.0, pnpm 11.9.0, and 25 exact direct dependency versions match the lockfile. +PASS: English, French, and Arabic catalogs have exact key parity and valid direction metadata. +PASS: 5 route IDs have complete locale, runtime, hash, query, and hreflang contracts. +PASS: Phase 9 semantic tokens are unchanged and application styles contain no raw palette colors. +PASS: Phase 11 component tokens, theme fallback, and application-shell foundations are present. +PASS: 46 CSS files use direction-safe logical declarations. +PASS: Runtime source contains no placeholder destination, simulated submission, or research-only backdoor. +PASS: Localized canonical, hreflang, Open Graph, social, and robots foundations are present. +PASS: 60 inventory entries and 93 component source files satisfy Phase 12 static controls. diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..da90fbc --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,40 @@ +import { defineConfig, globalIgnores } from 'eslint/config'; +import nextVitals from 'eslint-config-next/core-web-vitals'; +import nextTypeScript from 'eslint-config-next/typescript'; +import prettier from 'eslint-config-prettier'; + +export default defineConfig([ + ...nextVitals, + ...nextTypeScript, + prettier, + { + rules: { + 'no-console': ['error', { allow: ['log', 'warn', 'error'] }], + }, + }, + { + files: ['**/*.{ts,tsx}'], + languageOptions: { + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + rules: { + '@typescript-eslint/consistent-type-imports': [ + 'error', + { prefer: 'type-imports', fixStyle: 'inline-type-imports' }, + ], + '@typescript-eslint/no-floating-promises': 'error', + '@typescript-eslint/switch-exhaustiveness-check': 'error', + }, + }, + globalIgnores([ + '.next/**', + 'coverage/**', + 'playwright-report/**', + 'test-results/**', + 'contracts/**', + 'next-env.d.ts', + ]), +]); diff --git a/next-env.d.ts b/next-env.d.ts new file mode 100644 index 0000000..9edff1c --- /dev/null +++ b/next-env.d.ts @@ -0,0 +1,6 @@ +/// +/// +import "./.next/types/routes.d.ts"; + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/next.config.ts b/next.config.ts new file mode 100644 index 0000000..66b79a2 --- /dev/null +++ b/next.config.ts @@ -0,0 +1,10 @@ +import type { NextConfig } from 'next'; + +const nextConfig: NextConfig = { + compress: true, + output: 'standalone', + poweredByHeader: false, + reactStrictMode: true, +}; + +export default nextConfig; diff --git a/package.json b/package.json new file mode 100644 index 0000000..5deb9e8 --- /dev/null +++ b/package.json @@ -0,0 +1,72 @@ +{ + "name": "rentaldrivego-web", + "version": "0.4.0", + "private": true, + "description": "Phase 13 multilingual homepage assembly for the RentalDriveGo marketing website.", + "license": "UNLICENSED", + "packageManager": "pnpm@11.9.0", + "engines": { + "node": "24.17.0", + "pnpm": "11.9.0" + }, + "scripts": { + "dev": "next dev", + "build": "next build && node scripts/prepare-standalone.mjs", + "start": "node .next/standalone/server.js", + "lint": "eslint . --max-warnings=0", + "format": "prettier --write .", + "format:check": "prettier --check .", + "typecheck": "tsc --noEmit", + "test:unit": "vitest run --coverage", + "test:unit:watch": "vitest", + "test:browser": "playwright test tests/browser", + "test:a11y": "playwright test tests/a11y", + "test:visual": "playwright test tests/visual", + "test:e2e": "playwright test", + "test:visual:update": "playwright test tests/visual --update-snapshots", + "validate:contracts": "node scripts/validate-phase9-contract.mjs", + "validate:locales": "node scripts/validate-locales.mjs", + "validate:routes": "node scripts/validate-routes.mjs", + "validate:tokens": "node scripts/validate-tokens.mjs", + "validate:css": "node scripts/validate-css-logical.mjs", + "validate:claims": "node scripts/validate-prohibited-content.mjs", + "validate": "node scripts/run-validations.mjs", + "audit": "pnpm audit --audit-level low", + "check": "node scripts/run-checks.mjs", + "manifest:generate": "node scripts/generate-phase13-manifest.mjs", + "validate:package": "node scripts/validate-phase13-manifest.mjs", + "validate:foundation": "node scripts/validate-phase11-foundation.mjs", + "validate:metadata": "node scripts/validate-metadata.mjs", + "validate:components": "node scripts/validate-phase12-components.mjs", + "validate:homepage": "node scripts/validate-phase13-homepage.mjs" + }, + "dependencies": { + "@fontsource-variable/inter": "5.2.8", + "@fontsource-variable/noto-sans-arabic": "5.2.10", + "next": "16.2.9", + "react": "19.2.7", + "react-dom": "19.2.7", + "zod": "4.4.3" + }, + "devDependencies": { + "@axe-core/playwright": "4.12.1", + "@eslint/js": "9.39.4", + "@playwright/test": "1.61.1", + "@testing-library/jest-dom": "6.9.1", + "@testing-library/react": "16.3.2", + "@testing-library/user-event": "14.6.1", + "@types/node": "24.10.9", + "@types/react": "19.2.17", + "@types/react-dom": "19.2.3", + "@vitest/coverage-v8": "4.1.9", + "eslint": "9.39.4", + "eslint-config-next": "16.2.9", + "eslint-config-prettier": "10.1.8", + "globals": "17.7.0", + "jsdom": "29.1.1", + "prettier": "3.8.4", + "typescript": "6.0.3", + "typescript-eslint": "8.62.0", + "vitest": "4.1.9" + } +} diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..d64f462 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,57 @@ +import { defineConfig, devices } from '@playwright/test'; + +const baseURL = process.env.PLAYWRIGHT_BASE_URL ?? 'http://127.0.0.1:3000'; +const executablePath = process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH; +const serverCommand = process.env.PLAYWRIGHT_SERVER_COMMAND ?? 'pnpm start'; + +export default defineConfig({ + testDir: './tests', + fullyParallel: true, + forbidOnly: Boolean(process.env.CI), + retries: process.env.CI ? 2 : 0, + ...(process.env.CI ? { workers: 2 } : {}), + reporter: process.env.CI ? [['html', { open: 'never' }], ['github']] : 'list', + expect: { + timeout: 5_000, + toHaveScreenshot: { + animations: 'disabled', + caret: 'hide', + maxDiffPixelRatio: 0.005, + }, + }, + use: { + baseURL, + locale: 'en-US', + timezoneId: 'UTC', + trace: 'retain-on-failure', + screenshot: 'only-on-failure', + video: + process.env.PLAYWRIGHT_VIDEO === 'off' ? 'off' : process.env.CI ? 'retain-on-failure' : 'off', + }, + projects: [ + { + name: 'chromium', + use: { + ...devices['Desktop Chrome'], + ...(executablePath ? { launchOptions: { executablePath } } : {}), + }, + }, + { name: 'firefox', use: { ...devices['Desktop Firefox'] } }, + { name: 'webkit', use: { ...devices['Desktop Safari'] } }, + { name: 'mobile-chrome', use: { ...devices['Pixel 7'] } }, + { name: 'mobile-safari', use: { ...devices['iPhone 15'] } }, + ], + webServer: { + command: serverCommand, + url: baseURL, + reuseExistingServer: !process.env.CI, + timeout: 120_000, + env: { + SITE_ORIGIN: baseURL, + PUBLIC_RELEASE_APPROVED: 'false', + COMPONENT_FIXTURES_ENABLED: 'true', + HOSTNAME: '127.0.0.1', + PORT: '3000', + }, + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..3ad35f4 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,5135 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + postcss: 8.5.15 + +importers: + + .: + dependencies: + '@fontsource-variable/inter': + specifier: 5.2.8 + version: 5.2.8 + '@fontsource-variable/noto-sans-arabic': + specifier: 5.2.10 + version: 5.2.10 + next: + specifier: 16.2.9 + version: 16.2.9(@babel/core@7.29.7)(@playwright/test@1.61.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: + specifier: 19.2.7 + version: 19.2.7 + react-dom: + specifier: 19.2.7 + version: 19.2.7(react@19.2.7) + zod: + specifier: 4.4.3 + version: 4.4.3 + devDependencies: + '@axe-core/playwright': + specifier: 4.12.1 + version: 4.12.1(playwright-core@1.61.1) + '@eslint/js': + specifier: 9.39.4 + version: 9.39.4 + '@playwright/test': + specifier: 1.61.1 + version: 1.61.1 + '@testing-library/jest-dom': + specifier: 6.9.1 + version: 6.9.1 + '@testing-library/react': + specifier: 16.3.2 + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + '@testing-library/user-event': + specifier: 14.6.1 + version: 14.6.1(@testing-library/dom@10.4.1) + '@types/node': + specifier: 24.10.9 + version: 24.10.9 + '@types/react': + specifier: 19.2.17 + version: 19.2.17 + '@types/react-dom': + specifier: 19.2.3 + version: 19.2.3(@types/react@19.2.17) + '@vitest/coverage-v8': + specifier: 4.1.9 + version: 4.1.9(vitest@4.1.9) + eslint: + specifier: 9.39.4 + version: 9.39.4 + eslint-config-next: + specifier: 16.2.9 + version: 16.2.9(@typescript-eslint/parser@8.62.0(eslint@9.39.4)(typescript@6.0.3))(eslint@9.39.4)(typescript@6.0.3) + eslint-config-prettier: + specifier: 10.1.8 + version: 10.1.8(eslint@9.39.4) + globals: + specifier: 17.7.0 + version: 17.7.0 + jsdom: + specifier: 29.1.1 + version: 29.1.1 + prettier: + specifier: 3.8.4 + version: 3.8.4 + typescript: + specifier: 6.0.3 + version: 6.0.3 + typescript-eslint: + specifier: 8.62.0 + version: 8.62.0(eslint@9.39.4)(typescript@6.0.3) + vitest: + specifier: 4.1.9 + version: 4.1.9(@types/node@24.10.9)(@vitest/coverage-v8@4.1.9)(jsdom@29.1.1)(vite@8.1.0(@types/node@24.10.9)) + +packages: + + '@adobe/css-tools@4.5.0': + resolution: {integrity: sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==} + + '@asamuzakjp/css-color@5.1.11': + resolution: {integrity: sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + '@asamuzakjp/dom-selector@7.1.1': + resolution: {integrity: sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + '@asamuzakjp/generational-cache@1.0.1': + resolution: {integrity: sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + '@asamuzakjp/nwsapi@2.3.9': + resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + + '@axe-core/playwright@4.12.1': + resolution: {integrity: sha512-rMd7xriptqKpP+w5265i4Hdkv2X5kbu6uiBi/B2I7uf3hieRBM3qDCfaKPtxfiYb2mKXfF+yLODJwIx+Jv1GDw==} + peerDependencies: + playwright-core: '>= 1.0.0' + + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.7': + resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.7': + resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.7': + resolution: {integrity: sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.29.7': + resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.29.7': + resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.29.7': + resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.29.7': + resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.29.7': + resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.7': + resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.7': + resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/runtime@7.29.7': + resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.29.7': + resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.7': + resolution: {integrity: sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.7': + resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + + '@bramus/specificity@2.4.2': + resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==} + hasBin: true + + '@csstools/color-helpers@6.0.2': + resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==} + engines: {node: '>=20.19.0'} + + '@csstools/css-calc@3.2.1': + resolution: {integrity: sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-parser-algorithms': ^4.0.0 + '@csstools/css-tokenizer': ^4.0.0 + + '@csstools/css-color-parser@4.1.8': + resolution: {integrity: sha512-3chWb7PRLijpJpPIKkDxdu6IBeO5MrFACND57On0j8OPpc0wZibcGc3xAHrSEbOx/KDRyMHoIxGn0w1PhXMYHw==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-parser-algorithms': ^4.0.0 + '@csstools/css-tokenizer': ^4.0.0 + + '@csstools/css-parser-algorithms@4.0.0': + resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-tokenizer': ^4.0.0 + + '@csstools/css-syntax-patches-for-csstree@1.1.5': + resolution: {integrity: sha512-oNjBvzLq2GPZtJphCjLqXow/cHySHSgtxvKZb7OqSZ/xHgw6NWNhfad+6AB9cLeVm6eA9d/qMll3JdEHjy6M+A==} + peerDependencies: + css-tree: ^3.2.1 + peerDependenciesMeta: + css-tree: + optional: true + + '@csstools/css-tokenizer@4.0.0': + resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} + engines: {node: '>=20.19.0'} + + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + + '@emnapi/core@1.11.1': + resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} + + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@exodus/bytes@1.15.1': + resolution: {integrity: sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@noble/hashes': ^1.8.0 || ^2.0.0 + peerDependenciesMeta: + '@noble/hashes': + optional: true + + '@fontsource-variable/inter@5.2.8': + resolution: {integrity: sha512-kOfP2D+ykbcX/P3IFnokOhVRNoTozo5/JxhAIVYLpea/UBmCQ/YWPBfWIDuBImXX/15KH+eKh4xpEUyS2sQQGQ==} + + '@fontsource-variable/noto-sans-arabic@5.2.10': + resolution: {integrity: sha512-6vP9gU5yQQE/4ClrVoS92rjwc3qUnSkoxaw/Hkrha1Nqn9UEwuh3WVxT2+DMlMdV49uxvxUKVauSd2nwLu/WBA==} + + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@napi-rs/wasm-runtime@1.1.6': + resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + + '@next/env@16.2.9': + resolution: {integrity: sha512-ki5VxxXfzD/9TDe13wyeTKIjQTAwBVpnr8KhRDUr8ltMUq1/NBpWNT5tiPoxiGl+PHM4X2ahSOiPk6iAimIzPg==} + + '@next/eslint-plugin-next@16.2.9': + resolution: {integrity: sha512-UZi8+YT/MLgTC9nrrn2Xd4lBYv1B7lVmtWHfPcthAI5Tt/C1LuDe6DfmtCtJ+WQod3ksY4VrKSvk3oMVAnL7qw==} + + '@next/swc-darwin-arm64@16.2.9': + resolution: {integrity: sha512-HkfxNYUCmcct0Xsqib5KxqMSHV4AHJq857BNRchyBDs4YS19aHzVfn1kDuBYKqLLQBjXgnkIsjV2Kd4d2wzYhw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@16.2.9': + resolution: {integrity: sha512-7IAtK4MeybpqRV9GRABWEhJ62mOS+rzWOzOTFie4cSEtm12xsoOMJRcECoZx3FHPzFAqN/IJtHqWAFOLfl152w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@16.2.9': + resolution: {integrity: sha512-hBD75iWpUtkL9SmQmcRhmLomn9jgkPzCEkbOcLgHymPEKzv+6ONy13RRiIEz/iEObjkS2Jlb5gYS2XGoS3X4rw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@16.2.9': + resolution: {integrity: sha512-qZTI3pf9SGc/obr8NkQAekBxmp1QK+kVm+VAf3BALLfFAj+1kUhkTxmrWpVos9R/UYIA8AWX2p6cGI5WdwzVUA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@next/swc-linux-x64-gnu@16.2.9': + resolution: {integrity: sha512-xm0HfRNX+UkH4R3c18ynswjj5o5uEj/7iI9p9omdtTSIsRCzQqkGMA+10nzJ4EHnYC3as65IMhbbl5fWRUWHYg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@next/swc-linux-x64-musl@16.2.9': + resolution: {integrity: sha512-QumimHkGEG6vM3PfEDWKyKen03NcqLOkeKB1EfcPe7VxzmEiCa4jNnMyBn/US5zcd/VE1CI+O8Ovb3lfjVHfGw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@next/swc-win32-arm64-msvc@16.2.9': + resolution: {integrity: sha512-hzQpKZvw8rAwI6A2uQh6SacCSvNAXaIkPNsWwzqqfRiIMiXMfH936skDhz1OO6KpvdKkJrgHHtqQOq5PIXOvdQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@16.2.9': + resolution: {integrity: sha512-qr2VL3Ce5QrwgO2yh1ujSBawrimjVKX8FGF/cOynmdYKJY0BdHpGVNIRK1tqONB10Vkm25Ub1BD2bkjWs4+96w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@oxc-project/types@0.137.0': + resolution: {integrity: sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==} + + '@playwright/test@1.61.1': + resolution: {integrity: sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig==} + engines: {node: '>=18'} + hasBin: true + + '@rolldown/binding-android-arm64@1.1.3': + resolution: {integrity: sha512-DT6Z3PhvioeHMvxo+xHc3KtqggrI7CCTXCmC2h/5zUlp5jVitv7XEy+9q5/7v8IolhlioawpMo8Kg0EEBy7J0g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.1.3': + resolution: {integrity: sha512-0NwgwsjM7LrsuVnXMK3koTpagBNOhloc/BNjKqZjv4V5zI5r13qx69uVhRx+o5Z0yy4Hzq+lpy7TAgUG/ocvrw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.1.3': + resolution: {integrity: sha512-YtiBp4disu6V560loT6PjMdiRaWmVvDNrUunAalbiFx2ggeJwxdAsgZMcoGP17uyAsTwAj5V1niksxlHnVQ1Sw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.1.3': + resolution: {integrity: sha512-yD3EkEdXk2LypPxnf/kSZHirarsI8gcPzc62SukhR9VJTyvV+F9Q/GxWNuCojc7sXyuVC4DxRGhdDK4X8VSsbw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.1.3': + resolution: {integrity: sha512-c+8vieQbsD7HNAHKIA34w0GJ9FedFFuJGD+7E6vz7Q3uqAIugL5p45fhlsj4UaAsHpcmlqugBWMhA0/j7o0sIg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.1.3': + resolution: {integrity: sha512-50jD0uUwLvur7Zz9LHz17kaAdTPjn5wN93hEgjvmYFRZwiR7ZJYovTd5ipyWJDAnXKvZ+wgc+/Ika6dwSF5OcA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.1.3': + resolution: {integrity: sha512-BO9+oPL8K9poZJBfYPsXNtYjPE5uM3qeehT3aFcW4LITOl+iSqhp0abzjR2nWBUNjIZeKXjAEWBZ64WjNoHd6w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.1.3': + resolution: {integrity: sha512-f3VpLB1vQ0Eo6ecr/6cekLnvYMFF4YBFoVGkfkvPLq1bAkbAwHYQPZKoAmG6OJyTcxxoC+AvezGx/S1obNC0Mw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.1.3': + resolution: {integrity: sha512-AmurZ26Pqx/RI9N1gzEOCklkKXl927yjfXWUUS0O7Puh8ARM/Ob8qfrD3qnWksScdw6cSrW5PSHE9DyLu7+PtA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.1.3': + resolution: {integrity: sha512-JJpqs8bRGITDOdbkNKnlojzBabbOHrqjSvDr0IVsZObE1lBcPjxItUEY9eWIDbxaJ3cGrXPWGfGkIxFijg/URg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.1.3': + resolution: {integrity: sha512-rSJcdjPxzA/by/6/rYs+v+bXU7UjvnbUWz8MJb6kh6+knqB1dCrtHg0uu7C/4haqJvqdkYHQ5IGn+tCH9GLW/g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.1.3': + resolution: {integrity: sha512-hQ3/PYkDJICgevvyNcVrihVeqq7k1Pp3VZ9lY+dauAYUJKO+auqApvANhvR1An9BhmqYKvW2Mu1F9u4DXSMLxQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.1.3': + resolution: {integrity: sha512-Elcv/BtML9lXrV6JuKITc/grN2kYV9gjsQpW8Jfw4ioK0TOkjBjye0nnyqQNy9STNaI20lXNaQBRrD5gSgR0Yg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.1.3': + resolution: {integrity: sha512-2DrEfhluH9yhiaFApmsjsjwrSYbNcY1oFTzYSP1a535jDbV98zCFanA/96TBUd0iDFcxGmw9QRExwGCXz3U+/g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.1.3': + resolution: {integrity: sha512-OL4OMk7UPXOeVGGd3qo5zJyPIljf4AFgk5QAkPPS+OoLuOOozhuaQGC18MxVTnw/06q93gShAJzlwnSCY9YtqA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} + engines: {node: '>=18'} + + '@testing-library/jest-dom@6.9.1': + resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/react@16.3.2': + resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 || ^19.0.0 + '@types/react-dom': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/node@24.10.9': + resolution: {integrity: sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw==} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.17': + resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==} + + '@typescript-eslint/eslint-plugin@8.62.0': + resolution: {integrity: sha512-o+mpz7EYiMzXoySXiKmzlabIvTVqUuK5yLrAedRPRDA0IpPFMUV1IXt6OqljIxX/kumN6EjUYp41Hqelh6p/Dw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.62.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/parser@8.62.0': + resolution: {integrity: sha512-dzHeT2gySzZtLDsuqxU9AkYgIsQoHAHtRBpOqM+Ofzx1Bwrd2RcCjQJ+6iQbsHOIR6NS33bF2W1k3blN1zLDrA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.62.0': + resolution: {integrity: sha512-wexnCqiTg7BOGtbLDftYpRWlmLq4xfoMd7BKFR6Y75sZS3QmRKLdN3yWLhmIYgqMmP/OXWpj3H8odkb5nGURCQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.62.0': + resolution: {integrity: sha512-1lX38kNxXIRb8mEc3lbq5mdHq1Pf2+U0nFU65KfT18mtPxxl0fvjuEE92mHuXPuCtElJhOrddOpyMlM3Z0umEA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.62.0': + resolution: {integrity: sha512-y2GAdB6ykaXUvuspbYnizQc4oDDz0Tz/Yc7iWrXf9mx8vm/L/0vLHCe0tS2boG96Zy+DivnVDQ9ZUEWoHqqx1g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.62.0': + resolution: {integrity: sha512-+g5O3j0w2ldzC86Pv6fvbO/xhAonbJFIdf/MKQ1d30gndlsVzUOE83ldfSE15Qrl9fhFjK6AovHs5Wpp6vx86w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.62.0': + resolution: {integrity: sha512-KvAclkktORPvM54TgLgA4z9HIV1M8zOgw9ZVNXl9f/8dLYfXYX1wkMXP7qmabpijQRV5bHJLOmoyGQbLMaUYeg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.62.0': + resolution: {integrity: sha512-+hVbNxtW64pIcZWDPGbyaKF7vp2IBTVY5ma1blwwksrjdsbdqqEKvJWMGbBofei4F6Dovx1M0RJgoFeNu2279A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@8.62.0': + resolution: {integrity: sha512-82r66fi9zYwZ+mTq3vKgwjbZ1PVk/DJzrXFLpG6RnBbdvH8TEGVHIs9H4d2drhkOzf0syZuD/OZvvlu6GDbP4g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.62.0': + resolution: {integrity: sha512-CY3uyFSRbcQv3nnSv8S0+lDftMVz6P963PoRlxrV7ew/Md564g9ut60PYzdLM5qW4jFn93GBF+Soi90ISAN+GQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@unrs/resolver-binding-android-arm-eabi@1.12.2': + resolution: {integrity: sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.12.2': + resolution: {integrity: sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.12.2': + resolution: {integrity: sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.12.2': + resolution: {integrity: sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.12.2': + resolution: {integrity: sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2': + resolution: {integrity: sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2': + resolution: {integrity: sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.12.2': + resolution: {integrity: sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-arm64-musl@1.12.2': + resolution: {integrity: sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': + resolution: {integrity: sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-loong64-musl@1.12.2': + resolution: {integrity: sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': + resolution: {integrity: sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': + resolution: {integrity: sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': + resolution: {integrity: sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': + resolution: {integrity: sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-x64-gnu@1.12.2': + resolution: {integrity: sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-x64-musl@1.12.2': + resolution: {integrity: sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-openharmony-arm64@1.12.2': + resolution: {integrity: sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==} + cpu: [arm64] + os: [openharmony] + + '@unrs/resolver-binding-wasm32-wasi@1.12.2': + resolution: {integrity: sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': + resolution: {integrity: sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.12.2': + resolution: {integrity: sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.12.2': + resolution: {integrity: sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==} + cpu: [x64] + os: [win32] + + '@vitest/coverage-v8@4.1.9': + resolution: {integrity: sha512-G9/lgqibheLVBDRuya45EbsEXTYcWoSG+TLg7i2axuzx0Eq62eXn+aWXyaVdV5vKvFSWd6ywcX8hA7la9Pvu8g==} + peerDependencies: + '@vitest/browser': 4.1.9 + vitest: 4.1.9 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@4.1.9': + resolution: {integrity: sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==} + + '@vitest/mocker@4.1.9': + resolution: {integrity: sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.1.9': + resolution: {integrity: sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==} + + '@vitest/runner@4.1.9': + resolution: {integrity: sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==} + + '@vitest/snapshot@4.1.9': + resolution: {integrity: sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==} + + '@vitest/spy@4.1.9': + resolution: {integrity: sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==} + + '@vitest/utils@4.1.9': + resolution: {integrity: sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + ast-v8-to-istanbul@1.0.4: + resolution: {integrity: sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.12.1: + resolution: {integrity: sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==} + engines: {node: '>=4'} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + baseline-browser-mapping@2.10.38: + resolution: {integrity: sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==} + engines: {node: '>=6.0.0'} + hasBin: true + + bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + + brace-expansion@1.1.15: + resolution: {integrity: sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==} + + brace-expansion@5.0.6: + resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + engines: {node: 18 || 20 || >=22} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.4: + resolution: {integrity: sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001799: + resolution: {integrity: sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==} + + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + data-urls@7.0.0: + resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + electron-to-chromium@1.5.378: + resolution: {integrity: sha512-VinvOAuuPmdD1guEgGv5f2Qp7/vlfqOrUOMYNnOD4wj3pit8kRsQHzfIf6teyUGWo15Tg5+bOJaRunvyltpVWQ==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + entities@8.0.0: + resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} + engines: {node: '>=20.19.0'} + + es-abstract-get@1.0.0: + resolution: {integrity: sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==} + engines: {node: '>= 0.4'} + + es-abstract@1.24.2: + resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-iterator-helpers@1.3.3: + resolution: {integrity: sha512-0PuBxFi+4uPanB97iDxCLWuHeYud2FALrw5HFZGtAF38UpJDbDC8frwp2cnDyae692CQ0dou60UwWfhgsa4U/g==} + engines: {node: '>= 0.4'} + + es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} + + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.1: + resolution: {integrity: sha512-CxN9N56HYfd2m/acc/NOFrZQsN9kU4eh+2kk6A707Kz1krH8tKmfrs5RnftB8WNX80T0NS7vSQsDOlg23diR2g==} + engines: {node: '>= 0.4'} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-next@16.2.9: + resolution: {integrity: sha512-olGtBrs07bQchpaJWeqbk9GaMoU0oGmN/pYNEBXSbfgKngb5uHnPe37X6tVeh6DJfaWFQildvinGEOrolo5fmw==} + peerDependencies: + eslint: '>=9.0.0' + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-node@0.3.10: + resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==} + + eslint-import-resolver-typescript@3.10.1: + resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.13.0: + resolution: {integrity: sha512-bLohSkT6469rRs8czj0tLTD8vaeIS/whvPRJVjDr7IuoTT1k5DYDERlNycjDj/HkOlvQdYurmfZ/g3fG5bgeLQ==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-plugin-react-hooks@7.1.1: + resolution: {integrity: sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==} + engines: {node: '>=18'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0 + + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.2.0: + resolution: {integrity: sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.14.0: + resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.4.0: + resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} + engines: {node: '>=18'} + + globals@17.7.0: + resolution: {integrity: sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + + hermes-estree@0.25.1: + resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} + + hermes-parser@0.25.1: + resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + + html-encoding-sniffer@6.0.0: + resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.2: + resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-document.all@1.0.0: + resolution: {integrity: sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.2.0: + resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} + hasBin: true + + jsdom@29.1.1: + resolution: {integrity: sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0} + peerDependencies: + canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@11.5.1: + resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} + engines: {node: 20 || >=22} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magicast@0.5.3: + resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.15: + resolution: {integrity: sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + next@16.2.9: + resolution: {integrity: sha512-MEOJiq/UvuezAdqVSceHbqDgZt1kDw2tpGVOlsdIoJsQdbN2JY2hpVG4xnXGkbdJUOEWhnRfiu/O4Hpc9Juwww==} + engines: {node: '>=20.9.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + node-exports-info@1.6.2: + resolution: {integrity: sha512-kXs9Go0cah0qHVV2v389IXQLdLCeE1xfFtjOAF+iobu0OIoG1pje8At2vMHyaPMiPMnG/LWP50twML21eMcAag==} + engines: {node: '>= 0.4'} + + node-releases@2.0.49: + resolution: {integrity: sha512-f06bl1D+8ZDkn2oOQQKAh5/otFWqVnM1Q5oerA8Pex7UfT66Tx4IPHIqVVFKqFT3FUtaDstdgkM7yT7JWhqxfw==} + engines: {node: '>=18'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + obug@2.1.3: + resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} + engines: {node: '>=12.20.0'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse5@8.0.1: + resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + playwright-core@1.61.1: + resolution: {integrity: sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.61.1: + resolution: {integrity: sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==} + engines: {node: '>=18'} + hasBin: true + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss@8.5.15: + resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@3.8.4: + resolution: {integrity: sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react-dom@19.2.7: + resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==} + peerDependencies: + react: ^19.2.7 + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + react@19.2.7: + resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==} + engines: {node: '>=0.10.0'} + + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@2.0.0-next.7: + resolution: {integrity: sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rolldown@1.1.3: + resolution: {integrity: sha512-1F1eEtUBtFvcGm1HQ9TiUIUHPQG7mSAODrhIzjxoUEFuo8OcbrGLiVLkevNgj84TE4lnHvnumwFjhJO5Eu135g==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.4: + resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==} + engines: {node: '>=0.4'} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stable-hash@0.0.5: + resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@4.1.0: + resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.11: + resolution: {integrity: sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.10: + resolution: {integrity: sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@1.2.4: + resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} + engines: {node: '>=18'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} + engines: {node: '>=14.0.0'} + + tldts-core@7.4.4: + resolution: {integrity: sha512-vwVLJVvvpslm7vqAH7+XNj/neA/Ynq7DT2EEcMuwc5YzN5XaMyRAqxwU+uX3azZ1FQtB2gvrvnLnAEkvYlVdfg==} + + tldts@7.4.4: + resolution: {integrity: sha512-kFXFK7O4WPextIUAOk8qtnw9dxR9UIXP9CjuH1cTBVBZMDeQcUPgr/IazGiw1B0Yiw5L75gHLWeW4iD793r90g==} + hasBin: true + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tough-cookie@6.0.1: + resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} + engines: {node: '>=16'} + + tr46@6.0.0: + resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} + engines: {node: '>=20'} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.8: + resolution: {integrity: sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==} + engines: {node: '>= 0.4'} + + typescript-eslint@8.62.0: + resolution: {integrity: sha512-8QxXi+ZACKX0kaqO4gY8kn0RSD9gFfaHDWwjqtEN48aWCBkX4MJaufWN+c3BzlrXLOxfywDL8CaoqUwcRq4j4Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + undici@7.28.0: + resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==} + engines: {node: '>=20.18.1'} + + unrs-resolver@1.12.2: + resolution: {integrity: sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + vite@8.1.0: + resolution: {integrity: sha512-BuJcQK/56NQTWDGn4ABea3q4SSBdNPWwNZKTkkUpcMPnLoquSYH8llRtSUIgoL1KSCpHt5eghLShn50mH36y7Q==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.3.0 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@4.1.9: + resolution: {integrity: sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.1.9 + '@vitest/browser-preview': 4.1.9 + '@vitest/browser-webdriverio': 4.1.9 + '@vitest/coverage-istanbul': 4.1.9 + '@vitest/coverage-v8': 4.1.9 + '@vitest/ui': 4.1.9 + happy-dom: '*' + jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + + webidl-conversions@8.0.1: + resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} + engines: {node: '>=20'} + + whatwg-mimetype@5.0.0: + resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} + engines: {node: '>=20'} + + whatwg-url@16.0.1: + resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.22: + resolution: {integrity: sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zod-validation-error@4.0.2: + resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + +snapshots: + + '@adobe/css-tools@4.5.0': {} + + '@asamuzakjp/css-color@5.1.11': + dependencies: + '@asamuzakjp/generational-cache': 1.0.1 + '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.8(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + + '@asamuzakjp/dom-selector@7.1.1': + dependencies: + '@asamuzakjp/generational-cache': 1.0.1 + '@asamuzakjp/nwsapi': 2.3.9 + bidi-js: 1.0.3 + css-tree: 3.2.1 + is-potential-custom-element-name: 1.0.1 + + '@asamuzakjp/generational-cache@1.0.1': {} + + '@asamuzakjp/nwsapi@2.3.9': {} + + '@axe-core/playwright@4.12.1(playwright-core@1.61.1)': + dependencies: + axe-core: 4.12.1 + playwright-core: 1.61.1 + + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.7': {} + + '@babel/core@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.7 + '@babel/helper-compilation-targets': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) + '@babel/helpers': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/template': 7.29.7 + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.7': + dependencies: + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.29.7': + dependencies: + '@babel/compat-data': 7.29.7 + '@babel/helper-validator-option': 7.29.7 + browserslist: 4.28.4 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.29.7': {} + + '@babel/helper-module-imports@7.29.7': + dependencies: + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-module-imports': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + '@babel/traverse': 7.29.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.29.7': {} + + '@babel/helper-validator-identifier@7.29.7': {} + + '@babel/helper-validator-option@7.29.7': {} + + '@babel/helpers@7.29.7': + dependencies: + '@babel/template': 7.29.7 + '@babel/types': 7.29.7 + + '@babel/parser@7.29.7': + dependencies: + '@babel/types': 7.29.7 + + '@babel/runtime@7.29.7': {} + + '@babel/template@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + + '@babel/traverse@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.7 + '@babel/helper-globals': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/template': 7.29.7 + '@babel/types': 7.29.7 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.7': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + + '@bcoe/v8-coverage@1.0.2': {} + + '@bramus/specificity@2.4.2': + dependencies: + css-tree: 3.2.1 + + '@csstools/color-helpers@6.0.2': {} + + '@csstools/css-calc@3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + + '@csstools/css-color-parser@4.1.8(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/color-helpers': 6.0.2 + '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + + '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/css-tokenizer': 4.0.0 + + '@csstools/css-syntax-patches-for-csstree@1.1.5(css-tree@3.2.1)': + optionalDependencies: + css-tree: 3.2.1 + + '@csstools/css-tokenizer@4.0.0': {} + + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/core@1.11.1': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)': + dependencies: + eslint: 9.39.4 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.2': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.5': + dependencies: + ajv: 6.15.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.2.0 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.4': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@exodus/bytes@1.15.1': {} + + '@fontsource-variable/inter@5.2.8': {} + + '@fontsource-variable/noto-sans-arabic@5.2.10': {} + + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@img/colour@1.1.0': + optional: true + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.11.1 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.3 + optional: true + + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@tybys/wasm-util': 0.10.3 + optional: true + + '@next/env@16.2.9': {} + + '@next/eslint-plugin-next@16.2.9': + dependencies: + fast-glob: 3.3.1 + + '@next/swc-darwin-arm64@16.2.9': + optional: true + + '@next/swc-darwin-x64@16.2.9': + optional: true + + '@next/swc-linux-arm64-gnu@16.2.9': + optional: true + + '@next/swc-linux-arm64-musl@16.2.9': + optional: true + + '@next/swc-linux-x64-gnu@16.2.9': + optional: true + + '@next/swc-linux-x64-musl@16.2.9': + optional: true + + '@next/swc-win32-arm64-msvc@16.2.9': + optional: true + + '@next/swc-win32-x64-msvc@16.2.9': + optional: true + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@nolyfill/is-core-module@1.0.39': {} + + '@oxc-project/types@0.137.0': {} + + '@playwright/test@1.61.1': + dependencies: + playwright: 1.61.1 + + '@rolldown/binding-android-arm64@1.1.3': + optional: true + + '@rolldown/binding-darwin-arm64@1.1.3': + optional: true + + '@rolldown/binding-darwin-x64@1.1.3': + optional: true + + '@rolldown/binding-freebsd-x64@1.1.3': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.1.3': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.1.3': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.1.3': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.1.3': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.1.3': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.1.3': + optional: true + + '@rolldown/binding-linux-x64-musl@1.1.3': + optional: true + + '@rolldown/binding-openharmony-arm64@1.1.3': + optional: true + + '@rolldown/binding-wasm32-wasi@1.1.3': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.1.3': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.1.3': + optional: true + + '@rolldown/pluginutils@1.0.1': {} + + '@rtsao/scc@1.1.0': {} + + '@standard-schema/spec@1.1.0': {} + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@testing-library/dom@10.4.1': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/runtime': 7.29.7 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + picocolors: 1.1.1 + pretty-format: 27.5.1 + + '@testing-library/jest-dom@6.9.1': + dependencies: + '@adobe/css-tools': 4.5.0 + aria-query: 5.3.2 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + picocolors: 1.1.1 + redent: 3.0.0 + + '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@babel/runtime': 7.29.7 + '@testing-library/dom': 10.4.1 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + optionalDependencies: + '@types/react': 19.2.17 + '@types/react-dom': 19.2.3(@types/react@19.2.17) + + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': + dependencies: + '@testing-library/dom': 10.4.1 + + '@tybys/wasm-util@0.10.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/aria-query@5.0.4': {} + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} + + '@types/estree@1.0.9': {} + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/node@24.10.9': + dependencies: + undici-types: 7.16.0 + + '@types/react-dom@19.2.3(@types/react@19.2.17)': + dependencies: + '@types/react': 19.2.17 + + '@types/react@19.2.17': + dependencies: + csstype: 3.2.3 + + '@typescript-eslint/eslint-plugin@8.62.0(@typescript-eslint/parser@8.62.0(eslint@9.39.4)(typescript@6.0.3))(eslint@9.39.4)(typescript@6.0.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.62.0(eslint@9.39.4)(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.62.0 + '@typescript-eslint/type-utils': 8.62.0(eslint@9.39.4)(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.0(eslint@9.39.4)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.62.0 + eslint: 9.39.4 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.62.0(eslint@9.39.4)(typescript@6.0.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.62.0 + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/typescript-estree': 8.62.0(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.62.0 + debug: 4.4.3 + eslint: 9.39.4 + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.62.0(typescript@6.0.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.62.0(typescript@6.0.3) + '@typescript-eslint/types': 8.62.0 + debug: 4.4.3 + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.62.0': + dependencies: + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/visitor-keys': 8.62.0 + + '@typescript-eslint/tsconfig-utils@8.62.0(typescript@6.0.3)': + dependencies: + typescript: 6.0.3 + + '@typescript-eslint/type-utils@8.62.0(eslint@9.39.4)(typescript@6.0.3)': + dependencies: + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/typescript-estree': 8.62.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.0(eslint@9.39.4)(typescript@6.0.3) + debug: 4.4.3 + eslint: 9.39.4 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.62.0': {} + + '@typescript-eslint/typescript-estree@8.62.0(typescript@6.0.3)': + dependencies: + '@typescript-eslint/project-service': 8.62.0(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.62.0(typescript@6.0.3) + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/visitor-keys': 8.62.0 + debug: 4.4.3 + minimatch: 10.2.5 + semver: 7.8.5 + tinyglobby: 0.2.17 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.62.0(eslint@9.39.4)(typescript@6.0.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@typescript-eslint/scope-manager': 8.62.0 + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/typescript-estree': 8.62.0(typescript@6.0.3) + eslint: 9.39.4 + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.62.0': + dependencies: + '@typescript-eslint/types': 8.62.0 + eslint-visitor-keys: 5.0.1 + + '@unrs/resolver-binding-android-arm-eabi@1.12.2': + optional: true + + '@unrs/resolver-binding-android-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.12.2': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-loong64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-openharmony-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.12.2': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.12.2': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.12.2': + optional: true + + '@vitest/coverage-v8@4.1.9(vitest@4.1.9)': + dependencies: + '@bcoe/v8-coverage': 1.0.2 + '@vitest/utils': 4.1.9 + ast-v8-to-istanbul: 1.0.4 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.2.0 + magicast: 0.5.3 + obug: 2.1.3 + std-env: 4.1.0 + tinyrainbow: 3.1.0 + vitest: 4.1.9(@types/node@24.10.9)(@vitest/coverage-v8@4.1.9)(jsdom@29.1.1)(vite@8.1.0(@types/node@24.10.9)) + + '@vitest/expect@4.1.9': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.9 + '@vitest/utils': 4.1.9 + chai: 6.2.2 + tinyrainbow: 3.1.0 + + '@vitest/mocker@4.1.9(vite@8.1.0(@types/node@24.10.9))': + dependencies: + '@vitest/spy': 4.1.9 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.1.0(@types/node@24.10.9) + + '@vitest/pretty-format@4.1.9': + dependencies: + tinyrainbow: 3.1.0 + + '@vitest/runner@4.1.9': + dependencies: + '@vitest/utils': 4.1.9 + pathe: 2.0.3 + + '@vitest/snapshot@4.1.9': + dependencies: + '@vitest/pretty-format': 4.1.9 + '@vitest/utils': 4.1.9 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.1.9': {} + + '@vitest/utils@4.1.9': + dependencies: + '@vitest/pretty-format': 4.1.9 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 + + acorn-jsx@5.3.2(acorn@8.17.0): + dependencies: + acorn: 8.17.0 + + acorn@8.17.0: {} + + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + argparse@2.0.1: {} + + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + aria-query@5.3.2: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-includes@3.1.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.2 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + math-intrinsics: 1.1.0 + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + es-shim-unscopables: 1.1.0 + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-shim-unscopables: 1.1.0 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + assertion-error@2.0.1: {} + + ast-types-flow@0.0.8: {} + + ast-v8-to-istanbul@1.0.4: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 10.0.0 + + async-function@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + axe-core@4.12.1: {} + + axobject-query@4.1.0: {} + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + baseline-browser-mapping@2.10.38: {} + + bidi-js@1.0.3: + dependencies: + require-from-string: 2.0.2 + + brace-expansion@1.1.15: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@5.0.6: + dependencies: + balanced-match: 4.0.4 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.4: + dependencies: + baseline-browser-mapping: 2.10.38 + caniuse-lite: 1.0.30001799 + electron-to-chromium: 1.5.378 + node-releases: 2.0.49 + update-browserslist-db: 1.2.3(browserslist@4.28.4) + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.9: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001799: {} + + chai@6.2.2: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + client-only@0.0.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + convert-source-map@2.0.0: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-tree@3.2.1: + dependencies: + mdn-data: 2.27.1 + source-map-js: 1.2.1 + + css.escape@1.5.1: {} + + csstype@3.2.3: {} + + damerau-levenshtein@1.0.8: {} + + data-urls@7.0.0: + dependencies: + whatwg-mimetype: 5.0.0 + whatwg-url: 16.0.1 + transitivePeerDependencies: + - '@noble/hashes' + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decimal.js@10.6.0: {} + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + dequal@2.0.3: {} + + detect-libc@2.1.2: {} + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + dom-accessibility-api@0.5.16: {} + + dom-accessibility-api@0.6.3: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + electron-to-chromium@1.5.378: {} + + emoji-regex@9.2.2: {} + + entities@8.0.0: {} + + es-abstract-get@1.0.0: + dependencies: + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + is-callable: 1.2.7 + object-inspect: 1.13.4 + + es-abstract@1.24.2: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.1 + function.prototype.name: 1.2.0 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.4 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.11 + string.prototype.trimend: 1.0.10 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.8 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.22 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-iterator-helpers@1.3.3: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + math-intrinsics: 1.1.0 + + es-module-lexer@2.1.0: {} + + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.4 + + es-to-primitive@1.3.1: + dependencies: + es-abstract-get: 1.0.0 + es-errors: 1.3.0 + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-next@16.2.9(@typescript-eslint/parser@8.62.0(eslint@9.39.4)(typescript@6.0.3))(eslint@9.39.4)(typescript@6.0.3): + dependencies: + '@next/eslint-plugin-next': 16.2.9 + eslint: 9.39.4 + eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.62.0(eslint@9.39.4)(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4) + eslint-plugin-react: 7.37.5(eslint@9.39.4) + eslint-plugin-react-hooks: 7.1.1(eslint@9.39.4) + globals: 16.4.0 + typescript-eslint: 8.62.0(eslint@9.39.4)(typescript@6.0.3) + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + + eslint-config-prettier@10.1.8(eslint@9.39.4): + dependencies: + eslint: 9.39.4 + + eslint-import-resolver-node@0.3.10: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.2 + resolve: 2.0.0-next.7 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.3 + eslint: 9.39.4 + get-tsconfig: 4.14.0 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.17 + unrs-resolver: 1.12.2 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.62.0(eslint@9.39.4)(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.13.0(@typescript-eslint/parser@8.62.0(eslint@9.39.4)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.62.0(eslint@9.39.4)(typescript@6.0.3) + eslint: 9.39.4 + eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4) + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.62.0(eslint@9.39.4)(typescript@6.0.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.39.4 + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.62.0(eslint@9.39.4)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4) + hasown: 2.0.4 + is-core-module: 2.16.2 + is-glob: 4.0.3 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.10 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.62.0(eslint@9.39.4)(typescript@6.0.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.9 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.12.1 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 9.39.4 + hasown: 2.0.4 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + + eslint-plugin-react-hooks@7.1.1(eslint@9.39.4): + dependencies: + '@babel/core': 7.29.7 + '@babel/parser': 7.29.7 + eslint: 9.39.4 + hermes-parser: 0.25.1 + zod: 4.4.3 + zod-validation-error: 4.0.2(zod@4.4.3) + transitivePeerDependencies: + - supports-color + + eslint-plugin-react@7.37.5(eslint@9.39.4): + dependencies: + array-includes: 3.1.9 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.3.3 + eslint: 9.39.4 + estraverse: 5.3.0 + hasown: 2.0.4 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.5 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.7 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.4: + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.9 + + esutils@2.0.3: {} + + expect-type@1.3.0: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.1: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + + flatted@3.4.2: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + fsevents@2.3.2: + optional: true + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.2.0: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + es-define-property: 1.0.1 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + hasown: 2.0.4 + is-callable: 1.2.7 + is-document.all: 1.0.0 + + functions-have-names@1.2.3: {} + + generator-function@2.0.1: {} + + gensync@1.0.0-beta.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-tsconfig@4.14.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + globals@16.4.0: {} + + globals@17.7.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + gopd@1.2.0: {} + + has-bigints@1.1.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + + hermes-estree@0.25.1: {} + + hermes-parser@0.25.1: + dependencies: + hermes-estree: 0.25.1 + + html-encoding-sniffer@6.0.0: + dependencies: + '@exodus/bytes': 1.15.1 + transitivePeerDependencies: + - '@noble/hashes' + + html-escaper@2.0.2: {} + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.4 + side-channel: 1.1.1 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-bun-module@2.0.0: + dependencies: + semver: 7.8.5 + + is-callable@1.2.7: {} + + is-core-module@2.16.2: + dependencies: + hasown: 2.0.4 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-document.all@1.0.0: + dependencies: + call-bound: 1.0.4 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-potential-custom-element-name@1.0.1: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.22 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.2 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + + js-tokens@10.0.0: {} + + js-tokens@4.0.0: {} + + js-yaml@4.2.0: + dependencies: + argparse: 2.0.1 + + jsdom@29.1.1: + dependencies: + '@asamuzakjp/css-color': 5.1.11 + '@asamuzakjp/dom-selector': 7.1.1 + '@bramus/specificity': 2.4.2 + '@csstools/css-syntax-patches-for-csstree': 1.1.5(css-tree@3.2.1) + '@exodus/bytes': 1.15.1 + css-tree: 3.2.1 + data-urls: 7.0.0 + decimal.js: 10.6.0 + html-encoding-sniffer: 6.0.0 + is-potential-custom-element-name: 1.0.1 + lru-cache: 11.5.1 + parse5: 8.0.1 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 6.0.1 + undici: 7.28.0 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 8.0.1 + whatwg-mimetype: 5.0.0 + whatwg-url: 16.0.1 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - '@noble/hashes' + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.9 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lru-cache@11.5.1: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lz-string@1.5.0: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magicast@0.5.3: + dependencies: + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + source-map-js: 1.2.1 + + make-dir@4.0.0: + dependencies: + semver: 7.8.5 + + math-intrinsics@1.1.0: {} + + mdn-data@2.27.1: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + min-indent@1.0.1: {} + + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.6 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.15 + + minimist@1.2.8: {} + + ms@2.1.3: {} + + nanoid@3.3.15: {} + + napi-postinstall@0.3.4: {} + + natural-compare@1.4.0: {} + + next@16.2.9(@babel/core@7.29.7)(@playwright/test@1.61.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7): + dependencies: + '@next/env': 16.2.9 + '@swc/helpers': 0.5.15 + baseline-browser-mapping: 2.10.38 + caniuse-lite: 1.0.30001799 + postcss: 8.5.15 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + styled-jsx: 5.1.6(@babel/core@7.29.7)(react@19.2.7) + optionalDependencies: + '@next/swc-darwin-arm64': 16.2.9 + '@next/swc-darwin-x64': 16.2.9 + '@next/swc-linux-arm64-gnu': 16.2.9 + '@next/swc-linux-arm64-musl': 16.2.9 + '@next/swc-linux-x64-gnu': 16.2.9 + '@next/swc-linux-x64-musl': 16.2.9 + '@next/swc-win32-arm64-msvc': 16.2.9 + '@next/swc-win32-x64-msvc': 16.2.9 + '@playwright/test': 1.61.1 + sharp: 0.34.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + node-exports-info@1.6.2: + dependencies: + array.prototype.flatmap: 1.3.3 + es-errors: 1.3.0 + object.entries: 1.1.9 + semver: 6.3.1 + + node-releases@2.0.49: {} + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.entries@1.1.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.2 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 + + obug@2.1.3: {} + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse5@8.0.1: + dependencies: + entities: 8.0.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + picomatch@4.0.4: {} + + playwright-core@1.61.1: {} + + playwright@1.61.1: + dependencies: + playwright-core: 1.61.1 + optionalDependencies: + fsevents: 2.3.2 + + possible-typed-array-names@1.1.0: {} + + postcss@8.5.15: + dependencies: + nanoid: 3.3.15 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier@3.8.4: {} + + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + react-dom@19.2.7(react@19.2.7): + dependencies: + react: 19.2.7 + scheduler: 0.27.0 + + react-is@16.13.1: {} + + react-is@17.0.2: {} + + react@19.2.7: {} + + redent@3.0.0: + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + require-from-string@2.0.2: {} + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@2.0.0-next.7: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.2 + node-exports-info: 1.6.2 + object-keys: 1.1.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + rolldown@1.1.3: + dependencies: + '@oxc-project/types': 0.137.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.1.3 + '@rolldown/binding-darwin-arm64': 1.1.3 + '@rolldown/binding-darwin-x64': 1.1.3 + '@rolldown/binding-freebsd-x64': 1.1.3 + '@rolldown/binding-linux-arm-gnueabihf': 1.1.3 + '@rolldown/binding-linux-arm64-gnu': 1.1.3 + '@rolldown/binding-linux-arm64-musl': 1.1.3 + '@rolldown/binding-linux-ppc64-gnu': 1.1.3 + '@rolldown/binding-linux-s390x-gnu': 1.1.3 + '@rolldown/binding-linux-x64-gnu': 1.1.3 + '@rolldown/binding-linux-x64-musl': 1.1.3 + '@rolldown/binding-openharmony-arm64': 1.1.3 + '@rolldown/binding-wasm32-wasi': 1.1.3 + '@rolldown/binding-win32-arm64-msvc': 1.1.3 + '@rolldown/binding-win32-x64-msvc': 1.1.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.4: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + + scheduler@0.27.0: {} + + semver@6.3.1: {} + + semver@7.8.5: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + + sharp@0.34.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.8.5 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + optional: true + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + siginfo@2.0.0: {} + + source-map-js@1.2.1: {} + + stable-hash@0.0.5: {} + + stackback@0.0.2: {} + + std-env@4.1.0: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + string.prototype.includes@2.0.1: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + + string.prototype.matchall@4.0.12: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.1 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.24.2 + + string.prototype.trim@1.2.11: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.2 + has-property-descriptors: 1.0.2 + safe-regex-test: 1.1.0 + + string.prototype.trimend@1.0.10: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 + + strip-bom@3.0.0: {} + + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + + strip-json-comments@3.1.1: {} + + styled-jsx@5.1.6(@babel/core@7.29.7)(react@19.2.7): + dependencies: + client-only: 0.0.1 + react: 19.2.7 + optionalDependencies: + '@babel/core': 7.29.7 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + symbol-tree@3.2.4: {} + + tinybench@2.9.0: {} + + tinyexec@1.2.4: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + tinyrainbow@3.1.0: {} + + tldts-core@7.4.4: {} + + tldts@7.4.4: + dependencies: + tldts-core: 7.4.4 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tough-cookie@6.0.1: + dependencies: + tldts: 7.4.4 + + tr46@6.0.0: + dependencies: + punycode: 2.3.1 + + ts-api-utils@2.5.0(typescript@6.0.3): + dependencies: + typescript: 6.0.3 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.8.1: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.8: + dependencies: + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript-eslint@8.62.0(eslint@9.39.4)(typescript@6.0.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.62.0(@typescript-eslint/parser@8.62.0(eslint@9.39.4)(typescript@6.0.3))(eslint@9.39.4)(typescript@6.0.3) + '@typescript-eslint/parser': 8.62.0(eslint@9.39.4)(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.62.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.0(eslint@9.39.4)(typescript@6.0.3) + eslint: 9.39.4 + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + typescript@6.0.3: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@7.16.0: {} + + undici@7.28.0: {} + + unrs-resolver@1.12.2: + dependencies: + napi-postinstall: 0.3.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.12.2 + '@unrs/resolver-binding-android-arm64': 1.12.2 + '@unrs/resolver-binding-darwin-arm64': 1.12.2 + '@unrs/resolver-binding-darwin-x64': 1.12.2 + '@unrs/resolver-binding-freebsd-x64': 1.12.2 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.12.2 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.12.2 + '@unrs/resolver-binding-linux-arm64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-arm64-musl': 1.12.2 + '@unrs/resolver-binding-linux-loong64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-loong64-musl': 1.12.2 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-riscv64-musl': 1.12.2 + '@unrs/resolver-binding-linux-s390x-gnu': 1.12.2 + '@unrs/resolver-binding-linux-x64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-x64-musl': 1.12.2 + '@unrs/resolver-binding-openharmony-arm64': 1.12.2 + '@unrs/resolver-binding-wasm32-wasi': 1.12.2 + '@unrs/resolver-binding-win32-arm64-msvc': 1.12.2 + '@unrs/resolver-binding-win32-ia32-msvc': 1.12.2 + '@unrs/resolver-binding-win32-x64-msvc': 1.12.2 + + update-browserslist-db@1.2.3(browserslist@4.28.4): + dependencies: + browserslist: 4.28.4 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + vite@8.1.0(@types/node@24.10.9): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.15 + rolldown: 1.1.3 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 24.10.9 + fsevents: 2.3.3 + + vitest@4.1.9(@types/node@24.10.9)(@vitest/coverage-v8@4.1.9)(jsdom@29.1.1)(vite@8.1.0(@types/node@24.10.9)): + dependencies: + '@vitest/expect': 4.1.9 + '@vitest/mocker': 4.1.9(vite@8.1.0(@types/node@24.10.9)) + '@vitest/pretty-format': 4.1.9 + '@vitest/runner': 4.1.9 + '@vitest/snapshot': 4.1.9 + '@vitest/spy': 4.1.9 + '@vitest/utils': 4.1.9 + es-module-lexer: 2.1.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.3 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.1.0 + tinybench: 2.9.0 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.0 + vite: 8.1.0(@types/node@24.10.9) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 24.10.9 + '@vitest/coverage-v8': 4.1.9(vitest@4.1.9) + jsdom: 29.1.1 + transitivePeerDependencies: + - msw + + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + + webidl-conversions@8.0.1: {} + + whatwg-mimetype@5.0.0: {} + + whatwg-url@16.0.1: + dependencies: + '@exodus/bytes': 1.15.1 + tr46: 6.0.0 + webidl-conversions: 8.0.1 + transitivePeerDependencies: + - '@noble/hashes' + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.2.0 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.2 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.22 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.22: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + word-wrap@1.2.5: {} + + xml-name-validator@5.0.0: {} + + xmlchars@2.2.0: {} + + yallist@3.1.1: {} + + yocto-queue@0.1.0: {} + + zod-validation-error@4.0.2(zod@4.4.3): + dependencies: + zod: 4.4.3 + + zod@4.4.3: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..02ca845 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,21 @@ +packages: + - . + +allowBuilds: + sharp: true + unrs-resolver: true + +minimumReleaseAge: 1440 +minimumReleaseAgeExclude: + - next@16.2.9 + - react@19.2.7 + - react-dom@19.2.7 + - typescript@6.0.3 + - eslint@9.39.4 + - prettier@3.8.4 + - vitest@4.1.9 + - '@vitest/coverage-v8@4.1.9' + - '@playwright/test@1.61.1' + +overrides: + postcss: 8.5.15 diff --git a/prettier.config.mjs b/prettier.config.mjs new file mode 100644 index 0000000..b1f4351 --- /dev/null +++ b/prettier.config.mjs @@ -0,0 +1,9 @@ +/** @type {import("prettier").Config} */ +const config = { + printWidth: 100, + singleQuote: true, + trailingComma: 'all', + plugins: [], +}; + +export default config; diff --git a/public/.gitkeep b/public/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/scripts/generate-phase10-manifest.mjs b/scripts/generate-phase10-manifest.mjs new file mode 100644 index 0000000..918b592 --- /dev/null +++ b/scripts/generate-phase10-manifest.mjs @@ -0,0 +1,55 @@ +import { createHash } from 'node:crypto'; +import { readFile, readdir, stat, writeFile } from 'node:fs/promises'; +import path from 'node:path'; + +const root = path.resolve(import.meta.dirname, '..'); +const manifestPath = path.join(root, 'PHASE_10_PACKAGE_MANIFEST_v1.0.json'); +const excludedDirectories = new Set([ + '.git', + '.next', + 'node_modules', + 'coverage', + 'playwright-report', + 'test-results', +]); +const excludedFiles = new Set(['PHASE_10_PACKAGE_MANIFEST_v1.0.json', 'tsconfig.tsbuildinfo']); + +async function walk(directory) { + const files = []; + const entries = await readdir(directory, { withFileTypes: true }); + for (const entry of entries) { + if (entry.isDirectory() && excludedDirectories.has(entry.name)) continue; + const fullPath = path.join(directory, entry.name); + if (entry.isDirectory()) files.push(...(await walk(fullPath))); + else { + const relative = path.relative(root, fullPath).split(path.sep).join('/'); + if (!excludedFiles.has(relative)) files.push({ fullPath, relative }); + } + } + return files; +} + +const files = (await walk(root)).sort((a, b) => a.relative.localeCompare(b.relative)); +const entries = []; +for (const file of files) { + const contents = await readFile(file.fullPath); + const details = await stat(file.fullPath); + entries.push({ + path: file.relative, + bytes: details.size, + sha256: createHash('sha256').update(contents).digest('hex'), + }); +} + +const manifest = { + schema_version: '1.0', + project: 'RentalDriveGo', + phase: 10, + generated_at: '2026-06-25', + excludes: [...excludedDirectories, ...excludedFiles], + file_count: entries.length, + files: entries, +}; + +await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`); +console.log(`Generated Phase 10 manifest for ${entries.length} files.`); diff --git a/scripts/generate-phase11-manifest.mjs b/scripts/generate-phase11-manifest.mjs new file mode 100644 index 0000000..d91d03a --- /dev/null +++ b/scripts/generate-phase11-manifest.mjs @@ -0,0 +1,55 @@ +import { createHash } from 'node:crypto'; +import { readFile, readdir, stat, writeFile } from 'node:fs/promises'; +import path from 'node:path'; + +const root = path.resolve(import.meta.dirname, '..'); +const manifestPath = path.join(root, 'PHASE_11_PACKAGE_MANIFEST_v1.0.json'); +const excludedDirectories = new Set([ + '.git', + '.next', + 'node_modules', + 'coverage', + 'playwright-report', + 'test-results', +]); +const excludedFiles = new Set(['PHASE_11_PACKAGE_MANIFEST_v1.0.json', 'tsconfig.tsbuildinfo']); + +async function walk(directory) { + const files = []; + const entries = await readdir(directory, { withFileTypes: true }); + for (const entry of entries) { + if (entry.isDirectory() && excludedDirectories.has(entry.name)) continue; + const fullPath = path.join(directory, entry.name); + if (entry.isDirectory()) files.push(...(await walk(fullPath))); + else { + const relative = path.relative(root, fullPath).split(path.sep).join('/'); + if (!excludedFiles.has(relative)) files.push({ fullPath, relative }); + } + } + return files; +} + +const files = (await walk(root)).sort((a, b) => a.relative.localeCompare(b.relative)); +const entries = []; +for (const file of files) { + const contents = await readFile(file.fullPath); + const details = await stat(file.fullPath); + entries.push({ + path: file.relative, + bytes: details.size, + sha256: createHash('sha256').update(contents).digest('hex'), + }); +} + +const manifest = { + schema_version: '1.0', + project: 'RentalDriveGo', + phase: 11, + generated_at: '2026-06-25', + excludes: [...excludedDirectories, ...excludedFiles], + file_count: entries.length, + files: entries, +}; + +await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`); +console.log(`Generated Phase 11 manifest for ${entries.length} files.`); diff --git a/scripts/generate-phase12-manifest.mjs b/scripts/generate-phase12-manifest.mjs new file mode 100644 index 0000000..98c0f21 --- /dev/null +++ b/scripts/generate-phase12-manifest.mjs @@ -0,0 +1,52 @@ +import { createHash } from 'node:crypto'; +import { readFile, readdir, stat, writeFile } from 'node:fs/promises'; +import path from 'node:path'; + +const root = path.resolve(import.meta.dirname, '..'); +const manifestPath = path.join(root, 'PHASE_12_PACKAGE_MANIFEST_v1.0.json'); +const excludedDirectories = new Set([ + '.git', + '.next', + 'node_modules', + 'coverage', + 'playwright-report', + 'test-results', +]); +const excludedFiles = new Set(['PHASE_12_PACKAGE_MANIFEST_v1.0.json', 'tsconfig.tsbuildinfo']); + +async function walk(directory) { + const files = []; + for (const entry of await readdir(directory, { withFileTypes: true })) { + if (entry.isDirectory() && excludedDirectories.has(entry.name)) continue; + const fullPath = path.join(directory, entry.name); + if (entry.isDirectory()) files.push(...(await walk(fullPath))); + else { + const relative = path.relative(root, fullPath).split(path.sep).join('/'); + if (!excludedFiles.has(relative)) files.push({ fullPath, relative }); + } + } + return files; +} + +const files = (await walk(root)).sort((a, b) => a.relative.localeCompare(b.relative)); +const entries = []; +for (const file of files) { + const contents = await readFile(file.fullPath); + const details = await stat(file.fullPath); + entries.push({ + path: file.relative, + bytes: details.size, + sha256: createHash('sha256').update(contents).digest('hex'), + }); +} +const manifest = { + schema_version: '1.0', + project: 'RentalDriveGo', + phase: 12, + generated_at: '2026-06-25', + excludes: [...excludedDirectories, ...excludedFiles], + file_count: entries.length, + files: entries, +}; +await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`); +console.log(`Generated Phase 12 manifest for ${entries.length} files.`); diff --git a/scripts/generate-phase13-manifest.mjs b/scripts/generate-phase13-manifest.mjs new file mode 100644 index 0000000..859452b --- /dev/null +++ b/scripts/generate-phase13-manifest.mjs @@ -0,0 +1,56 @@ +import { createHash } from 'node:crypto'; +import { readFile, readdir, stat, writeFile } from 'node:fs/promises'; +import path from 'node:path'; + +const root = path.resolve(import.meta.dirname, '..'); +const manifestPath = path.join(root, 'PHASE_13_PACKAGE_MANIFEST_v1.0.json'); +const excludedDirectories = new Set([ + '.git', + '.next', + 'node_modules', + 'coverage', + 'playwright-report', + 'test-results', +]); +const excludedFiles = new Set([ + 'PHASE_13_PACKAGE_MANIFEST_v1.0.json', + 'package-lock.json', + 'tsconfig.tsbuildinfo', +]); + +async function walk(directory) { + const files = []; + for (const entry of await readdir(directory, { withFileTypes: true })) { + if (entry.isDirectory() && excludedDirectories.has(entry.name)) continue; + const fullPath = path.join(directory, entry.name); + if (entry.isDirectory()) files.push(...(await walk(fullPath))); + else { + const relative = path.relative(root, fullPath).split(path.sep).join('/'); + if (!excludedFiles.has(relative)) files.push({ fullPath, relative }); + } + } + return files; +} + +const files = (await walk(root)).sort((a, b) => a.relative.localeCompare(b.relative)); +const entries = []; +for (const file of files) { + const contents = await readFile(file.fullPath); + const details = await stat(file.fullPath); + entries.push({ + path: file.relative, + bytes: details.size, + sha256: createHash('sha256').update(contents).digest('hex'), + }); +} +const manifest = { + schema_version: '1.0', + project: 'RentalDriveGo', + phase: 13, + generated_at: '2026-06-25', + excludes: [...excludedDirectories, ...excludedFiles], + file_count: entries.length, + files: entries, +}; +await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`); +console.log(`Generated Phase 13 manifest for ${entries.length} files.`); diff --git a/scripts/lib.mjs b/scripts/lib.mjs new file mode 100644 index 0000000..95a81f7 --- /dev/null +++ b/scripts/lib.mjs @@ -0,0 +1,46 @@ +import { createHash } from 'node:crypto'; +import { readFile, readdir, stat } from 'node:fs/promises'; +import path from 'node:path'; + +export const repositoryRoot = path.resolve(import.meta.dirname, '..'); + +export async function sha256(filePath) { + const contents = await readFile(filePath); + return createHash('sha256').update(contents).digest('hex'); +} + +export async function walk(directory, predicate = () => true) { + const output = []; + for (const entry of await readdir(directory)) { + const fullPath = path.join(directory, entry); + const details = await stat(fullPath); + if (details.isDirectory()) output.push(...(await walk(fullPath, predicate))); + else if (predicate(fullPath)) output.push(fullPath); + } + return output; +} + +export function flatten(value, prefix = '', output = new Map()) { + if (Array.isArray(value)) { + value.forEach((entry, index) => flatten(entry, `${prefix}[${index}]`, output)); + if (value.length === 0) output.set(prefix, value); + return output; + } + if (value && typeof value === 'object') { + for (const [key, entry] of Object.entries(value)) { + flatten(entry, prefix ? `${prefix}.${key}` : key, output); + } + return output; + } + output.set(prefix, value); + return output; +} + +export function fail(messages) { + for (const message of messages) console.error(`ERROR: ${message}`); + process.exitCode = 1; +} + +export function pass(message) { + console.log(`PASS: ${message}`); +} diff --git a/scripts/prepare-standalone.mjs b/scripts/prepare-standalone.mjs new file mode 100644 index 0000000..9a1feb5 --- /dev/null +++ b/scripts/prepare-standalone.mjs @@ -0,0 +1,24 @@ +import { cp, mkdir, rm } from 'node:fs/promises'; +import { existsSync } from 'node:fs'; +import path from 'node:path'; + +const root = process.cwd(); +const standalone = path.join(root, '.next', 'standalone'); + +if (!existsSync(standalone)) { + throw new Error('Missing .next/standalone. Run next build before preparing the server.'); +} + +const copies = [ + [path.join(root, '.next', 'static'), path.join(standalone, '.next', 'static')], + [path.join(root, 'public'), path.join(standalone, 'public')], +]; + +for (const [source, destination] of copies) { + if (!existsSync(source)) continue; + await rm(destination, { recursive: true, force: true }); + await mkdir(path.dirname(destination), { recursive: true }); + await cp(source, destination, { recursive: true }); +} + +console.log('Prepared standalone server assets.'); diff --git a/scripts/run-checks.mjs b/scripts/run-checks.mjs new file mode 100644 index 0000000..e84e3dd --- /dev/null +++ b/scripts/run-checks.mjs @@ -0,0 +1,19 @@ +import { spawnSync } from 'node:child_process'; + +const commands = [ + ['pnpm', ['validate']], + ['pnpm', ['format:check']], + ['pnpm', ['lint']], + ['pnpm', ['typecheck']], + ['pnpm', ['test:unit']], + ['pnpm', ['build'], { SITE_ORIGIN: 'http://127.0.0.1:3000', PUBLIC_RELEASE_APPROVED: 'false' }], + ['pnpm', ['audit']], +]; +for (const [command, args, extraEnv = {}] of commands) { + const result = spawnSync(command, args, { + stdio: 'inherit', + shell: process.platform === 'win32', + env: { ...process.env, ...extraEnv }, + }); + if (result.status !== 0) process.exit(result.status ?? 1); +} diff --git a/scripts/run-validations.mjs b/scripts/run-validations.mjs new file mode 100644 index 0000000..e6e7e10 --- /dev/null +++ b/scripts/run-validations.mjs @@ -0,0 +1,19 @@ +import { spawnSync } from 'node:child_process'; + +const scripts = [ + 'validate-phase9-contract.mjs', + 'validate-runtime-dependencies.mjs', + 'validate-locales.mjs', + 'validate-routes.mjs', + 'validate-tokens.mjs', + 'validate-phase11-foundation.mjs', + 'validate-css-logical.mjs', + 'validate-prohibited-content.mjs', + 'validate-metadata.mjs', + 'validate-phase12-components.mjs', + 'validate-phase13-homepage.mjs', +]; +for (const script of scripts) { + const result = spawnSync(process.execPath, [`scripts/${script}`], { stdio: 'inherit' }); + if (result.status !== 0) process.exit(result.status ?? 1); +} diff --git a/scripts/validate-css-logical.mjs b/scripts/validate-css-logical.mjs new file mode 100644 index 0000000..0008690 --- /dev/null +++ b/scripts/validate-css-logical.mjs @@ -0,0 +1,26 @@ +import { readFile } from 'node:fs/promises'; +import path from 'node:path'; +import { fail, pass, repositoryRoot, walk } from './lib.mjs'; + +const cssFiles = await walk(path.join(repositoryRoot, 'src'), (file) => file.endsWith('.css')); +const errors = []; +const forbidden = [ + /(^|[;{]\s*)(left|right)\s*:/gim, + /(^|[;{]\s*)(margin|padding|border)-(left|right)(?:-[a-z]+)?\s*:/gim, + /(^|[;{]\s*)inset-(left|right)\s*:/gim, + /(^|[;{]\s*)text-align\s*:\s*(left|right)/gim, + /(^|[;{]\s*)float\s*:\s*(left|right)/gim, +]; +for (const file of cssFiles) { + const text = await readFile(file, 'utf8'); + for (const expression of forbidden) { + const matches = text.match(expression); + if (matches) + errors.push( + `${path.relative(repositoryRoot, file)} uses physical CSS: ${matches.join(', ')}`, + ); + } +} + +if (errors.length > 0) fail(errors); +else pass(`${cssFiles.length} CSS files use direction-safe logical declarations.`); diff --git a/scripts/validate-locales.mjs b/scripts/validate-locales.mjs new file mode 100644 index 0000000..dec3166 --- /dev/null +++ b/scripts/validate-locales.mjs @@ -0,0 +1,47 @@ +import { readFile } from 'node:fs/promises'; +import path from 'node:path'; +import { fail, flatten, pass, repositoryRoot } from './lib.mjs'; + +const localeRoot = path.join(repositoryRoot, 'src', 'content', 'locales'); +const locales = ['en', 'fr', 'ar']; +const files = ['homepage.json', 'shell.json']; +const errors = []; + +for (const file of files) { + const catalogs = new Map(); + for (const locale of locales) { + const parsed = JSON.parse(await readFile(path.join(localeRoot, locale, file), 'utf8')); + catalogs.set(locale, flatten(parsed)); + } + const sourceKeys = [...catalogs.get('en').keys()]; + for (const locale of locales) { + const catalog = catalogs.get(locale); + const keys = [...catalog.keys()]; + const missing = sourceKeys.filter((key) => !catalog.has(key)); + const extra = keys.filter((key) => !catalogs.get('en').has(key)); + if (missing.length) errors.push(`${locale}/${file} missing: ${missing.join(', ')}`); + if (extra.length) errors.push(`${locale}/${file} extra: ${extra.join(', ')}`); + for (const [key, value] of catalog) { + if (typeof value === 'string' && value.trim().length === 0) { + errors.push(`${locale}/${file}:${key} is empty.`); + } + } + } +} + +const expectedDirections = { en: 'ltr', fr: 'ltr', ar: 'rtl' }; +for (const locale of locales) { + const homepage = JSON.parse( + await readFile(path.join(localeRoot, locale, 'homepage.json'), 'utf8'), + ); + if (homepage.meta.dir !== expectedDirections[locale]) { + errors.push(`${locale} metadata direction must be ${expectedDirections[locale]}.`); + } + if (JSON.stringify(homepage).includes('homePageCar')) { + errors.push(`${locale} implementation catalog still contains the retired project name.`); + } +} + +if (errors.length > 0) fail(errors); +else + pass('English, French, and Arabic catalogs have exact key parity and valid direction metadata.'); diff --git a/scripts/validate-metadata.mjs b/scripts/validate-metadata.mjs new file mode 100644 index 0000000..172b74f --- /dev/null +++ b/scripts/validate-metadata.mjs @@ -0,0 +1,39 @@ +import { readFile } from 'node:fs/promises'; +import path from 'node:path'; +import { fail, pass, repositoryRoot } from './lib.mjs'; + +const errors = []; +const metadata = await readFile( + path.join(repositoryRoot, 'src', 'lib', 'metadata', 'build-metadata.ts'), + 'utf8', +); +const homepage = await readFile( + path.join(repositoryRoot, 'src', 'app', '[locale]', 'page.tsx'), + 'utf8', +); +const pending = await readFile( + path.join(repositoryRoot, 'src', 'app', '[locale]', '[slug]', 'page.tsx'), + 'utf8', +); + +for (const required of [ + 'alternates', + 'canonical', + 'hreflangMap', + 'openGraph', + 'alternateLocale', + 'twitter', + 'robots', +]) { + if (!metadata.includes(required)) errors.push(`Metadata foundation omits ${required}.`); +} +if (!homepage.includes("routeId: 'home'")) errors.push('Homepage metadata is not route-ID driven.'); +if (!pending.includes('indexable: false')) { + errors.push('Unapproved route shells must remain noindex.'); +} +if (/application\/ld\+json|aggregateRating|priceCurrency/.test(metadata + homepage + pending)) { + errors.push('Unsupported structured data or pricing metadata was introduced.'); +} + +if (errors.length) fail(errors); +else pass('Localized canonical, hreflang, Open Graph, social, and robots foundations are present.'); diff --git a/scripts/validate-phase10-manifest.mjs b/scripts/validate-phase10-manifest.mjs new file mode 100644 index 0000000..d6d7acd --- /dev/null +++ b/scripts/validate-phase10-manifest.mjs @@ -0,0 +1,30 @@ +import { readFile, stat } from 'node:fs/promises'; +import path from 'node:path'; +import { repositoryRoot, sha256, fail, pass } from './lib.mjs'; + +const manifestPath = path.join(repositoryRoot, 'PHASE_10_PACKAGE_MANIFEST_v1.0.json'); +const manifest = JSON.parse(await readFile(manifestPath, 'utf8')); +const failures = []; + +if (manifest.project !== 'RentalDriveGo' || manifest.phase !== 10) { + failures.push('Phase 10 manifest identity is invalid.'); +} +if (manifest.file_count !== manifest.files.length) { + failures.push( + `Manifest file_count ${manifest.file_count} does not match ${manifest.files.length} entries.`, + ); +} +for (const entry of manifest.files) { + const filePath = path.join(repositoryRoot, entry.path); + try { + const details = await stat(filePath); + if (details.size !== entry.bytes) failures.push(`${entry.path}: byte size changed.`); + const digest = await sha256(filePath); + if (digest !== entry.sha256) failures.push(`${entry.path}: SHA-256 changed.`); + } catch { + failures.push(`${entry.path}: file is missing.`); + } +} + +if (failures.length) fail(failures); +else pass(`Phase 10 package manifest verifies ${manifest.files.length} repository files.`); diff --git a/scripts/validate-phase11-foundation.mjs b/scripts/validate-phase11-foundation.mjs new file mode 100644 index 0000000..2731a52 --- /dev/null +++ b/scripts/validate-phase11-foundation.mjs @@ -0,0 +1,89 @@ +import { readFile } from 'node:fs/promises'; +import path from 'node:path'; +import { fail, pass, repositoryRoot, walk } from './lib.mjs'; + +const errors = []; +const componentTokenPath = path.join(repositoryRoot, 'src', 'styles', 'component-tokens.css'); +const componentTokens = await readFile(componentTokenPath, 'utf8'); +const requiredTokens = [ + '--surface-page', + '--surface-primary', + '--surface-elevated', + '--surface-muted', + '--text-primary', + '--text-secondary', + '--text-inverse', + '--border-standard', + '--border-strong', + '--interactive-primary', + '--interactive-conversion', + '--interactive-danger', + '--focus-ring', + '--status-success-surface', + '--status-warning-surface', + '--status-error-surface', + '--status-info-surface', + '--overlay-scrim', + '--control-disabled-surface', + '--selection-surface', + '--skeleton-base', + '--shadow-card', + '--container-wide', + '--layer-overlay', + '--type-display-size', +]; + +for (const token of requiredTokens) { + if (!componentTokens.includes(token)) errors.push(`Missing Phase 11 component token ${token}.`); +} +if (!componentTokens.includes("html[data-theme='dark']")) { + errors.push('Component token layer has no explicit dark-theme mapping.'); +} +if (!componentTokens.includes("html[data-theme-preference='system']")) { + errors.push('Component token layer has no CSS-only system-theme fallback.'); +} + +const cssFiles = await walk(path.join(repositoryRoot, 'src'), (file) => file.endsWith('.css')); +const declarationFiles = new Set([ + path.join(repositoryRoot, 'src', 'styles', 'tokens.css'), + componentTokenPath, +]); +const literalColor = /(?:#[0-9a-f]{3,8}\b|\brgba?\(|\bhsla?\()/gi; +const rawPaletteReference = /var\(--color-(?:blue|orange|navy|gray|green|amber|red)-/gi; + +for (const file of cssFiles) { + if (declarationFiles.has(file)) continue; + const text = await readFile(file, 'utf8'); + if (literalColor.test(text)) { + errors.push( + `${path.relative(repositoryRoot, file)} contains a literal color outside token declarations.`, + ); + } + literalColor.lastIndex = 0; + if (rawPaletteReference.test(text)) { + errors.push(`${path.relative(repositoryRoot, file)} consumes a raw palette token.`); + } + rawPaletteReference.lastIndex = 0; +} + +const shellFiles = [ + 'src/components/app-shell/SiteHeader.tsx', + 'src/components/app-shell/MobileNavigation.tsx', + 'src/components/app-shell/SiteFooter.tsx', + 'src/app/[locale]/loading.tsx', + 'src/app/[locale]/error.tsx', + 'src/app/[locale]/not-found.tsx', + 'src/app/[locale]/[slug]/page.tsx', +]; +for (const relativePath of shellFiles) { + try { + await readFile(path.join(repositoryRoot, relativePath), 'utf8'); + } catch { + errors.push(`Required Phase 11 shell file is missing: ${relativePath}`); + } +} + +if (errors.length) fail(errors); +else { + pass('Phase 11 component tokens, theme fallback, and application-shell foundations are present.'); +} diff --git a/scripts/validate-phase11-manifest.mjs b/scripts/validate-phase11-manifest.mjs new file mode 100644 index 0000000..2b3779f --- /dev/null +++ b/scripts/validate-phase11-manifest.mjs @@ -0,0 +1,87 @@ +import { readFile, readdir, stat } from 'node:fs/promises'; +import path from 'node:path'; +import { fail, pass, repositoryRoot, sha256 } from './lib.mjs'; + +const manifestName = 'PHASE_11_PACKAGE_MANIFEST_v1.0.json'; +const manifestPath = path.join(repositoryRoot, manifestName); +const excludedDirectories = new Set([ + '.git', + '.next', + 'node_modules', + 'coverage', + 'playwright-report', + 'test-results', +]); +const excludedFiles = new Set([manifestName, 'tsconfig.tsbuildinfo']); + +async function walk(directory) { + const files = []; + const entries = await readdir(directory, { withFileTypes: true }); + for (const entry of entries) { + if (entry.isDirectory() && excludedDirectories.has(entry.name)) continue; + const fullPath = path.join(directory, entry.name); + if (entry.isDirectory()) { + files.push(...(await walk(fullPath))); + continue; + } + const relative = path.relative(repositoryRoot, fullPath).split(path.sep).join('/'); + if (!excludedFiles.has(relative)) files.push(relative); + } + return files; +} + +const manifest = JSON.parse(await readFile(manifestPath, 'utf8')); +const failures = []; + +if (manifest.project !== 'RentalDriveGo' || manifest.phase !== 11) { + failures.push('Phase 11 manifest identity is invalid.'); +} +if (!Array.isArray(manifest.files)) { + failures.push('Manifest files property must be an array.'); +} else if (manifest.file_count !== manifest.files.length) { + failures.push( + `Manifest file_count ${manifest.file_count} does not match ${manifest.files.length} entries.`, + ); +} + +const listedPaths = new Set(); +for (const entry of manifest.files ?? []) { + if ( + typeof entry.path !== 'string' || + entry.path.length === 0 || + path.isAbsolute(entry.path) || + entry.path.split('/').includes('..') + ) { + failures.push(`Unsafe manifest path: ${String(entry.path)}`); + continue; + } + if (listedPaths.has(entry.path)) { + failures.push(`${entry.path}: duplicate manifest entry.`); + continue; + } + listedPaths.add(entry.path); + + const filePath = path.join(repositoryRoot, entry.path); + try { + const details = await stat(filePath); + if (!details.isFile()) failures.push(`${entry.path}: is not a regular file.`); + if (details.size !== entry.bytes) failures.push(`${entry.path}: byte size changed.`); + const digest = await sha256(filePath); + if (digest !== entry.sha256) failures.push(`${entry.path}: SHA-256 changed.`); + } catch { + failures.push(`${entry.path}: file is missing.`); + } +} + +const actualPaths = new Set(await walk(repositoryRoot)); +for (const actual of actualPaths) { + if (!listedPaths.has(actual)) failures.push(`${actual}: unlisted repository file.`); +} +for (const listed of listedPaths) { + if (!actualPaths.has(listed)) failures.push(`${listed}: listed but excluded or absent.`); +} + +if (failures.length) fail(failures); +else { + pass(`Phase 11 package manifest verifies ${listedPaths.size} repository files with no extras.`); +} diff --git a/scripts/validate-phase12-components.mjs b/scripts/validate-phase12-components.mjs new file mode 100644 index 0000000..58c2367 --- /dev/null +++ b/scripts/validate-phase12-components.mjs @@ -0,0 +1,97 @@ +import { readFile, stat } from 'node:fs/promises'; +import path from 'node:path'; +import { fail, pass, repositoryRoot, walk } from './lib.mjs'; + +const inventoryPath = path.join(repositoryRoot, 'docs/phase12/COMPONENT_INVENTORY_v1.0.json'); +const inventory = JSON.parse(await readFile(inventoryPath, 'utf8')); +const errors = []; +const allowedStatus = new Set(['implemented', 'partially-implemented', 'blocked', 'excluded']); +const names = new Set(); + +if (inventory.phase !== 12 || !Array.isArray(inventory.entries)) { + errors.push('Component inventory must identify Phase 12 and contain an entries array.'); +} +for (const entry of inventory.entries ?? []) { + if (names.has(entry.name)) errors.push(`Duplicate inventory component: ${entry.name}`); + names.add(entry.name); + if (!allowedStatus.has(entry.status)) + errors.push(`${entry.name}: invalid status ${entry.status}`); + for (const field of ['sourceSpecification', 'variants', 'openIssues', 'homepageConsumers']) { + if (!Array.isArray(entry[field])) errors.push(`${entry.name}: ${field} must be an array.`); + } + if ( + !entry.tests || + !['unit', 'interaction', 'accessibility', 'visual'].every( + (key) => typeof entry.tests[key] === 'boolean', + ) + ) { + errors.push(`${entry.name}: test coverage flags are incomplete.`); + } + if (entry.status === 'blocked' && entry.openIssues.length === 0) { + errors.push(`${entry.name}: blocked components require an issue reference.`); + } +} + +for (const required of [ + 'Button', + 'ActionLink', + 'FormField', + 'Tabs', + 'Accordion', + 'Dialog', + 'Alert', + 'Card', + 'Workflow', + 'Comparison', + 'Metric', + 'CTA', + 'ProductPreview', +]) { + if (!names.has(required)) errors.push(`Required component missing from inventory: ${required}`); +} + +const componentFiles = await walk(path.join(repositoryRoot, 'src/components'), (file) => + /\.(?:ts|tsx|css)$/.test(file), +); +const forbiddenRawToken = /var\(--color-(?:blue|orange|gray|green|amber|red|navy)-/g; +const forbiddenLiteralColor = /(?:#[0-9a-f]{3,8}\b|rgba?\(|hsla?\()/gi; +for (const file of componentFiles) { + const text = await readFile(file, 'utf8'); + const relative = path.relative(repositoryRoot, file); + if (file.endsWith('.css') && forbiddenRawToken.test(text)) + errors.push(`${relative}: consumes a raw palette token.`); + if (file.endsWith('.css') && forbiddenLiteralColor.test(text)) + errors.push(`${relative}: contains a literal color.`); + if (/href=["']#["']/.test(text)) errors.push(`${relative}: contains a placeholder href="#".`); +} + +for (const artifact of [ + 'COMPONENT_SPECIFICATION_TRACEABILITY_v1.0.csv', + 'VARIANT_INVENTORY_v1.0.csv', + 'ACCESSIBILITY_BEHAVIOR_MATRIX_v1.0.csv', + 'RTL_BEHAVIOR_MATRIX_UPDATE_v1.0.csv', + 'RESPONSIVE_VALIDATION_MATRIX_v1.0.csv', + 'STORY_AND_FIXTURE_INVENTORY_v1.0.csv', + 'TEST_COVERAGE_REPORT_v1.0.csv', + 'COMPONENT_CATALOG_v1.0.md', +]) { + try { + await stat(path.join(repositoryRoot, 'docs/phase12', artifact)); + } catch { + errors.push(`Required Phase 12 artifact missing: ${artifact}`); + } +} + +const fixturePage = await readFile( + path.join(repositoryRoot, 'src/app/[locale]/component-lab/page.tsx'), + 'utf8', +); +if (!fixturePage.includes("COMPONENT_FIXTURES_ENABLED !== 'true'")) { + errors.push('Component fixture route is not protected by the production environment guard.'); +} + +if (errors.length > 0) fail(errors); +else + pass( + `${inventory.entries.length} inventory entries and ${componentFiles.length} component source files satisfy Phase 12 static controls.`, + ); diff --git a/scripts/validate-phase12-manifest.mjs b/scripts/validate-phase12-manifest.mjs new file mode 100644 index 0000000..c57def3 --- /dev/null +++ b/scripts/validate-phase12-manifest.mjs @@ -0,0 +1,65 @@ +import { readFile, readdir, stat } from 'node:fs/promises'; +import path from 'node:path'; +import { fail, pass, repositoryRoot, sha256 } from './lib.mjs'; + +const manifestName = 'PHASE_12_PACKAGE_MANIFEST_v1.0.json'; +const excludedDirectories = new Set([ + '.git', + '.next', + 'node_modules', + 'coverage', + 'playwright-report', + 'test-results', +]); +const excludedFiles = new Set([manifestName, 'tsconfig.tsbuildinfo']); +async function walk(directory) { + const files = []; + for (const entry of await readdir(directory, { withFileTypes: true })) { + if (entry.isDirectory() && excludedDirectories.has(entry.name)) continue; + const fullPath = path.join(directory, entry.name); + if (entry.isDirectory()) files.push(...(await walk(fullPath))); + else { + const relative = path.relative(repositoryRoot, fullPath).split(path.sep).join('/'); + if (!excludedFiles.has(relative)) files.push(relative); + } + } + return files; +} +const manifest = JSON.parse(await readFile(path.join(repositoryRoot, manifestName), 'utf8')); +const failures = []; +if (manifest.project !== 'RentalDriveGo' || manifest.phase !== 12) + failures.push('Phase 12 manifest identity is invalid.'); +if (!Array.isArray(manifest.files) || manifest.file_count !== manifest.files.length) + failures.push('Manifest file count is invalid.'); +const listed = new Set(); +for (const entry of manifest.files ?? []) { + if ( + typeof entry.path !== 'string' || + path.isAbsolute(entry.path) || + entry.path.split('/').includes('..') + ) { + failures.push(`Unsafe manifest path: ${String(entry.path)}`); + continue; + } + if (listed.has(entry.path)) { + failures.push(`${entry.path}: duplicate manifest entry.`); + continue; + } + listed.add(entry.path); + try { + const filePath = path.join(repositoryRoot, entry.path); + const details = await stat(filePath); + if (!details.isFile() || details.size !== entry.bytes) + failures.push(`${entry.path}: file metadata changed.`); + if ((await sha256(filePath)) !== entry.sha256) failures.push(`${entry.path}: SHA-256 changed.`); + } catch { + failures.push(`${entry.path}: file is missing.`); + } +} +const actual = new Set(await walk(repositoryRoot)); +for (const file of actual) + if (!listed.has(file)) failures.push(`${file}: unlisted repository file.`); +for (const file of listed) + if (!actual.has(file)) failures.push(`${file}: listed but excluded or absent.`); +if (failures.length) fail(failures); +else pass(`Phase 12 package manifest verifies ${listed.size} repository files with no extras.`); diff --git a/scripts/validate-phase13-homepage.mjs b/scripts/validate-phase13-homepage.mjs new file mode 100644 index 0000000..d42ed0e --- /dev/null +++ b/scripts/validate-phase13-homepage.mjs @@ -0,0 +1,68 @@ +import { readFile, stat } from 'node:fs/promises'; +import path from 'node:path'; +import { fail, pass, repositoryRoot } from './lib.mjs'; + +const errors = []; +const pagePath = path.join(repositoryRoot, 'src/app/[locale]/page.tsx'); +const cssPath = path.join(repositoryRoot, 'src/app/[locale]/page.module.css'); +const modelPath = path.join(repositoryRoot, 'src/content/homepage-model.ts'); +const page = await readFile(pagePath, 'utf8'); +const css = await readFile(cssPath, 'utf8'); +const model = await readFile(modelPath, 'utf8'); + +for (const sectionId of ['product', 'workflow', 'modules', 'pricing', 'faq']) { + if (!page.includes(`id="${sectionId}"`)) + errors.push(`Homepage section #${sectionId} is missing.`); +} + +for (const component of [ + 'ActionLink', + 'Accordion', + 'CTA', + 'Comparison', + 'FeatureCard', + 'ProductPreview', + 'SectionHeader', + 'Workflow', +]) { + if (!page.includes(component)) + errors.push(`Homepage does not compose the approved ${component}.`); +} + +if (!page.includes('buildHomepageContent')) + errors.push('Homepage does not consume the typed route content model.'); +if (!page.includes("localizedPath('home', locale)")) + errors.push('Homepage actions do not use the locale route helper.'); +if (page.includes('messages.foundation')) + errors.push('Phase 11 foundation placeholder remains in the homepage route.'); +if (/href=["']#["']/.test(page)) errors.push('Homepage contains href="#".'); +if (/#[0-9a-f]{3,8}\b|rgba?\(|hsla?\(/i.test(css)) + errors.push('Homepage CSS contains literal colors.'); +if (/var\(--color-(?:blue|orange|gray|green|amber|red|navy)-/i.test(css)) { + errors.push('Homepage CSS consumes a raw palette token.'); +} +if (!model.includes('disabledReason')) + errors.push('Homepage content model does not encode unavailable destinations.'); +if (!model.includes('PreviewRow')) + errors.push('Homepage content model does not type product preview rows.'); + +for (const artifact of [ + 'tests/unit/homepage-content.test.ts', + 'tests/browser/homepage.spec.ts', + 'tests/a11y/homepage.a11y.spec.ts', + 'tests/visual/homepage.visual.spec.ts', + 'docs/phase13/HOMEPAGE_SECTION_MATRIX_v1.0.csv', + 'docs/phase13/HOMEPAGE_CONTENT_MODEL_v1.0.md', +]) { + try { + await stat(path.join(repositoryRoot, artifact)); + } catch { + errors.push(`Required Phase 13 artifact missing: ${artifact}`); + } +} + +if (errors.length > 0) fail(errors); +else + pass( + 'Phase 13 homepage composition, content model, destination gates, and test artifacts satisfy static controls.', + ); diff --git a/scripts/validate-phase13-manifest.mjs b/scripts/validate-phase13-manifest.mjs new file mode 100644 index 0000000..582546f --- /dev/null +++ b/scripts/validate-phase13-manifest.mjs @@ -0,0 +1,69 @@ +import { readFile, readdir, stat } from 'node:fs/promises'; +import path from 'node:path'; +import { fail, pass, repositoryRoot, sha256 } from './lib.mjs'; + +const manifestName = 'PHASE_13_PACKAGE_MANIFEST_v1.0.json'; +const excludedDirectories = new Set([ + '.git', + '.next', + 'node_modules', + 'coverage', + 'playwright-report', + 'test-results', +]); +const excludedFiles = new Set([manifestName, 'package-lock.json', 'tsconfig.tsbuildinfo']); + +async function walk(directory) { + const files = []; + for (const entry of await readdir(directory, { withFileTypes: true })) { + if (entry.isDirectory() && excludedDirectories.has(entry.name)) continue; + const fullPath = path.join(directory, entry.name); + if (entry.isDirectory()) files.push(...(await walk(fullPath))); + else { + const relative = path.relative(repositoryRoot, fullPath).split(path.sep).join('/'); + if (!excludedFiles.has(relative)) files.push(relative); + } + } + return files; +} + +const manifest = JSON.parse(await readFile(path.join(repositoryRoot, manifestName), 'utf8')); +const failures = []; +if (manifest.project !== 'RentalDriveGo' || manifest.phase !== 13) { + failures.push('Phase 13 manifest identity is invalid.'); +} +if (!Array.isArray(manifest.files) || manifest.file_count !== manifest.files.length) { + failures.push('Manifest file count is invalid.'); +} +const listed = new Set(); +for (const entry of manifest.files ?? []) { + if ( + typeof entry.path !== 'string' || + path.isAbsolute(entry.path) || + entry.path.split('/').includes('..') + ) { + failures.push(`Unsafe manifest path: ${String(entry.path)}`); + continue; + } + if (listed.has(entry.path)) { + failures.push(`${entry.path}: duplicate manifest entry.`); + continue; + } + listed.add(entry.path); + try { + const filePath = path.join(repositoryRoot, entry.path); + const details = await stat(filePath); + if (!details.isFile() || details.size !== entry.bytes) + failures.push(`${entry.path}: file metadata changed.`); + if ((await sha256(filePath)) !== entry.sha256) failures.push(`${entry.path}: SHA-256 changed.`); + } catch { + failures.push(`${entry.path}: file is missing.`); + } +} +const actual = new Set(await walk(repositoryRoot)); +for (const file of actual) + if (!listed.has(file)) failures.push(`${file}: unlisted repository file.`); +for (const file of listed) + if (!actual.has(file)) failures.push(`${file}: listed but excluded or absent.`); +if (failures.length) fail(failures); +else pass(`Phase 13 package manifest verifies ${listed.size} repository files with no extras.`); diff --git a/scripts/validate-phase9-contract.mjs b/scripts/validate-phase9-contract.mjs new file mode 100644 index 0000000..1e98df3 --- /dev/null +++ b/scripts/validate-phase9-contract.mjs @@ -0,0 +1,41 @@ +import { spawnSync } from 'node:child_process'; +import { readFile, stat } from 'node:fs/promises'; +import path from 'node:path'; +import { fail, pass, repositoryRoot, sha256 } from './lib.mjs'; + +const contractRoot = path.join(repositoryRoot, 'contracts', 'phase9'); +const manifestPath = path.join(contractRoot, 'PACKAGE_MANIFEST_v1.0.json'); +const manifest = JSON.parse(await readFile(manifestPath, 'utf8')); +const errors = []; + +if (manifest.file_count !== manifest.files.length) { + errors.push( + `Manifest count ${manifest.file_count} differs from ${manifest.files.length} entries.`, + ); +} + +for (const entry of manifest.files) { + const filePath = path.join(contractRoot, entry.path); + try { + const details = await stat(filePath); + if (details.size !== entry.bytes) errors.push(`${entry.path}: byte count changed.`); + if ((await sha256(filePath)) !== entry.sha256) errors.push(`${entry.path}: checksum changed.`); + } catch { + errors.push(`${entry.path}: missing.`); + } +} + +const validator = spawnSync( + process.execPath, + [path.join(contractRoot, 'qa', 'validate-phase9-package_v1.0.mjs'), contractRoot], + { encoding: 'utf8' }, +); +if (validator.status !== 0) { + errors.push(`Phase 9 validator failed: ${validator.stderr || validator.stdout}`); +} + +if (errors.length > 0) fail(errors); +else + pass( + `Phase 9 contract package is immutable and ${manifest.files.length} payload checksums match.`, + ); diff --git a/scripts/validate-prohibited-content.mjs b/scripts/validate-prohibited-content.mjs new file mode 100644 index 0000000..9bbc3b8 --- /dev/null +++ b/scripts/validate-prohibited-content.mjs @@ -0,0 +1,28 @@ +import { readFile } from 'node:fs/promises'; +import path from 'node:path'; +import { fail, pass, repositoryRoot, walk } from './lib.mjs'; + +const sourceFiles = await walk(path.join(repositoryRoot, 'src'), (file) => + /\.(?:ts|tsx|js|jsx|css)$/.test(file), +); +const errors = []; +const prohibited = [ + { label: 'placeholder domain', pattern: /example\.(?:com|org|net)|placeholder\.(?:com|test)/i }, + { label: 'simulated submission', pattern: /simulate(?:d|Submission)|fakeSubmit/i }, + { label: 'research-only state backdoor', pattern: /[?&](?:state|scenario|fixture)=/i }, + { label: 'prototype research logger', pattern: /researchLog|prototypeLog/i }, +]; +for (const file of sourceFiles) { + const text = await readFile(file, 'utf8'); + for (const rule of prohibited) { + if (rule.pattern.test(text)) + errors.push(`${path.relative(repositoryRoot, file)} contains ${rule.label}.`); + } +} + +if (errors.length > 0) fail(errors); +else + pass( + 'Runtime source contains no placeholder destination, simulated submission, ' + + 'or research-only backdoor.', + ); diff --git a/scripts/validate-routes.mjs b/scripts/validate-routes.mjs new file mode 100644 index 0000000..0ce4ddd --- /dev/null +++ b/scripts/validate-routes.mjs @@ -0,0 +1,50 @@ +import { readFile, stat } from 'node:fs/promises'; +import path from 'node:path'; +import { fail, pass, repositoryRoot } from './lib.mjs'; + +const manifest = JSON.parse( + await readFile( + path.join(repositoryRoot, 'src', 'contracts', 'phase9', 'route-manifest.json'), + 'utf8', + ), +); +const errors = []; +const requiredLocales = ['en', 'fr', 'ar']; +const ids = new Set(); + +if (JSON.stringify(manifest.locales) !== JSON.stringify(requiredLocales)) { + errors.push('Route locales must remain exactly en, fr, ar.'); +} +for (const route of manifest.routes) { + if (ids.has(route.id)) errors.push(`Duplicate route ID: ${route.id}`); + ids.add(route.id); + for (const locale of requiredLocales) { + if (typeof route.slugs[locale] !== 'string') errors.push(`${route.id} has no ${locale} slug.`); + } +} +for (const locale of requiredLocales) { + if (!manifest.hreflang.values.includes(locale)) errors.push(`hreflang omits ${locale}.`); +} +if (manifest.hreflang.xDefaultLocale !== 'en') errors.push('x-default must resolve to English.'); +if (manifest.switching.dropUnknownQuery !== true) { + errors.push('Unknown query parameters must be dropped.'); +} + +for (const routeFile of [ + 'src/app/[locale]/page.tsx', + 'src/app/[locale]/[slug]/page.tsx', + 'src/app/[locale]/not-found.tsx', +]) { + try { + await stat(path.join(repositoryRoot, routeFile)); + } catch { + errors.push(`Runtime route implementation missing: ${routeFile}`); + } +} + +if (errors.length > 0) fail(errors); +else + pass( + `${manifest.routes.length} route IDs have complete locale, runtime, hash, query, ` + + 'and hreflang contracts.', + ); diff --git a/scripts/validate-runtime-dependencies.mjs b/scripts/validate-runtime-dependencies.mjs new file mode 100644 index 0000000..cef6461 --- /dev/null +++ b/scripts/validate-runtime-dependencies.mjs @@ -0,0 +1,55 @@ +import { readFile } from 'node:fs/promises'; +import path from 'node:path'; +import { fail, pass, repositoryRoot } from './lib.mjs'; + +const expected = { + node: '24.17.0', + pnpm: '11.9.0', +}; +const packageJson = JSON.parse(await readFile(path.join(repositoryRoot, 'package.json'), 'utf8')); +const lockfile = await readFile(path.join(repositoryRoot, 'pnpm-lock.yaml'), 'utf8'); +const nodeVersion = (await readFile(path.join(repositoryRoot, '.node-version'), 'utf8')).trim(); +const nvmVersion = (await readFile(path.join(repositoryRoot, '.nvmrc'), 'utf8')).trim(); +const errors = []; + +if (packageJson.packageManager !== `pnpm@${expected.pnpm}`) { + errors.push(`packageManager must be pnpm@${expected.pnpm}.`); +} +if (packageJson.engines?.node !== expected.node) { + errors.push(`package.json engines.node must be ${expected.node}.`); +} +if (packageJson.engines?.pnpm !== expected.pnpm) { + errors.push(`package.json engines.pnpm must be ${expected.pnpm}.`); +} +if (nodeVersion !== expected.node || nvmVersion !== expected.node) { + errors.push('.node-version and .nvmrc must match the approved Node.js runtime.'); +} + +const directDependencies = { + ...(packageJson.dependencies ?? {}), + ...(packageJson.devDependencies ?? {}), +}; +const exactVersion = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/; +for (const [name, version] of Object.entries(directDependencies)) { + if (typeof version !== 'string' || !exactVersion.test(version)) { + errors.push(`${name} must use an exact direct version, received ${String(version)}.`); + continue; + } + const escapedName = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const escapedVersion = version.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const lockSpecifier = new RegExp( + `(?:^|\\n)\\s{6}['\"]?${escapedName}['\"]?:\\n\\s{8}specifier: ${escapedVersion}(?:\\n|$)`, + ); + if (!lockSpecifier.test(lockfile)) { + errors.push( + `${name}@${version} is not represented by an exact importer specifier in pnpm-lock.yaml.`, + ); + } +} + +if (errors.length) fail(errors); +else { + pass( + `Pinned Node ${expected.node}, pnpm ${expected.pnpm}, and ${Object.keys(directDependencies).length} exact direct dependency versions match the lockfile.`, + ); +} diff --git a/scripts/validate-tokens.mjs b/scripts/validate-tokens.mjs new file mode 100644 index 0000000..f1b2ee8 --- /dev/null +++ b/scripts/validate-tokens.mjs @@ -0,0 +1,50 @@ +import { readFile } from 'node:fs/promises'; +import path from 'node:path'; +import { fail, pass, repositoryRoot, walk } from './lib.mjs'; + +const sourceCss = await readFile( + path.join(repositoryRoot, 'contracts', 'phase9', 'tokens', 'semantic-tokens_v1.0.css'), + 'utf8', +); +const implementationCssPath = path.join(repositoryRoot, 'src', 'styles', 'tokens.css'); +const implementationCss = await readFile(implementationCssPath, 'utf8'); +const designTokens = JSON.parse( + await readFile( + path.join(repositoryRoot, 'src', 'contracts', 'phase9', 'design-tokens.json'), + 'utf8', + ), +); +const errors = []; + +if (sourceCss !== implementationCss) + errors.push('Implementation tokens.css differs from Phase 9 source.'); +const rawColors = new Set(); +for (const scale of Object.values(designTokens.raw.color)) { + for (const value of Object.values(scale)) rawColors.add(String(value).toLowerCase()); +} + +const applicationStyles = await walk( + path.join(repositoryRoot, 'src'), + (file) => file.endsWith('.css') && file !== implementationCssPath, +); +for (const file of applicationStyles) { + const text = (await readFile(file, 'utf8')).toLowerCase(); + for (const color of rawColors) { + if (text.includes(color)) + errors.push(`${path.relative(repositoryRoot, file)} embeds raw brand color ${color}.`); + } +} +for (const required of [ + '--color-canvas', + '--color-text', + '--color-action-primary', + '--color-focus', +]) { + if (!implementationCss.includes(required)) errors.push(`Missing semantic token ${required}.`); +} + +if (errors.length > 0) fail(errors); +else + pass( + 'Phase 9 semantic tokens are unchanged and application styles contain no raw palette colors.', + ); diff --git a/src/app/[locale]/[slug]/page.tsx b/src/app/[locale]/[slug]/page.tsx new file mode 100644 index 0000000..912bb8e --- /dev/null +++ b/src/app/[locale]/[slug]/page.tsx @@ -0,0 +1,70 @@ +import { StateAction, StateActions, StateShell } from '@/components/app-shell/StateShell'; +import { + isLocale, + localizedPath, + routeIdFromSlug, + type Locale, + type RouteId, +} from '@/lib/localization/config'; +import { getMessages, type ShellMessages } from '@/lib/localization/messages'; +import { buildLocalizedMetadata } from '@/lib/metadata/build-metadata'; +import type { Metadata } from 'next'; +import { notFound } from 'next/navigation'; + +interface PendingRouteProps { + params: Promise<{ locale: string; slug: string }>; +} + +function routeLabel(messages: ShellMessages, routeId: RouteId): string { + const labels = messages.footer.links; + switch (routeId) { + case 'login': + return labels.login; + case 'privacy': + return labels.privacy; + case 'terms': + return labels.terms; + case 'accessibility': + return labels.accessibility; + case 'home': + return 'RentalDriveGo'; + } +} + +async function resolveParams(params: PendingRouteProps['params']) { + const { locale: localeValue, slug } = await params; + if (!isLocale(localeValue)) notFound(); + const routeId = routeIdFromSlug(localeValue, slug); + if (!routeId || routeId === 'home') notFound(); + return { locale: localeValue as Locale, routeId }; +} + +export async function generateMetadata({ params }: PendingRouteProps): Promise { + const { locale, routeId } = await resolveParams(params); + const messages = getMessages(locale).shell; + const label = routeLabel(messages, routeId); + return buildLocalizedMetadata({ + locale, + routeId, + title: `${label} | ${messages.metadata.pendingTitle}`, + description: messages.metadata.pendingDescription, + indexable: false, + }); +} + +export default async function PendingRoute({ params }: PendingRouteProps) { + const { locale, routeId } = await resolveParams(params); + const messages = getMessages(locale).shell; + const label = routeLabel(messages, routeId); + + return ( + + + {messages.states.backHome} + + + ); +} diff --git a/src/app/[locale]/component-lab/ComponentLabInteractive.tsx b/src/app/[locale]/component-lab/ComponentLabInteractive.tsx new file mode 100644 index 0000000..1cba5e1 --- /dev/null +++ b/src/app/[locale]/component-lab/ComponentLabInteractive.tsx @@ -0,0 +1,96 @@ +'use client'; + +import { Button } from '@/components/actions/Button'; +import { Accordion } from '@/components/controls/Accordion'; +import { SegmentedControl } from '@/components/controls/SegmentedControl'; +import { Tabs } from '@/components/controls/Tabs'; +import { Alert } from '@/components/feedback/Alert'; +import { Checkbox, Switch } from '@/components/forms/ChoiceControls'; +import { FormField } from '@/components/forms/FormField'; +import { TextInput } from '@/components/forms/TextInput'; +import { DropdownMenu } from '@/components/overlays/DropdownMenu'; +import { Dialog } from '@/components/overlays/Dialog'; +import type { ComponentLabCopy } from '@/content/development/component-lab'; +import { useRef, useState } from 'react'; +import styles from './page.module.css'; + +export function ComponentLabInteractive({ copy }: { copy: ComponentLabCopy }) { + const [dialogOpen, setDialogOpen] = useState(false); + const [segment, setSegment] = useState('comfortable'); + const triggerRef = useRef(null); + return ( +
+
+

Actions

+
+ + + + + + undefined }, + { + id: 'archive', + label: copy.menu.second, + onSelect: () => undefined, + destructive: true, + }, + ]} + /> +
+
+
+

Form controls

+ + + + + + +
+
+

Selection and disclosure

+ + +
+ + {copy.alert.body} + + +

{copy.dialog.content}

+
+
+ ); +} diff --git a/src/app/[locale]/component-lab/page.module.css b/src/app/[locale]/component-lab/page.module.css new file mode 100644 index 0000000..52517f5 --- /dev/null +++ b/src/app/[locale]/component-lab/page.module.css @@ -0,0 +1,32 @@ +.main { + min-block-size: 100dvh; +} +.interactiveGrid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: var(--space-6); +} +.group { + display: grid; + align-content: start; + gap: var(--space-4); + min-inline-size: 0; + padding: var(--space-6); + border: 1px solid var(--border-standard); + border-radius: var(--radius-md); + background: var(--surface-elevated); +} +.group h2 { + margin: 0; + font-size: var(--type-heading-3-size); +} +.cluster { + display: flex; + flex-wrap: wrap; + gap: var(--space-3); +} +@media (max-width: 767px) { + .interactiveGrid { + grid-template-columns: 1fr; + } +} diff --git a/src/app/[locale]/component-lab/page.tsx b/src/app/[locale]/component-lab/page.tsx new file mode 100644 index 0000000..120134c --- /dev/null +++ b/src/app/[locale]/component-lab/page.tsx @@ -0,0 +1,81 @@ +import { Container, Section, Stack } from '@/components/layout/LayoutPrimitives'; +import { Comparison } from '@/components/marketing/Comparison'; +import { CTA } from '@/components/marketing/CTA'; +import { Metric } from '@/components/marketing/Evidence'; +import { ProductPreview } from '@/components/marketing/ProductPreview'; +import { SectionHeader } from '@/components/marketing/SectionHeader'; +import { Workflow } from '@/components/marketing/Workflow'; +import { getComponentLabCopy } from '@/content/development/component-lab'; +import { isLocale, type Locale } from '@/lib/localization/config'; +import { notFound } from 'next/navigation'; +import { ComponentLabInteractive } from './ComponentLabInteractive'; +import styles from './page.module.css'; + +export const metadata = { robots: { index: false, follow: false } }; + +export default async function ComponentLabPage({ + params, +}: { + params: Promise<{ locale: string }>; +}) { + if (process.env.COMPONENT_FIXTURES_ENABLED !== 'true') notFound(); + const { locale } = await params; + if (!isLocale(locale)) notFound(); + const resolvedLocale: Locale = locale; + const copy = getComponentLabCopy(resolvedLocale); + return ( +
+
+ + + + + + + ({ + ...row, + statusTone: index === 0 ? 'success' : 'warning', + }))} + /> + + + + +
+
+ ); +} diff --git a/src/app/[locale]/error.tsx b/src/app/[locale]/error.tsx new file mode 100644 index 0000000..d516598 --- /dev/null +++ b/src/app/[locale]/error.tsx @@ -0,0 +1,23 @@ +'use client'; + +import { StateButton, StateActions, StateShell } from '@/components/app-shell/StateShell'; +import { getClientShellMessages } from '@/lib/localization/client-messages'; +import { useParams } from 'next/navigation'; + +export default function ErrorPage({ + reset, +}: { + error: Error & { digest?: string }; + reset: () => void; +}) { + const params = useParams<{ locale?: string }>(); + const messages = getClientShellMessages(params?.locale); + + return ( + + + {messages.states.retry} + + + ); +} diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx new file mode 100644 index 0000000..a29865d --- /dev/null +++ b/src/app/[locale]/layout.tsx @@ -0,0 +1,70 @@ +import '@fontsource-variable/inter/index.css'; +import '@fontsource-variable/noto-sans-arabic/index.css'; +import '@/styles/tokens.css'; +import '@/styles/component-tokens.css'; +import '@/styles/globals.css'; + +import { SiteFooter } from '@/components/app-shell/SiteFooter'; +import { SiteHeader } from '@/components/app-shell/SiteHeader'; +import { ThemeController } from '@/components/app-shell/ThemeController'; +import { getDirection, isLocale, type Locale } from '@/lib/localization/config'; +import { getMessages } from '@/lib/localization/messages'; +import { themeBootstrapScript } from '@/lib/theme/bootstrap-script'; +import { + isThemePreference, + serverResolvedTheme, + themeCookie, + type ThemePreference, +} from '@/lib/theme/config'; +import { cookies, headers } from 'next/headers'; +import { notFound } from 'next/navigation'; +import type { ReactNode } from 'react'; + +export const dynamic = 'force-dynamic'; + +interface LocaleLayoutProps { + children: ReactNode; + params: Promise<{ locale: string }>; +} + +export default async function LocaleLayout({ children, params }: LocaleLayoutProps) { + const { locale: localeValue } = await params; + if (!isLocale(localeValue)) notFound(); + const locale: Locale = localeValue; + const messages = getMessages(locale); + const requestHeaders = await headers(); + const nonce = requestHeaders.get('x-nonce') ?? undefined; + const cookieStore = await cookies(); + const cookiePreference = cookieStore.get(themeCookie)?.value; + const preference: ThemePreference = isThemePreference(cookiePreference) + ? cookiePreference + : 'system'; + const resolvedTheme = serverResolvedTheme(preference); + + return ( + + +