build(deps): migrate Tailwind CSS v3.4 → v4
Root-fixes the opacity-modifier seed bug behind R10 S0: the theme colors were bare `var(--x)` hex with no <alpha-value>, so `bg-accent/40`, `ring-accent/40`, `border-border/60`, `text-muted/70`, … (~99 sites across 45 files) emitted no CSS rule at all — latent no-ops. v4 implements the opacity modifier via `color-mix`, so the modifier now works with the existing hex vars, no per-scheme token duplication needed. - `npx @tailwindcss/upgrade`: `@tailwind` directives → `@import "tailwindcss"`, JS config → CSS `@theme` (colors, --font-sans, the z-index tokens preserved), classname renames (rounded/shadow/blur scale, outline-none→outline-hidden, ring→ring-2) across 56 files; PostCSS plugin → @tailwindcss/postcss, autoprefixer removed (v4 prefixes for you). - `@theme` → `@theme inline` (load-bearing): the color vars are redefined at runtime under html[data-scheme]/[data-theme]; inline resolves them at the use site so per-scheme opacity tints track the active scheme (the shadcn v4 pattern). - Revert one codemod false-positive: it rewrote the English word "rounded" → "rounded-sm" inside a releaseNotes.ts prose sentence. Gate green: tsc(app+node) / eslint 0-err / prettier / vitest 79 / knip. Verified in-browser: bg-accent/15 now computes a scheme-tracking color at 0.15 alpha across all 6 schemes × 2 themes; the hand-rolled glass border/shadow/ radius/backdrop-filter render unchanged under v4.
This commit is contained in:
@@ -44,7 +44,7 @@ type Frac = { x: number; y: number; w: number; h: number };
|
||||
type Drag = { type: "seek" } | { type: "boundary"; bi: number };
|
||||
|
||||
const numCls =
|
||||
"w-24 rounded-md bg-surface border border-border px-2 py-1 text-sm tabular-nums focus:outline-none focus:ring-2 focus:ring-accent/40";
|
||||
"w-24 rounded-md bg-surface border border-border px-2 py-1 text-sm tabular-nums focus:outline-hidden focus:ring-2 focus:ring-accent/40";
|
||||
const MIN_SEG = 0.1;
|
||||
|
||||
export default function VideoEditor({ job, onClose }: { job: DownloadJob; onClose: () => void }) {
|
||||
@@ -348,7 +348,7 @@ export default function VideoEditor({ job, onClose }: { job: DownloadJob; onClos
|
||||
onPointerDown={(e) => onCropDown(e, "move")}
|
||||
>
|
||||
<div
|
||||
className="absolute -right-1.5 -bottom-1.5 w-4 h-4 rounded-sm bg-accent cursor-nwse-resize"
|
||||
className="absolute -right-1.5 -bottom-1.5 w-4 h-4 rounded-xs bg-accent cursor-nwse-resize"
|
||||
onPointerDown={(e) => onCropDown(e, "resize")}
|
||||
/>
|
||||
</div>
|
||||
@@ -432,7 +432,7 @@ export default function VideoEditor({ job, onClose }: { job: DownloadJob; onClos
|
||||
toggleKeep(s.id);
|
||||
}}
|
||||
className={clsx(
|
||||
"absolute top-1 left-1 p-0.5 rounded bg-black/50 backdrop-blur-sm",
|
||||
"absolute top-1 left-1 p-0.5 rounded-sm bg-black/50 backdrop-blur-xs",
|
||||
s.keep ? "text-accent" : "text-muted",
|
||||
)}
|
||||
title={s.keep ? t("editor.drop") : t("editor.keep")}
|
||||
@@ -449,7 +449,7 @@ export default function VideoEditor({ job, onClose }: { job: DownloadJob; onClos
|
||||
style={{ left: pct(b) }}
|
||||
>
|
||||
<div
|
||||
className="w-1 h-full bg-white/90 cursor-ew-resize rounded"
|
||||
className="w-1 h-full bg-white/90 cursor-ew-resize rounded-sm"
|
||||
onPointerDown={(e) => {
|
||||
e.stopPropagation();
|
||||
setDrag({ type: "boundary", bi });
|
||||
@@ -460,7 +460,7 @@ export default function VideoEditor({ job, onClose }: { job: DownloadJob; onClos
|
||||
e.stopPropagation();
|
||||
deleteBoundary(bi);
|
||||
}}
|
||||
className="absolute -top-0 -right-2 p-0.5 rounded-full bg-black/70 text-muted hover:text-red-400"
|
||||
className="absolute top-0 -right-2 p-0.5 rounded-full bg-black/70 text-muted hover:text-red-400"
|
||||
title={t("editor.removeCut")}
|
||||
>
|
||||
<X className="w-3 h-3" />
|
||||
|
||||
Reference in New Issue
Block a user