From 6ec1e31ec529cad14e9543e904b6e735ee6edbbe Mon Sep 17 00:00:00 2001 From: Marcos Paulo Date: Sat, 5 Sep 2026 17:44:20 +0000 Subject: [PATCH 1/2] feat(guide): add shared selector island Add one client-visible controller for the nine full-guide selectors. Keep static shells and page migration out of scope. --- src/components/islands/GuideSelector.astro | 283 +++++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 src/components/islands/GuideSelector.astro diff --git a/src/components/islands/GuideSelector.astro b/src/components/islands/GuideSelector.astro new file mode 100644 index 0000000..42e4528 --- /dev/null +++ b/src/components/islands/GuideSelector.astro @@ -0,0 +1,283 @@ +--- +// 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; +--- + + + + + + + From 7a1211ac5f9db98bfe25866cb3e35b0cc7e29254 Mon Sep 17 00:00:00 2001 From: Marcos Paulo Date: Sat, 5 Sep 2026 17:50:48 +0000 Subject: [PATCH 2/2] fix(guide): match 15c event name and the legacy focus ring The island listened for `ai-for-dummies:language-change` on `document`, but task 15c dispatches `ai-for-dummies:languagechange` on `window`. Window events do not reach a document listener, so that path was dead; only the `` MutationObserver was firing. The focus ring was `3px solid var(--red)` at `outline-offset: 2px`, applied globally to every button on the page. `responsive.css` uses gold at offset -3px for exactly these nine groups. Restored, and scoped to them. --- src/components/islands/GuideSelector.astro | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/components/islands/GuideSelector.astro b/src/components/islands/GuideSelector.astro index 42e4528..1c2dc67 100644 --- a/src/components/islands/GuideSelector.astro +++ b/src/components/islands/GuideSelector.astro @@ -260,7 +260,7 @@ const { rootSelector, data } = Astro.props; new MutationObserver((changes) => { if (changes.some((change) => change.attributeName === 'lang')) renderAll(); }).observe(document.documentElement, { attributes: true, attributeFilter: ['lang'] }); - document.addEventListener('ai-for-dummies:language-change', renderAll); + window.addEventListener('ai-for-dummies:languagechange', renderAll); renderAll(); } if ('IntersectionObserver' in window) { @@ -276,8 +276,19 @@ const { rootSelector, data } = Astro.props;