Per RFC-WS-PRIMEVUE-PLAN-2-5 §4 AD-2.5-D1 and §5.6 Fix 6. Single class
on <html> drives both PrimeVue darkModeSelector and Tailwind v4
@custom-variant dark — one toggle, two ecosystems react.
Audit findings (pre-change):
- applyDomAttributes was writing BOTH data-theme="dark" AND .dark on
documentElement. The historic data-theme write is the design-doc §4
mechanism that AD-2.5-D1 supersedes; the .dark toggle was already
correct (and is already paired with PrimeVue darkModeSelector: '.dark'
in plugins/primevue/index.ts:31, verified in P1).
- tailwind.css had NO @custom-variant dark directive — Tailwind v4
default is `prefers-color-scheme` (OS-controlled), so utility
`dark:` variants would have ignored the topbar toggle entirely.
- One stray .dark subtree wrapper in AppTopbar.stories.ts:56
(DarkTheme story) — deliberate Storybook isolation per its comment,
but in violation of AD-2.5-D1's single-source-of-truth rule.
Changes:
- useShellUiStore.applyDomAttributes(): removed data-theme write,
kept .dark class toggle on document.documentElement, kept
data-density (P6 wires density-toggle UI; density is an
orthogonal axis and unaffected). File-header comment updated to
cite AD-2.5-D1 + reference the Tailwind & PrimeVue mirror sites.
- assets/styles/tailwind.css: added
`@custom-variant dark (&:where(.dark, .dark *))` so utility
`dark:` classes resolve via the same .dark trigger.
- components-v2/layout/AppTopbar.stories.ts: stripped class="dark"
from the DarkTheme story's render wrapper. Story comment updated
to flag that visual confirmation now comes via parity-batch
Playwright (after Plan 2.5 closes), not Storybook autodocs. A
proper documentElement-mutating decorator is a backlog item.
- stores/__tests__/useShellUiStore.spec.ts: updated the existing
applyDomAttributes assertion to drop the data-theme expectation
(the write is gone); added a new `describe('applyDomAttributes
— dark mode (AD-2.5-D1)', …)` block with 2 specs (class toggle
reactive, no data-theme attribute written).
Re-grep verification — all three return 0 hits:
- stray .dark in v2 (excluding `dark:` utility prefixes)
- data-theme setAttribute calls in stores/
- [data-theme=…] CSS selectors anywhere
Suite delta: 573 → 575 (+2). vue-tsc clean. Scoped ESLint clean.
Note: darkModeSelector: '.dark' was already set in
plugins/primevue/index.ts:31 (verified in P1 audit) — the config
dimension of AD-2.5-D1 was satisfied before this commit; P3 closes
the store-side, Tailwind-side, and stray-class dimensions.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
57 lines
2.1 KiB
CSS
57 lines
2.1 KiB
CSS
/* Tailwind v4 CSS-first entry. Imports the framework and the
|
|
* tailwindcss-primeui plugin (semantic-token utilities that map
|
|
* PrimeVue Aura tokens like {primary.500} to Tailwind classes
|
|
* like bg-primary-500).
|
|
*
|
|
* Per Tailwind v4 with @tailwindcss/vite, the @source directive
|
|
* tells the plugin where to scan template content — we point it at
|
|
* apps/app/src/. Existing Vuetify/Vuexy SCSS stays untouched and is
|
|
* imported separately from main.ts.
|
|
*/
|
|
|
|
@import "tailwindcss";
|
|
@plugin "tailwindcss-primeui";
|
|
@source "../../**/*.{vue,ts,js,tsx,jsx}";
|
|
|
|
/* AD-2.5-D1 (RFC-WS-PRIMEVUE-PLAN-2-5 §4): align Tailwind v4's `dark:`
|
|
* variant to the same `.dark` class on <html> that PrimeVue's
|
|
* darkModeSelector and useShellUiStore.applyDomAttributes use. Without
|
|
* this, Tailwind v4 defaults to `prefers-color-scheme` (OS-controlled),
|
|
* and the explicit toggle in the topbar would update PrimeVue
|
|
* components but leave Tailwind utility classes (e.g. `dark:bg-*`,
|
|
* `dark:text-*`) responding only to the OS — half-broken dark mode.
|
|
*/
|
|
@custom-variant dark (&:where(.dark, .dark *));
|
|
|
|
/* AD-2.5-T1 — typography (RFC-WS-PRIMEVUE-PLAN-2-5).
|
|
*
|
|
* Inter is loaded via @fontsource/inter in main.ts (weights 400/500/600/700,
|
|
* local package, no Google Fonts CDN). The stack falls back to the
|
|
* platform UI sans-family if Inter fails to load.
|
|
*
|
|
* Two declarations are required:
|
|
* 1. The Tailwind v4 `@theme` token `--font-sans` so utility classes
|
|
* (e.g. `font-sans`) resolve to Inter.
|
|
* 2. The cascade-level `html, body { font-family }` so PrimeVue and
|
|
* Vuetify components — which inherit from `body` — render in Inter
|
|
* too. `--crewli-font-family` is the named CSS variable carrying
|
|
* the stack so other consumers can read it without re-declaring.
|
|
*/
|
|
|
|
@theme {
|
|
--font-sans:
|
|
"Inter", system-ui, -apple-system, "Segoe UI", Roboto,
|
|
"Helvetica Neue", Arial, sans-serif;
|
|
}
|
|
|
|
:root {
|
|
--crewli-font-family:
|
|
"Inter", system-ui, -apple-system, "Segoe UI", Roboto,
|
|
"Helvetica Neue", Arial, sans-serif;
|
|
}
|
|
|
|
html,
|
|
body {
|
|
font-family: var(--crewli-font-family);
|
|
}
|