feat(nav): liquid glass sidenav with Apple-style inset mode - #3737
Conversation
- Add glass/inset config options to navigation (backward compatible) - Sidenav uses liquidGlassStyle() for glassmorphism effect - Home page fullwidth when glass mode active, modules keep rail padding - Homogenize liquidGlassStyle() defaults: intensity 1, opacity 0.5, variant pill - Remove glowBorder feature (dead code) from helper, components, and tests - Add dark mode outer shadow to liquidGlassStyle() - Align dynamic island, tabs, presentation with same glass params as header - Compact PageHeader margins and module view content rows - Update MIGRATIONS.md with downstream upgrade notes
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3737 +/- ##
==========================================
- Coverage 99.19% 99.18% -0.01%
==========================================
Files 26 26
Lines 866 863 -3
Branches 225 223 -2
==========================================
- Hits 859 856 -3
Misses 7 7 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Warning Rate limit exceeded
⌛ 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)
WalkthroughThis PR adds a liquid-glass navigation mode: updates Changes
Sequence Diagram(s)sequenceDiagram
participant Router
participant App
participant NavComponent
participant ThemeHelper
Note over App,NavComponent: Config includes vuetify.navigation.glass/inset
Router->>App: route change (path, user state)
App->>App: compute mainStyle (checks config, route, logged-in)
App->>NavComponent: render navigation (passes props / uses config)
NavComponent->>ThemeHelper: liquidGlassStyle(options from config + theme)
ThemeHelper-->>NavComponent: style object (background, opacity, shadow, borderRadius)
NavComponent-->>App: navigation DOM with computed styles applied
App-->>Router: page render with adjusted layout/padding
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
🚥 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)
📝 Coding Plan
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 |
There was a problem hiding this comment.
Pull request overview
This PR updates the app’s navigation and related UI surfaces to support an optional “liquid glass” (glassmorphism) mode with an Apple-style inset drawer, while tightening layout spacing and standardizing glass styling via liquidGlassStyle().
Changes:
- Add glass + inset modes to the core navigation drawer and adjust global nav link styling for theme-aware colors.
- Change
liquidGlassStyle()defaults (intensity/opacity/variant) and remove the deadglowBorderfeature, updating related components and tests. - Compact layout spacing across multiple module views (e.g.,
mt-0rows, reducedPageHeadermargins) and document the migration.
Reviewed changes
Copilot reviewed 19 out of 20 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/modules/core/components/core.navigation.component.vue | Adds glass/inset drawer styling driven by config + liquidGlassStyle(). |
| src/modules/app/app.vue | Makes main layout padding conditional for glass overlay mode on home; updates nav link color inheritance. |
| src/modules/app/config/app.development.config.js | Introduces navigation.glass and navigation.inset config flags (dev). |
| src/lib/helpers/theme.js | Updates liquidGlassStyle() defaults and removes glowBorder behavior. |
| src/lib/helpers/tests/theme.unit.tests.js | Updates unit tests for new liquidGlassStyle() defaults and removed glowBorder. |
| src/modules/home/components/utils/home.tabs.component.vue | Aligns tab indicator styling with new liquidGlassStyle() defaults; removes custom glow CSS. |
| src/modules/home/components/utils/home.dynamicIsland.component.vue | Aligns dynamic island styling with new defaults; improves theme-aware text/dot colors. |
| src/modules/home/components/home.hero.component.vue | Removes glowBorder usage and custom border CSS; adjusts glass opacity. |
| src/modules/home/components/home.presentation.component.vue | Explicitly sets variant: 'card'/opacity to preserve non-pill surface styling. |
| src/modules/core/components/core.pageHeader.component.vue | Reduces vertical margins for a more compact header. |
| src/modules//views/.vue (admin/tasks/users/organizations) | Compacts spacing after PageHeader via mt-0. |
| MIGRATIONS.md | Documents the glass nav feature and breaking changes to liquidGlassStyle(). |
| package.json / package-lock.json | Downgrades @tryghost/content-api, affecting lockfile dependency graph. |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/modules/core/components/core.navigation.component.vue (1)
63-87:⚠️ Potential issue | 🟡 MinorApply the same drawer styling to the socials block.
When
config.vuetify.theme.footeris false, the list on Lines 78-85 is now the only append-section list that does not uselistStyle, so it can fall back to Vuetify’s default surface background/colors and visually break both glass and non-glass modes. This block should inherit the same list/background/icon treatment as the other drawer sections.Suggested fix
- <v-list> - <v-list-item v-for="({ icon, label, url }, i) in config.header.socials" :key="i" :href="url"> + <v-list :style="listStyle" nav> + <v-list-item + v-for="({ icon, label, url }, i) in config.header.socials" + :key="i" + :href="url" + :style="{ color: navColor }" + > <template `#prepend`> - <v-icon>{{ icon }}</v-icon> + <v-icon :style="{ color: navColor }">{{ icon }}</v-icon> </template> <v-list-item-title>{{ label }}</v-list-item-title> </v-list-item> </v-list>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/modules/core/components/core.navigation.component.vue` around lines 63 - 87, The socials block should use the same drawer styling as the nav lists: add :style="listStyle" and nav to the <v-list> that renders config.header.socials, keep the v-list-item :href but ensure each social icon uses the same color binding as other items (e.g. set the <v-icon> to use :style="{ color: navColor }" or the same conditional color logic used for nav items) and ensure sizing/props match (size="small" if used elsewhere); update the template rendering config.header.socials (the v-list, v-list-item and v-icon within that block) to mirror the styling seen in the navBottom block (listStyle, nav, icon color, size).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@MIGRATIONS.md`:
- Around line 11-17: Update the migration snippet in MIGRATIONS.md to use the
correct config path `vuetify.theme.navigation` instead of the top-level
`navigation`; change the example object key from `navigation: { ... }` to
`vuetify: { theme: { navigation: { glass: true, inset: true } } }` (or
equivalent structure used by the app) so consumers copy the right configuration
location for `glass` and `inset`.
In `@src/lib/helpers/theme.js`:
- Around line 95-109: The liquidGlassStyle helper currently sets opacity = 0.5
by default which makes the guard checking opacity !== undefined (and the layered
background branch that builds the layered background when opacity is not
provided) unreachable; either revert the default to undefined so callers get the
auto-computed path (set opacity default to undefined in the liquidGlassStyle
signature and leave the opacity !== undefined branch intact) or remove the dead
layered-background branch and update the JSDoc to state opacity is always used
(delete the opacity !== undefined check and the layered background code and
adjust the docs to reflect a required/always-applied opacity). Ensure you update
references to opacity in liquidGlassStyle and the JSDoc comment to keep the API
contract consistent.
In `@src/modules/app/app.vue`:
- Around line 80-90: Add unit tests for the mainStyle computed/method to assert
the route/state-dependent layout behavior: create component tests that mount the
component and verify mainStyle returns a base background style and that when
config.vuetify.theme.navigation.glass is true, isLoggedIn is true, and
$route.path === '/' the returned style includes 'padding-left': '0px', and that
the padding remains unchanged for other permutations (glass false, not logged
in, or different route); target the mainStyle accessor and exercise toggling
config.vuetify.theme.navigation.glass, isLoggedIn, and $route.path in the test
harness so the new behavior is locked down.
In `@src/modules/core/components/core.navigation.component.vue`:
- Around line 8-12: The mobile toggle is still getting translucent/blur styles
when navigation.glass is false; update the inline style and the
glassButtonStyle() computed to make the toggle fully solid: use background:
isGlass ? undefined : navBackground (remove the `${navBackground}99` alpha
suffix) and ensure glassButtonStyle() returns an empty object {} when
navigation.glass/isGlass is false (also remove any blur/backdrop-filter entries
when not glass) so the mobile toggle uses a plain solid background and no
glass-specific CSS.
---
Outside diff comments:
In `@src/modules/core/components/core.navigation.component.vue`:
- Around line 63-87: The socials block should use the same drawer styling as the
nav lists: add :style="listStyle" and nav to the <v-list> that renders
config.header.socials, keep the v-list-item :href but ensure each social icon
uses the same color binding as other items (e.g. set the <v-icon> to use
:style="{ color: navColor }" or the same conditional color logic used for nav
items) and ensure sizing/props match (size="small" if used elsewhere); update
the template rendering config.header.socials (the v-list, v-list-item and v-icon
within that block) to mirror the styling seen in the navBottom block (listStyle,
nav, icon color, size).
🪄 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: 643ce8ee-ebf4-40f7-a7d0-70d92763f112
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (19)
MIGRATIONS.mdpackage.jsonsrc/lib/helpers/tests/theme.unit.tests.jssrc/lib/helpers/theme.jssrc/modules/admin/views/admin.user.view.vuesrc/modules/admin/views/admin.view.vuesrc/modules/app/app.vuesrc/modules/app/config/app.development.config.jssrc/modules/core/components/core.header.component.vuesrc/modules/core/components/core.navigation.component.vuesrc/modules/core/components/core.pageHeader.component.vuesrc/modules/home/components/home.hero.component.vuesrc/modules/home/components/home.presentation.component.vuesrc/modules/home/components/utils/home.dynamicIsland.component.vuesrc/modules/home/components/utils/home.tabs.component.vuesrc/modules/organizations/views/organization.create.view.vuesrc/modules/tasks/views/task.view.vuesrc/modules/tasks/views/tasks.view.vuesrc/modules/users/views/user.view.vue
💤 Files with no reviewable changes (1)
- src/modules/core/components/core.header.component.vue
- Fix config path in MIGRATIONS.md (vuetify.theme.navigation) - Update liquidGlassStyle JSDoc for opacity default - Remove backdrop blur from mobile button in non-glass mode - Add mainStyle unit tests for glass layout behavior
- Test solid background with default opacity - Test zero intensity shadow in light mode
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
MIGRATIONS.md (1)
570-570:⚠️ Potential issue | 🟡 MinorFix broken list numbering.
Line 570 shows "8. Run
npm run lint..." but it's not part of a numbered list context—this appears to be a leftover from a previous edit. Consider removing the number or integrating it into the appropriate list.📝 Suggested fix
-8. Run `npm run lint && npm run test:unit && npm run build` to confirm everything works. +Run `npm run lint && npm run test:unit && npm run build` to confirm everything works.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@MIGRATIONS.md` at line 570, The line containing "Run `npm run lint && npm run test:unit && npm run build`" is incorrectly numbered as "8." outside of any numbered list; remove the leading "8." or reformat the surrounding Markdown so this command is properly part of the intended numbered list (e.g., adjust surrounding list markers to include this step). Locate the exact string "Run `npm run lint && npm run test:unit && npm run build`" in MIGRATIONS.md and either strip the "8. " prefix or insert it into the correct list block so numbering and formatting are consistent.
♻️ Duplicate comments (1)
src/modules/core/components/core.navigation.component.vue (1)
8-12: 🧹 Nitpick | 🔵 TrivialMobile button retains alpha suffix when glass is off.
The prior review noted that
${navBackground}99(Line 10) still applies a translucent background whenisGlassis false. While the critical backdrop blur issue was resolved, this alpha suffix means the toggle isn't fully solid in non-glass mode. If a fully opaque button is desired when glass is off, consider usingnavBackgrounddirectly without the99suffix.♻️ Optional fix for fully solid button
:style="{ color: navColor, - background: isGlass ? undefined : `${navBackground}99`, + background: isGlass ? undefined : navBackground, ...glassButtonStyle, }"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/modules/core/components/core.navigation.component.vue` around lines 8 - 12, The mobile toggle's background uses a hard-coded alpha suffix (`${navBackground}99`) so when isGlass is false the button remains translucent; update the style logic in the component so the background is navBackground (no alpha) when isGlass is false and only append the alpha suffix when isGlass is true (or otherwise desired). Locate the inline style block that references navColor, isGlass, navBackground and glassButtonStyle and change the background expression to choose between navBackground (opaque) and `${navBackground}99` (translucent) based on isGlass.
🤖 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/app/tests/app.vue.unit.tests.js`:
- Around line 75-81: The test titled "removes padding-left on home route when
glass mode is active and logged in" is misleading because the auth mock
(useAuthStore) returns isLoggedIn: false and the assertion only checks
background; either rename the test to reflect what it actually verifies (e.g.,
"sets background color on home route when glass mode inactive/not logged in") or
add a new test that explicitly mocks useAuthStore to return isLoggedIn: true,
re-imports the component if necessary, mounts via mountWithRoute('/') and
asserts wrapper.vm.mainStyle['padding-left'] === 0 to verify the logged-in
glass-mode behavior.
- Around line 55-73: Add a JSDoc block immediately above the mountWithRoute
function describing its purpose and parameters; include `@param` {string} path -
route path to mount the App at, `@param` {Object} [configOverrides] - optional
overrides merged into the default config, and `@returns`
{import('@vue/test-utils').VueWrapper} (or appropriate wrapper type) indicating
the mounted component wrapper; ensure the description mentions it returns a
mounted App wrapper for the given route and config overrides and place the block
directly above the mountWithRoute declaration.
In `@src/modules/core/components/core.navigation.component.vue`:
- Around line 122-127: Move the useTheme() call out of data() into setup(): call
useTheme() inside a setup() function (e.g. setup() { const theme = useTheme();
return { theme }; }) and keep data() as a plain object returning only reactive
state like drawer: true; update any references to theme/drawer to rely on the
returned properties from setup()/data() and ensure the component exports both
setup() and data() (removing theme from the data() return).
---
Outside diff comments:
In `@MIGRATIONS.md`:
- Line 570: The line containing "Run `npm run lint && npm run test:unit && npm
run build`" is incorrectly numbered as "8." outside of any numbered list; remove
the leading "8." or reformat the surrounding Markdown so this command is
properly part of the intended numbered list (e.g., adjust surrounding list
markers to include this step). Locate the exact string "Run `npm run lint && npm
run test:unit && npm run build`" in MIGRATIONS.md and either strip the "8. "
prefix or insert it into the correct list block so numbering and formatting are
consistent.
---
Duplicate comments:
In `@src/modules/core/components/core.navigation.component.vue`:
- Around line 8-12: The mobile toggle's background uses a hard-coded alpha
suffix (`${navBackground}99`) so when isGlass is false the button remains
translucent; update the style logic in the component so the background is
navBackground (no alpha) when isGlass is false and only append the alpha suffix
when isGlass is true (or otherwise desired). Locate the inline style block that
references navColor, isGlass, navBackground and glassButtonStyle and change the
background expression to choose between navBackground (opaque) and
`${navBackground}99` (translucent) based on isGlass.
🪄 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: 7addcd69-5073-43b3-98a8-dd4f6e5d6b59
📒 Files selected for processing (5)
MIGRATIONS.mdsrc/lib/helpers/tests/theme.unit.tests.jssrc/lib/helpers/theme.jssrc/modules/app/tests/app.vue.unit.tests.jssrc/modules/core/components/core.navigation.component.vue
- Add JSDoc to mountWithRoute helper - Fix misleading test name (user is not logged in)
# [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
liquidGlassStyle(), with Apple-style inset floating. Homogenized glass parameters across all components (header, sidenav, dynamic island, tabs, presentation). Removed deadglowBorderfeature. Compacted module layout spacing.Scope
core(navigation, header, pageHeader),app(layout, config),home(hero, dynamic island, tabs, presentation),tasks,admin,users,organizations(view spacing)yes—liquidGlassStyle()defaults changed (intensity 1, opacity 0.5, variant pill),glowBorderparam removed,PageHeadermargins reduced, module view rows usemt-0medium— glass mode is config-gated (glass: false= no change), but default changes toliquidGlassStyle()affect all consumersValidation
npm run lintnpm run test:unitnpm run buildGuardrails check
Optional: Infra/Stack alignment details
Before vs After (key changes only)
#2c3e50backgroundliquidGlassStyle()glass effectnavigation.glass: truenavigation.inset: true/routeliquidGlassStyle()defaultsvariant: 'card'where neededglowBorderparamonPrimaryinheritfrom parentmt-4 mb-2my-1pa-2pa-2 mt-0glass: falseandinset: falsein config for full backward compatibilityNotes for reviewers
liquidGlassStyle()need to check new defaults (see MIGRATIONS.md)Summary by CodeRabbit
New Features
Documentation
Style
Tests