feat(home): add FAQ accordion component with JSON-LD schema#3821
feat(home): add FAQ accordion component with JSON-LD schema#3821PierreBrisorgueil merged 7 commits intomasterfrom
Conversation
Add HomeFaqComponent with v-expansion-panels, prefers-reduced-motion support, JSON-LD FAQPage schema via useHead, 1/2-column layout, and config example. Register in home.view.vue. Add "CSS last resort" rule to /ui skill. Closes #3819
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 12 minutes and 18 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughAdds a config-driven FAQ accordion component to the home page, registers it in the home view, injects JSON-LD FAQ schema, supports markdown answers, responsive 1–2 column layout, dark/light theming, reduced-motion handling, and updates UI guidance to prefer Vuetify props/classes/transitions before custom CSS. Changes
Sequence DiagramsequenceDiagram
participant User as User
participant Component as HomeFaqComponent
participant PrefAPI as PrefersReducedMotion (matchMedia)
participant HeadAPI as useHead
participant Document as Document
participant Vuetify as v-expansion-panels
User->>Component: mount
Component->>PrefAPI: query prefers-reduced-motion
PrefAPI-->>Component: returns preference
alt reduced motion
Component->>Document: inject zero-duration CSS style (client-only)
end
Component->>HeadAPI: provide FAQPage JSON-LD
HeadAPI->>Document: insert head schema
Component->>Vuetify: render accordion items from setup.content
User->>Vuetify: click question
Vuetify-->>User: expand panel and render markdown answer
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3821 +/- ##
=======================================
Coverage 99.23% 99.23%
=======================================
Files 28 28
Lines 910 910
Branches 243 243
=======================================
Hits 903 903
Misses 7 7 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Adds a new Home FAQ accordion section to the Home module, including runtime JSON-LD FAQPage schema injection for SEO and a documented config example.
Changes:
- Adds
HomeFaqComponent(Vuetify expansion panels) with markdown answers and theme-aware styling. - Registers and conditionally renders the FAQ section in
home.view.vuewhenconfig.home.faqis present. - Documents the new
home.faqconfig block inhome.development.config.jsand updates the UI skill guidelines.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
src/modules/home/views/home.view.vue |
Imports/registers/renders the new FAQ section based on config. |
src/modules/home/config/home.development.config.js |
Adds a documented example home.faq config block. |
src/modules/home/components/home.faq.component.vue |
Implements the FAQ accordion UI + JSON-LD injection + reduced-motion handling. |
.claude/skills/ui/SKILL.md |
Adds a “CSS last resort” ordering rule for UI work. |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/modules/home/components/home.faq.component.vue`:
- Around line 138-143: The injected <style> element created when
prefersReducedMotion is true is never removed, causing duplicate tags on
repeated mounts; modify the component to store a reference to the created
element (the one with attribute 'data-faq-reduced-motion') and remove it in the
beforeUnmount lifecycle hook (e.g., call element.remove() or
document.head.removeChild(element)) so the style is cleaned up when the
component is destroyed; ensure this logic is tied to the same creation branch
that sets style.setAttribute('data-faq-reduced-motion', '') so you reliably
locate and remove the exact element.
- Around line 145-163: Move the useHead call out of the created lifecycle and
into the component's setup() function: remove the useHead invocation from
created() and invoke useHead(...) inside setup(), replacing any this.*
references (e.g., this.setup.content) with reactive/computed sources accessible
in setup (create a computed that maps setup.content to the JSON-LD mainEntity if
needed) so the head configuration is initialized in the proper setup context per
`@unhead/vue`.
In `@src/modules/home/config/home.development.config.js`:
- Around line 663-666: Update the inline comment so it correctly documents that
"columns" is a section-level property, not a per-item property: change the
"Content items" list (which currently includes question, answer, columns) to
only list per-item props (question, answer) and add "columns (Number): 1 | 2" to
the section-level props alongside existing section keys like variant and
alignment; reference the existing symbols "columns", "question", "answer",
"variant", and "alignment" to locate and update the comment near the FAQ/section
config.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 11b34c28-21a3-4d98-9f9b-128707017594
📒 Files selected for processing (4)
.claude/skills/ui/SKILL.mdsrc/modules/home/components/home.faq.component.vuesrc/modules/home/config/home.development.config.jssrc/modules/home/views/home.view.vue
- Move useHead to setup() per @unhead/vue Options API docs - Add beforeUnmount cleanup for reduced-motion style tag (memory leak fix) - Use item.question as stable key on v-expansion-panel - Filter empty columns in two-column layout - Add JSDoc to all computed properties - Move `columns` prop doc to section-level in config comments
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/modules/home/components/home.faq.component.vue`:
- Around line 140-147: The sectionStyle computed property currently sets
background: bgColor after spreading style('section', this.setup), which always
overrides any custom background from style('section'); change the order so the
theme-derived bgColor is applied as a fallback by placing it before spreading
the custom style (i.e., build an object that includes background: bgColor and
colorModeStyle first, then spread ...style('section', this.setup) so a
user-defined style.section.background wins), keeping references to sectionStyle,
style('section', this.setup), colorModeStyle, this.variant, and
this.theme.current.colors.* to locate the code.
- Around line 172-178: The cardStyle computed method currently spreads
style('card', this.setup) then unconditionally sets background: cardColor which
overrides any custom background from the style; update cardStyle to merge the
objects so that an existing background returned by style('card', this.setup)
takes precedence—i.e., fetch the base styles via style('card', this.setup),
check if base.background is set, and only apply background: cardColor when
base.background is undefined or falsy, then return the merged style object so
custom backgrounds are preserved.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: a5989252-88f6-4f1d-ad49-60932738179b
📒 Files selected for processing (2)
src/modules/home/components/home.faq.component.vuesrc/modules/home/config/home.development.config.js
JSON.stringify does not escape < by default in V8 — a FAQ answer containing </script> could break out of the script tag. Mirror the seo-inject.js pattern: .replace(/</g, '\\u003c').
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/modules/home/components/home.faq.component.vue`:
- Around line 195-197: The methods block currently exposes the imported helper
"style" (methods: { style }) even though "style" is used directly inside
computed properties and not invoked from the template; remove the "style" entry
from the methods object (or remove the entire methods object if it's empty) so
that "style" is only imported/used where needed and no unused methods are
exported from the component.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 1d04c6f9-c0bd-42d3-9126-dc1efc878672
📒 Files selected for processing (1)
src/modules/home/components/home.faq.component.vue
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/modules/home/components/home.faq.component.vue`:
- Around line 37-42: The v-for on v-expansion-panel uses :key="item.question",
which will break if duplicate questions exist; update the key to a more robust
unique value (e.g., combine the loop index with the question or use a dedicated
id) by changing the v-for/key usage where v-expansion-panel iterates over column
(the item variable) — replace :key="item.question" with a composite key like
:key="`faq-${index}-${item.question}`" or use item.id if available to ensure
stable keys during re-renders.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: a97c4a99-df10-4e52-8692-0360b69302ed
📒 Files selected for processing (1)
src/modules/home/components/home.faq.component.vue
…licate key issues
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/modules/home/components/home.faq.component.vue`:
- Around line 96-103: mainEntity currently maps props.setup.content into
Questions without validating fields, which can produce invalid JSON-LD when
items lack item.question or item.answer; update the generation to first filter
props.setup.content for entries where both question and answer are non-empty
(e.g., drop items with falsy item.question or item.answer) and then map the
filtered list to the Question/Answer shape so only complete FAQ items are
emitted; ensure the code references the same symbols (mainEntity and
props.setup.content) so the change is localized.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: a78078eb-8333-44e7-9f91-319f55c5a0dc
📒 Files selected for processing (1)
src/modules/home/components/home.faq.component.vue
…revent invalid schema
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/modules/home/components/home.faq.component.vue`:
- Around line 154-161: The columns() computed property currently builds columns
directly from this.setup.content and can include items missing question/answer;
update columns() to first filter this.setup.content using the same validation
used for JSON-LD (exclude items without both question and answer) before
splitting into halves or returning a single column so the UI panels match the
schema output; locate the columns() function and apply the filter to
this.setup.content (or the local content variable) prior to calculating half,
cols, and the final returned array.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 701dac00-2a8d-40dd-9d02-81138675dfad
📒 Files selected for processing (1)
src/modules/home/components/home.faq.component.vue
…and JSON-LD consistent
# [1.5.0](v1.4.0...v1.5.0) (2026-04-01) ### Bug Fixes * **analytics:** PostHog api_host bug + identify/group on login ([#3772](#3772)) ([534fdf3](534fdf3)), closes [#3753](#3753) [#3766](#3766) [#3769](#3769) [#3771](#3771) * **auth,admin:** move mailer warning to admin page, fix verify-email routing, align invite button ([0d195c4](0d195c4)) * **auth:** add missing $route.query mock in verifyEmail tests ([b2732f6](b2732f6)) * **auth:** address CodeRabbit review feedback ([1d14b06](1d14b06)) * **auth:** address review feedback from pass 1 ([bd27d2f](bd27d2f)) * **auth:** address review feedback from pass 1 ([a87fdb1](a87fdb1)) * **auth:** address review feedback from pass 2 — prevent form flash on load ([a6afeca](a6afeca)) * **auth:** fix runtime deprecation warnings and add auth view unit tests ([1901dad](1901dad)), closes [#3592](#3592) * **auth:** persist snackbar dismissal on implicit close ([5e464c3](5e464c3)) * **auth:** resolve lint errors and update test mocks for fetchServerConfig ([a642001](a642001)) * **billing:** add store unit tests and fix view import paths ([e370272](e370272)) * **billing:** address CodeRabbit review — guards, tests, JSDoc, price fallback ([f0f6657](f0f6657)) * **billing:** address CodeRabbit review feedback ([b195d2d](b195d2d)) * **billing:** address CodeRabbit review feedback ([8435d1c](8435d1c)) * **billing:** address CodeRabbit review feedback ([4187771](4187771)) * **billing:** address review — tier comparison, graceful failure, tests, naming ([7b00b91](7b00b91)) * **billing:** address review feedback — pricing card, fetch guard, router tests ([34cbda9](34cbda9)) * **billing:** address UI review findings ([b281a8a](b281a8a)) * **billing:** address UI review findings ([ead3eb0](ead3eb0)) * **billing:** address UI review findings ([b2d3897](b2d3897)) * **billing:** address UI review findings ([a756cd9](a756cd9)) * **billing:** align CASL guard subject with backend policy ([7e8287b](7e8287b)) * **billing:** align CASL guard subject with backend policy ([8e9b768](8e9b768)) * **billing:** correct plan field name, add enterprise badge, store cleanup ([#3733](#3733)) ([9b6e30d](9b6e30d)), closes [#3729](#3729) [#3730](#3730) [#3731](#3731) [#3732](#3732) [#3729](#3729) [#3730](#3730) [#3731](#3731) [#3732](#3732) * **billing:** correct test URL assertions to match store checkout URLs ([cd64628](cd64628)) * **billing:** correct view import paths to match lowercase filenames ([e2646dd](e2646dd)) * **billing:** default free plan display + E2E security tests ([#3751](#3751)) ([025534a](025534a)) * **billing:** fix branch coverage and E2E auth guard test ([2864cf7](2864cf7)) * **billing:** fix branch coverage and harden E2E auth test ([7b91edb](7b91edb)) * **billing:** fix error-handling tests and restore CASL guard on /billing route ([bcb15a6](bcb15a6)) * **billing:** fix plan merge — match by planId/name and build price objects ([1c1c765](1c1c765)) * **billing:** gate fetchSubscription behind org check and add missing [@returns](https://github.com/returns) JSDoc ([9dd15a7](9dd15a7)) * **billing:** harden URL validation, test assertions, and error handling ([44d9cc2](44d9cc2)) * **billing:** include canceled query param in checkout cancel URL ([9e28636](9e28636)) * **billing:** propagate errors, add CASL route metadata, rename views ([39343ba](39343ba)) * **billing:** remove duplicate import in E2E test ([02576f5](02576f5)) * **billing:** rename views, fix test assertions, address review feedback ([cb72130](cb72130)) * **billing:** separate checkout error from fetch error in pricing view ([78db8b1](78db8b1)) * **billing:** update store cancel URL to include canceled query param ([ca5f1a3](ca5f1a3)) * **billing:** validate portal URL and catch fetchSubscription rejection ([7534b6c](7534b6c)) * **ci:** ensure coverage thresholds pass with all modules ([8e0c970](8e0c970)), closes [#3710](#3710) * **ci:** remove ARC-specific conditionals from CI.yml ([#3806](#3806)) ([48747f3](48747f3)), closes [#3805](#3805) * **config:** add missing api section to config.test.js ([#3679](#3679)) ([fff9ffc](fff9ffc)), closes [#3676](#3676) * **config:** address review — use lodash-es, drop glob dep, add env warning ([1ec84fa](1ec84fa)) * **config:** address review feedback from pass 1 ([3336f09](3336f09)) * **config:** align app_title default between Dockerfile and hooks/build ([b08dbf3](b08dbf3)) * **config:** backward-compat fallback for sucessColor and improve warning ([1965557](1965557)) * **config:** fail fast when config is missing in production builds ([#3671](#3671)) ([c660ba4](c660ba4)), closes [#3669](#3669) * **config:** generateConfig ignores module env-specific configs ([#3827](#3827)) ([1ffd80e](1ffd80e)), closes [#3826](#3826) * **config:** remove [@desc](https://github.com/desc) tag from deepMerge JSDoc ([7c4b613](7c4b613)) * **config:** remove duplicate vuetify.theme block from app config merge ([5a583a7](5a583a7)) * **config:** remove unused imports and fix typo in generateConfig ([7b0c006](7b0c006)) * **config:** replace _.merge with deepMerge to fix array handling ([4e91025](4e91025)), closes [#3628](#3628) * **config:** skip undefined values and guard against prototype pollution in deepMerge ([ffc574e](ffc574e)) * **config:** use pathToFileURL for cross-platform dynamic imports ([acad44e](acad44e)) * **core:** address review feedback from pass 1 ([0f6e3af](0f6e3af)) * **core:** make datatable generic via fetchAction prop ([e3a4926](e3a4926)), closes [#3596](#3596) * **coverage:** exclude bootstrapper files with 0% coverage from collection ([4dfde5a](4dfde5a)) * **datatable:** increase per page select width to 100px ([#3779](#3779)) ([ff65d6f](ff65d6f)), closes [#3778](#3778) * **docker:** add DEVKIT_NODE_api_port to docker-compose.test.yml ([#3815](#3815)) ([0f06402](0f06402)), closes [#3809](#3809) * **docker:** make docker-compose.test.yml work for downstream projects ([#3790](#3790)) ([838aec1](838aec1)), closes [#3789](#3789) * **docs:** add src/ prefix and use <env> placeholder in merge order table ([5af5d5b](5af5d5b)) * **docs:** mark global env override config files as optional ([7459d0f](7459d0f)) * **e2e:** read ports from project config instead of hardcoding ([#3777](#3777)) ([ec56d20](ec56d20)), closes [#3775](#3775) * **header:** address review feedback from pass 1 ([b05d210](b05d210)) * **home,config:** address review feedback from pass 1 ([709ccbe](709ccbe)) * **home:** add JSDoc for tabs colorMode validator and tabStyle method ([a7fb5e3](a7fb5e3)) * **home:** add JSDoc to created() hook in home.team.view ([7548c15](7548c15)) * **home:** address CodeRabbit review feedback ([9990286](9990286)) * **home:** hero vertical centering, overlap prop, and Vuetify 4 typography migration ([4c26b25](4c26b25)), closes [#3587](#3587) * **home:** pass colorMode to tabs component so forced text color applies to tab items ([50256d8](50256d8)) * **lodash:** use lodash-es imports for proper tree-shaking ([50570cf](50570cf)) * **nav:** fix organizations ghost item icon in sidenav ([bca4237](bca4237)), closes [#3706](#3706) * **pull-request skill:** add consecutive_zero guard and re-check pending review checks ([18c70f8](18c70f8)) * **pull-request skill:** address review feedback — clarity and consistency ([2dd1ce2](2dd1ce2)) * **pull-request skill:** reply and resolve all threads including non-actionable ([ff776c8](ff776c8)) * **security:** harden auth views against XSS and weak validation ([#3735](#3735)) ([c3b844d](c3b844d)) * **seo-inject:** add JSON-LD structured data injection ([#3670](#3670)) ([5b36e5c](5b36e5c)), closes [#3664](#3664) * **seo:** improve heading hierarchy and alt text for accessibility ([#3661](#3661)) ([918f9bd](918f9bd)) * **seo:** puppeteer prerender Docker support + minor plugin fixes ([#3673](#3673)) ([8ac241b](8ac241b)) * **seo:** skip runtime JSON-LD when seo-inject handles schema ([#3677](#3677)) ([#3680](#3680)) ([b0d90ac](b0d90ac)) * **skill:** add merge conflict check in pull-request convergence loop ([ef136ed](ef136ed)), closes [#3707](#3707) * **skill:** address review feedback from pass 1 ([4020b82](4020b82)) * **skill:** handle CHANGES_REQUESTED, UNKNOWN mergeable, and standardize $PR usage ([13cb3cf](13cb3cf)) * **skill:** pull-request skill should ignore stack-level CodeRabbit comments for downstream projects ([97d2cb2](97d2cb2)), closes [#3604](#3604) * **skills:** clarify feature Phase 0 completeness check ([#3773](#3773)) ([8ac6b1b](8ac6b1b)) * **skills:** match coderabbitai[bot] login in monitoring jq filter ([aae850f](aae850f)) * **update-stack:** add concrete gh issue create command and resolution guidance ([6092368](6092368)) * **update-stack:** add downstream-only new files rule to conflict table ([4a15e39](4a15e39)) * **update-stack:** address review feedback from pass 1 ([f7ed820](f7ed820)) * **update-stack:** address review feedback from pass 2 ([2bef8a3](2bef8a3)) * **update-stack:** clarify failure origin criteria in step 3bis ([a71515e](a71515e)) ### Features * add /frontend design skill + migrate Vuetify 3 patterns to V4 ([#3644](#3644)) ([2f2a8ff](2f2a8ff)) * **analytics:** add useFeatureFlag and usePostHog composables ([#3774](#3774)) ([2506a4f](2506a4f)), closes [#3771](#3771) * **auth:** add email verification gate UI for org setup ([999aa60](999aa60)) * **auth:** add password visibility toggle ([#3752](#3752)) ([ea3b0a0](ea3b0a0)), closes [#336](#336) * **auth:** display server-side auth status on signin/signup pages ([0f4276d](0f4276d)) * **billing:** add billing page with plan badge and subscription management ([e9a1fc5](e9a1fc5)), closes [#3715](#3715) * **billing:** add BillingUsageBar component and enhance UpgradePrompt ([#3744](#3744)) ([0e9ca7f](0e9ca7f)) * **billing:** add checkout flow with auth/org guards and Stripe redirect ([ce17d67](ce17d67)), closes [#3714](#3714) * **billing:** add checkout flow with auth/org guards and Stripe redirect ([f762d91](f762d91)), closes [#3714](#3714) * **billing:** add feature gates — composable, upgrade prompt, router guard ([207c022](207c022)), closes [#3716](#3716) * **billing:** add homepage pricing section ([a8ced6d](a8ced6d)), closes [#3717](#3717) * **billing:** add pricing page with plan cards and billing toggle ([abb1d4a](abb1d4a)), closes [#3713](#3713) * **billing:** add pricing page with plan cards and billing toggle ([0881a9f](0881a9f)), closes [#3713](#3713) * **billing:** add useQuota composable for plan-based feature gating ([#3743](#3743)) ([85e2984](85e2984)) * **billing:** move pricing to dedicated page, update topnav ([eaab6f3](eaab6f3)) * **billing:** scaffold billing module with store, router, and views ([7b08b12](7b08b12)), closes [#3712](#3712) * **ci:** skip setup-node and playwright install on self-hosted runner ([#3803](#3803)) ([104d4f8](104d4f8)), closes [#3802](#3802) * **ci:** support configurable runner via RUNNER variable ([#3794](#3794)) ([1151d02](1151d02)), closes [#3792](#3792) * **ci:** use APP_ENV variable for generateConfig in CI ([#3801](#3801)) ([e384c7c](e384c7c)), closes [#3795](#3795) * **config:** migrate WAOS_VUE_* env prefix to DEVKIT_VUE_* ([7ad1a7f](7ad1a7f)), closes [#3614](#3614) * **header:** add float scroll behavior and document all config options ([d1d4891](d1d4891)) * **home:** add dedicated 404 Not Found page ([#3655](#3655)) ([ac73739](ac73739)) * **home:** add FAQ accordion component with JSON-LD schema ([#3821](#3821)) ([444e62c](444e62c)), closes [#3819](#3819) * **nav:** liquid glass sidenav with Apple-style inset mode ([#3737](#3737)) ([8203f2c](8203f2c)) * **pageHeader:** add tabs slot as alternative to icon + title ([#3781](#3781)) ([763d814](763d814)), closes [#3780](#3780) * phase 2 organizations ([#3702](#3702)) ([71c6a5c](71c6a5c)), closes [#3674](#3674) [#3675](#3675) [#3684](#3684) [#3686](#3686) [#3681](#3681) [#3682](#3682) [#3683](#3683) [#3684](#3684) [#3685](#3685) [#3686](#3686) [#3675](#3675) [#3674](#3674) * rename /frontend to /ui, add workflow rules ([#3704](#3704)) ([3d8259e](3d8259e)) * **sentry:** add Sentry error tracking and ErrorBoundary component ([#3788](#3788)) ([b5463d7](b5463d7)), closes [#3787](#3787) * **seo-inject:** add noscript fallback, preconnect hints, and theme-color ([#3663](#3663)) ([261a3a8](261a3a8)) * **seo:** add pre-rendering of home page at build time ([#3660](#3660)) ([39d9414](39d9414)) * **seo:** add seo-static Vite plugin for robots.txt, sitemap.xml, manifest.json ([#3658](#3658)) ([0a50388](0a50388)) * **update-stack:** report upstream issues when verify fails on stack code ([71dbecc](71dbecc)) * **verify:** add coverage enforcement to verify skill ([#3776](#3776)) ([63301f9](63301f9)) ### Performance Improvements * **ci:** optimize GitHub Actions ([#3793](#3793)) ([e31287e](e31287e)), closes [#3791](#3791)
Summary
HomeFaqComponent— an accordion FAQ section using Vuetifyv-expansion-panelswith flat/elevation-0 cards,v-fade-transitiontoggle icons, andhomeContentComponentfor markdown answersFAQPageschema injected viauseHeadfor SEO;prefers-reduced-motionhandling via dynamic<style>tag; 1 or 2-column layout driven bysetup.columnshome.view.vueconsistent with all other home sectionshome.development.config.js/uiskillCloses #3819
Scope
homenonelowValidation
npm run lintnpm run test:unitnpm run buildGuardrails check
.env*,secrets/**, keys, tokens)Notes for reviewers
home.statistics.component.vueand other home sectionsprefers-reduced-motionCSS injection is guarded bywindow.matchMediacheck for SSR safetySummary by CodeRabbit
New Features
Documentation