Repository navigation
fix(frontend): declare Vuetify cascade layer order before the split CSS chunks - #1
Conversation
…SS chunks Vuetify 4 (Netflix#326) puts every style in a cascade layer, and the browser ranks layers by first appearance. The production index.html links Vite's split CSS chunks (VApp-*.css, VContainer-*.css, router-*.css) before index-*.css, and those chunks open `@layer vuetify-components` first, so `vuetify-core` lands above it. The `* { padding: 0; margin: 0 }` reset that vuetify-md2-compat.css restores into `vuetify-core.reset` then beats every component rule: v-main loses its app-bar and drawer offsets, so the page renders under the toolbar and the navigation drawer, and cards lose their title padding. Every layout is affected, the dashboard is just where it shows most. Declare the order Vuetify documents in an inline <style> at the top of <head>, before any stylesheet, so first appearance no longer depends on how Vite orders the chunks. Verified on a production image: .v-main padding goes from 0 to 64px top / 440px left and v-card-title padding returns. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
The fix is correct and verified, but the inline block is placed ahead of <meta charset>, an avoidable best-practice/robustness deviation that should be addressed before approval.
1 open issue
What changed in this PR
This PR fixes a layout regression introduced by the Vuetify 3 → 4 upgrade. In Vuetify 4 all styles live in CSS cascade layers, and the browser ranks layers by the order their names first appear. Because Vite's split CSS chunks (VApp-*.css, VContainer-*.css, …) open @layer vuetify-components before index-*.css names vuetify-core, vuetify-core wrongly outranked vuetify-components. That let the * { padding: 0; margin: 0 } reset (restored into vuetify-core.reset by vuetify-md2-compat.css) beat component rules, stripping .v-main of its app-bar/drawer offsets and cards of their padding. The fix pins the layer order up-front via an inline <style> at the top of <head>.
Changes:
- Add an inline
<style>block declaring@layer vuetify-core, vuetify-components, vuetify-overrides, vuetify-utilities, vuetify-final;before any stylesheet, matching Vuetify's documented order. - Add an explanatory comment documenting the root cause and rationale.
| File | Description |
|---|---|
| src/dispatch/static/dispatch/index.html | Declares the Vuetify cascade-layer order inline at the top of <head> so layer priority is deterministic regardless of Vite's chunk ordering; adds a comment explaining the fix. |
Review effort: Balanced
…he meta tags Review feedback on #1: the layer-order block only has to precede the stylesheets Vite injects, not the meta tags, and the HTML spec wants the charset declaration within the first 1024 bytes. Move the block below the three meta tags so the charset stays the first element in <head>. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Problem
Since the Vuetify 3 → 4 bump (Jamyn/dispatch#326) every page renders under the app bar and the navigation drawer, and cards lose their internal padding. Dashboards show it most, but
.v-mainis wrong on every layout.Cause
Vuetify 4 puts all of its styles in cascade layers, and the browser ranks layers by first appearance. The built
index.htmllinks Vite's split CSS chunks (VApp-*.css,VContainer-*.css,router-*.css, …) beforeindex-*.css, and those chunks open@layer vuetify-componentsfirst, sovuetify-coreends up above it. The* { padding: 0; margin: 0 }reset thatvuetify-md2-compat.cssrestores intovuetify-core.resetthen outranks every component rule. On.v-mainexactly two rules set padding,.v-main { padding: var(--v-layout-*) }and that*reset, and the reset wins.Fix
Declare the layer order Vuetify documents in an inline
<style>at the top of<head>, before any stylesheet, so the ranking no longer depends on how Vite orders the chunks. This is the pattern the Vuetify upgrade guide describes (vuetifyjs/vuetify#22848).Verification
Measured on the production image (
docker/Dockerfile, sample data loaded) with headless Chrome and the CDP matched-styles API:.v-mainpadding-top / padding-left.v-card-titlepadding🤖 Generated with Claude Code