Skip to content

feat(home): add FAQ accordion component with JSON-LD schema#3821

Merged
PierreBrisorgueil merged 7 commits intomasterfrom
feat/home-faq-component
Mar 31, 2026
Merged

feat(home): add FAQ accordion component with JSON-LD schema#3821
PierreBrisorgueil merged 7 commits intomasterfrom
feat/home-faq-component

Conversation

@PierreBrisorgueil
Copy link
Copy Markdown
Collaborator

@PierreBrisorgueil PierreBrisorgueil commented Mar 31, 2026

Summary

  • Add HomeFaqComponent — an accordion FAQ section using Vuetify v-expansion-panels with flat/elevation-0 cards, v-fade-transition toggle icons, and homeContentComponent for markdown answers
  • JSON-LD FAQPage schema injected via useHead for SEO; prefers-reduced-motion handling via dynamic <style> tag; 1 or 2-column layout driven by setup.columns
  • Register and conditionally render in home.view.vue consistent with all other home sections
  • Add config example with full documentation in home.development.config.js
  • Add "CSS last resort" ordering rule to /ui skill

Closes #3819

Scope

  • Modules impacted: home
  • Cross-module impact: none
  • Risk level: low

Validation

  • npm run lint
  • npm run test:unit
  • npm run build
  • Manual checks done (if applicable)

Guardrails check

  • No secrets or credentials introduced (.env*, secrets/**, keys, tokens)
  • No risky rename/move of core stack paths
  • Changes remain merge-friendly for downstream projects
  • Tests added or updated when behavior changed

Notes for reviewers

  • E2E tests skipped (Vue dev server not running locally) — all 744 unit tests pass, build clean
  • Component follows exact same pattern as home.statistics.component.vue and other home sections
  • prefers-reduced-motion CSS injection is guarded by window.matchMedia check for SSR safety

Summary by CodeRabbit

  • New Features

    • Added a configurable home-page FAQ section with accordion layout, optional one- or two-column mode, subtitle support, variant/background options, alignment/overlap controls, reduced‑motion accessibility handling, and automatic FAQ structured-data injection for search visibility. Component renders conditionally via site config.
  • Documentation

    • Updated UI design-system guidance with a “CSS last resort” styling priority and an anti‑pattern discouraging custom CSS when framework props/classes/transitions suffice.

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
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 31, 2026

Warning

Rate limit exceeded

@PierreBrisorgueil has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 12 minutes and 18 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 324ad63d-0725-41bb-a9d0-c6b986f05a9d

📥 Commits

Reviewing files that changed from the base of the PR and between c14dbb0 and 5c4a37a.

📒 Files selected for processing (1)
  • src/modules/home/components/home.faq.component.vue

Walkthrough

Adds 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

Cohort / File(s) Summary
FAQ Component Implementation
src/modules/home/components/home.faq.component.vue
New Vue SFC HomeFaqComponent: renders a v-expansion-panels accordion, supports responsive 1–2 column layout, renders markdown answers, applies theme-aware inline styles, injects JSON-LD FAQPage via useHead, and toggles reduced-motion behavior by injecting/removing a client-side style element.
FAQ Configuration
src/modules/home/config/home.development.config.js
Added faq section config with icon, title, subtitle, alignment, variant, columns, overlap, placeholder style.section/style.card, and content array of { question, answer }.
View Registration
src/modules/home/views/home.view.vue
Registered and conditionally renders <homeFaqComponent :setup="config.home.faq" /> when config.home.faq exists.
Design System Guidance
.claude/skills/ui/SKILL.md
Added “CSS last resort” rule to Key rules and matching Anti-pattern: prefer Vuetify component props, then Vuetify utility classes, then Vuetify transitions, and only fall back to scoped/custom CSS when no Vuetify alternative exists.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a FAQ accordion component with JSON-LD schema support for SEO.
Description check ✅ Passed The description comprehensively covers all required sections: Summary, Scope, Validation checklist (completed), Guardrails check (completed), and helpful notes for reviewers.
Linked Issues check ✅ Passed The PR fully addresses all requirements from issue #3819: accordion FAQ component, JSON-LD FAQPage schema, markdown support, responsive design, prefers-reduced-motion handling, and proper registration in home.view.vue.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the FAQ feature: new component, config example, view registration, and documentation update to UI skill. No unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/home-faq-component

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 31, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.23%. Comparing base (0f06402) to head (5c4a37a).
⚠️ Report is 3 commits behind head on master.

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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@PierreBrisorgueil PierreBrisorgueil marked this pull request as ready for review March 31, 2026 11:07
Copilot AI review requested due to automatic review settings March 31, 2026 11:07
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.vue when config.home.faq is present.
  • Documents the new home.faq config block in home.development.config.js and 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.

Comment thread src/modules/home/components/home.faq.component.vue Outdated
Comment thread src/modules/home/components/home.faq.component.vue Outdated
Comment thread src/modules/home/components/home.faq.component.vue
Comment thread src/modules/home/components/home.faq.component.vue Outdated
Comment thread src/modules/home/components/home.faq.component.vue Outdated
Comment thread src/modules/home/components/home.faq.component.vue
Comment thread src/modules/home/config/home.development.config.js Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5a94d6c and af5ba74.

📒 Files selected for processing (4)
  • .claude/skills/ui/SKILL.md
  • src/modules/home/components/home.faq.component.vue
  • src/modules/home/config/home.development.config.js
  • src/modules/home/views/home.view.vue

Comment thread src/modules/home/components/home.faq.component.vue Outdated
Comment thread src/modules/home/components/home.faq.component.vue Outdated
Comment thread src/modules/home/config/home.development.config.js Outdated
- 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
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between af5ba74 and 57cc9c3.

📒 Files selected for processing (2)
  • src/modules/home/components/home.faq.component.vue
  • src/modules/home/config/home.development.config.js

Comment thread src/modules/home/components/home.faq.component.vue
Comment thread src/modules/home/components/home.faq.component.vue
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').
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 57cc9c3 and 8878e42.

📒 Files selected for processing (1)
  • src/modules/home/components/home.faq.component.vue

Comment thread src/modules/home/components/home.faq.component.vue Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 8878e42 and 57eb4c6.

📒 Files selected for processing (1)
  • src/modules/home/components/home.faq.component.vue

Comment thread src/modules/home/components/home.faq.component.vue
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 57eb4c6 and d2bdb25.

📒 Files selected for processing (1)
  • src/modules/home/components/home.faq.component.vue

Comment thread src/modules/home/components/home.faq.component.vue Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between d2bdb25 and c14dbb0.

📒 Files selected for processing (1)
  • src/modules/home/components/home.faq.component.vue

Comment thread src/modules/home/components/home.faq.component.vue
@PierreBrisorgueil PierreBrisorgueil merged commit 444e62c into master Mar 31, 2026
6 checks passed
PierreBrisorgueil pushed a commit that referenced this pull request Apr 1, 2026
# [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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(home): add FAQ accordion component

2 participants