diff --git a/.agents/context/content-i18n.md b/.agents/context/content-i18n.md new file mode 100644 index 0000000..746be5d --- /dev/null +++ b/.agents/context/content-i18n.md @@ -0,0 +1,40 @@ +# Context: full-guide language switching + +## Decision + +The Astro full guide keeps the current client-side language switch on its +existing `/full-guide/` URL. It server-renders both locale variants and the +language-toggle island shows the selected variant after `client:idle` hydration. + +This deliberately preserves the current no-URL-change contract, including links +shared without a locale segment, and avoids a route/redirect and publishing +change. The cost is duplicated localized HTML and both locales in the response. +That is acceptable for this small guide and avoids sending duplicated string +data through every interactive island. + +## Markup and island contract for task 15d + +- Render each static localized fragment twice. Put `data-language-content="en"` + or `data-language-content="pt"` on its outer element. English is visible in + server HTML; the toggle uses the native `hidden` attribute for the inactive + locale. +- Add `` to the guide top bar. Astro's `client:idle` directive + is only valid for framework components; this `.astro` island defers its + browser setup with `requestIdleCallback` (and a timeout fallback) instead. Do + not hydrate the page or use `client:load`; the control is deliberately + idle-priority. +- The island owns the `ai-for-dummies-language` localStorage key. Every read and + write remains inside `try`/`catch`, because previews may disable storage. +- On each selection the island sets `` to `en` or `pt-BR`, updates + its `[data-lang]` buttons' `.active` class and `aria-pressed` state, updates + `[data-language-content]`, then dispatches `ai-for-dummies:languagechange` on + `window`. The event detail is `{ language: 'en' | 'pt' }`. +- The guide selector island (15a) must read `document.documentElement.lang` when + it hydrates and listen for that event. On receipt it must re-render the + currently active phase and all active selector panels from their collection + data. This preserves today’s `applyLanguage` behaviour without coupling the + toggle to page selectors. + +This is a page-local contract: the existing `/rules/` toggle continues using its +own `rules-language` key and must not be changed as part of full-guide +migration. diff --git a/src/components/islands/GuideSelector.astro b/src/components/islands/GuideSelector.astro new file mode 100644 index 0000000..1c2dc67 --- /dev/null +++ b/src/components/islands/GuideSelector.astro @@ -0,0 +1,294 @@ +--- +// GuideSelector — one client:visible controller for the nine independent +// selectors on /full-guide/. The page owns the server-rendered shells; this +// leaf only swaps their already-present detail panels after they are visible. + +interface Localized { + en: string; + pt: string; +} +interface GuideSelectorData { + phases: Record; + workers: Record; + trees: Record; + routes: Record; + providers: Record< + string, + { + label: string; + source: string; + title: Localized; + copy: Localized; + tiers: [string, string, Localized][]; + config: string; + } + >; + efforts: Record; + skillFiles: Record; + skillWorkflow: Record< + string, + { + number: string; + title: Localized; + question: Localized; + action: Localized; + output: Localized; + proof: Localized; + } + >; + commonSkills: Record< + string, + { + number: string; + kind: Localized; + title: string; + rule: Localized; + use: Localized; + example: Localized; + caution: Localized; + source: string; + } + >; + labels: { + context: Localized; + owner: Localized; + reasoningLoad: Localized; + officialSource: Localized; + skillFileHint: Localized; + workflow: { question: Localized; action: Localized; artifact: Localized; proof: Localized }; + commonSkill: { + whenToUse: Localized; + example: Localized; + watchOut: Localized; + source: Localized; + }; + }; +} +interface Props { + /** The page root that contains the nine static selector shells. */ + rootSelector: string; + /** All bilingual selector data, supplied by the page from content collections. */ + data: GuideSelectorData; +} +const { rootSelector, data } = Astro.props; +--- + + + + + + + diff --git a/src/components/islands/LanguageToggle.astro b/src/components/islands/LanguageToggle.astro new file mode 100644 index 0000000..f44f7fa --- /dev/null +++ b/src/components/islands/LanguageToggle.astro @@ -0,0 +1,68 @@ +--- +// LanguageToggle — idle-hydrated, full-guide-only locale control. +// +// The guide server-renders both locales. This leaf owns the persisted locale +// and announces changes so selector islands can rebuild their active panels +// from collection data without knowing about this control's markup. +--- + +
+ + / + +
+ +