mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
fix(css): repair Tailwind v4 color-mix parser crash on dev server
Tailwind v4's content scanner walks the entire project root by default
and emits a CSS rule for every class-shaped token it finds — including
literal class fragments quoted inside .planning report markdown and
docs/ design specs. The bracketed CSS-variable arbitrary-value form
combined with an opacity modifier (e.g. `bg-[var(--name)]/12`)
generates an escaped selector whose `\(...\)\/N` token sequence
crashes Turbopack's CSS parser with `Unexpected token Delim('.')`,
500-ing every page that imports globals.css.
The crash:
./src/app/globals.css:1853:27
Parsing CSS source code failed
1852 | .bg-\[var\(...\)\]\/12 {
> 1853 | background-color: var(...);
| ^
Three coordinated changes:
- Add `@source not "../../.planning"` and `@source not "../../docs"`
to globals.css so the scanner skips planning + docs trees. Stops
fixture-style class names in research/audit reports from poisoning
the generated CSS.
- Migrate `bg-[var(--dracula-*)]/N` / `ring-[var(--dracula-*)]/N` in
target-card.tsx to the Tailwind v4 parenthesised shorthand
`bg-(--dracula-*)/N` / `ring-(--dracula-*)/N`. The shorthand emits
a clean selector that LightningCSS parses cleanly. Per the Tailwind
v4 upgrade guide, the bracketed form is deprecated for CSS
variables.
- Replace `shadow-[0_0_0_1px_var(--dracula-green)]/20` in
consistency-strip.tsx with `shadow-[0_0_0_1px_color-mix(in_oklab,var(--dracula-green)_20%,transparent)]`.
The arbitrary shadow with opacity modifier hits the same parser
issue; encoding the alpha directly in the value via color-mix
removes the modifier and keeps the visual identical.
Verification: `pnpm dev --port 3030` then `curl -sI /auth/login` ->
HTTP/1.1 200 OK (was 500). Zero CSS parse errors in the dev server
log. Affected tests (targets + api-handler + api/version) still pass
(31/31).
This commit is contained in:
1 parent
53278ccd87
commit
782731aeda
3 files changed
+38
-8
No files matched your search
@@ -2,6 +2,21 @@
|
||||
@import "tw-animate-css";
|
||||
@import "shadcn/tailwind.css";
|
||||
|
||||
/*
|
||||
* Exclude planning + docs directories from Tailwind v4's content scan.
|
||||
*
|
||||
* v4's scanner walks the entire project root by default and picks any
|
||||
* class-shaped token out of every text file. Planning reports and
|
||||
* design docs often quote literal class-name fragments such as
|
||||
* `bg-[var(...)]/12` as examples, and the bracketed-CSS-variable form
|
||||
* combined with an opacity modifier generates an escaped selector that
|
||||
* Turbopack's CSS parser rejects with `Unexpected token Delim('.')`,
|
||||
* 500-ing every page. Constraining the scan to source code avoids
|
||||
* fixture-style strings poisoning the generated CSS.
|
||||
*/
|
||||
@source not "../../.planning";
|
||||
@source not "../../docs";
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
@theme inline {
|
||||
|
||||
@@ -47,10 +47,16 @@ export interface ConsistencyStripProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
// An arbitrary shadow utility with an opacity modifier (a "/20" suffix
|
||||
// on the bracketed value) hits the same Turbopack CSS-parser issue as
|
||||
// the bracket-form CSS-variable utilities — see the comment in
|
||||
// target-card.tsx for the full diagnosis. The shadow's alpha is now
|
||||
// encoded inside the value via color-mix so the opacity modifier is
|
||||
// no longer needed and the bracketed form parses cleanly.
|
||||
const BAND_STYLES: Record<NonNullable<ConsistencyBand>, string> = {
|
||||
in: "bg-[var(--dracula-green)] border-[var(--dracula-green)] shadow-[0_0_0_1px_var(--dracula-green)]/20",
|
||||
near: "bg-[var(--dracula-orange)] border-[var(--dracula-orange)]",
|
||||
out: "bg-[var(--dracula-red)] border-[var(--dracula-red)]",
|
||||
in: "bg-(--dracula-green) border-(--dracula-green) shadow-[0_0_0_1px_color-mix(in_oklab,var(--dracula-green)_20%,transparent)]",
|
||||
near: "bg-(--dracula-orange) border-(--dracula-orange)",
|
||||
out: "bg-(--dracula-red) border-(--dracula-red)",
|
||||
};
|
||||
|
||||
const BAND_ARIA: Record<NonNullable<ConsistencyBand>, string> = {
|
||||
|
||||
@@ -202,10 +202,19 @@ function statusGroupForCategory(category: string): "in" | "near" | "out" {
|
||||
return "near";
|
||||
}
|
||||
|
||||
// Use the Tailwind v4 parenthesised CSS-variable shorthand
|
||||
// (bg-VAR-PAREN-FORM-/N) instead of the legacy bracketed VAR-form. The
|
||||
// bracketed form combined with an opacity modifier emits an escaped
|
||||
// class selector that Turbopack's CSS parser rejects with
|
||||
// "Unexpected token Delim('.')" because the scanner picks the literal
|
||||
// string out of source files (including this comment) and emits a CSS
|
||||
// rule for it. The parenthesised shorthand produces a clean selector
|
||||
// that parses cleanly. See the Tailwind v4 upgrade guide for the
|
||||
// migration from bracket-form to paren-form for CSS-variable values.
|
||||
const STATUS_PILL_STYLES: Record<"in" | "near" | "out", string> = {
|
||||
in: "bg-[var(--dracula-green)]/12 text-[var(--dracula-green)] ring-[var(--dracula-green)]/30",
|
||||
near: "bg-[var(--dracula-orange)]/14 text-[var(--dracula-orange)] ring-[var(--dracula-orange)]/30",
|
||||
out: "bg-[var(--dracula-red)]/12 text-[var(--dracula-red)] ring-[var(--dracula-red)]/30",
|
||||
in: "bg-(--dracula-green)/12 text-(--dracula-green) ring-(--dracula-green)/30",
|
||||
near: "bg-(--dracula-orange)/14 text-(--dracula-orange) ring-(--dracula-orange)/30",
|
||||
out: "bg-(--dracula-red)/12 text-(--dracula-red) ring-(--dracula-red)/30",
|
||||
};
|
||||
|
||||
interface TargetClassification {
|
||||
@@ -611,11 +620,11 @@ export function TargetCard({
|
||||
)}
|
||||
{showStreak && (
|
||||
<span
|
||||
className="text-foreground inline-flex items-center gap-1.5 rounded-full bg-[var(--dracula-green)]/12 px-2 py-0.5 font-medium ring-1 ring-[var(--dracula-green)]/30"
|
||||
className="text-foreground inline-flex items-center gap-1.5 rounded-full bg-(--dracula-green)/12 px-2 py-0.5 font-medium ring-1 ring-(--dracula-green)/30"
|
||||
data-slot="target-streak"
|
||||
>
|
||||
<span
|
||||
className="size-1.5 rounded-full bg-[var(--dracula-green)]"
|
||||
className="size-1.5 rounded-full bg-(--dracula-green)"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
{t("targets.card.streak", { count: String(target.streakDays) })}
|
||||
|
||||
Reference in new issue
Block a user