Goal
Make every visible string come from the dictionary, every layout RTL-clean, every responsive breakpoint verified, and flip the default locale to Arabic per the global rule.
Scope
B.1 Dictionary infra
B.2 Translation coverage
B.3 Locale-aware formatting
B.4 RTL polish
B.5 Responsiveness + touch targets
Verification
Out of scope
- Modular dictionary split (defer; current monolithic dict is tractable)
- Full WCAG audit (Phase D)
Refs #5
Goal
Make every visible string come from the dictionary, every layout RTL-clean, every responsive breakpoint verified, and flip the default locale to Arabic per the global rule.
Scope
B.1 Dictionary infra
useDictionary()(clone hogwarts pattern — current version throws when no provider mounted, blocking client components in dictionary-less subtrees)src/components/internationalization/middleware.ts, keep onlysrc/proxy.tsen→arinsrc/components/internationalization/config.ts<link rel="alternate" hreflang="..." />in[lang]/layout.tsxheadB.2 Translation coverage
lang === 'ar' ? ... : ...ternariesuseDictionary()/getDictionary()transport/page.tsx,home-content.tsx,host/page.tsx, alltransport-host/[id]/*editors,(nondashboard)/searching/[id]/new-page.tsx,transport/booking/checkout/content.tsxB.3 Locale-aware formatting
toLocaleDateString()/toLocaleString()withformatDate(date, lang)etc. fromsrc/lib/i18n/formatters.tsB.4 RTL polish
ChevronLeft/ChevronRight/ArrowLeft/ArrowRight) —DirectionAwareIconhelper that flips viartl:rotate-180B.5 Responsiveness + touch targets
HeartButtonand the report-issue trigger in 44×44 hit areasVerification
scripts/i18n-anti-pattern-check.shgreps for inline ternaries / hardcoded JSX / rawtoLocaleDateString(); exits non-zero if any foundpnpm i18n:checkscript wires it uppre-commitrunspnpm i18n:checktests/e2e/seo.spec.tsextended to assert<html lang="ar" dir="rtl">on/ar/*and<html lang="en" dir="ltr">on/en/*Out of scope
Refs #5