fix(webapp): migrate to Tailwind CSS 4 to remove vulnerable braces dependency

This commit is contained in:
shuaiplus committed 2026-10-05 14:55:58 +08:00
1 parent 293f5ce196
commit 4c241aa64b
15 files changed
+551 -1102

No files matched your search

-1
View File
@@ -4,7 +4,6 @@ import App from './App';
import { initI18n } from './lib/i18n';
import { registerNodeWardenServiceWorker } from './lib/pwa';
import './tailwind.css';
import './styles.css';
const queryClient = new QueryClient({
defaultOptions: {
+2 -2
View File
@@ -353,7 +353,7 @@
}
.not-found-logo {
@apply h-14 w-14 flex-shrink-0 object-contain;
@apply h-14 w-14 shrink-0 object-contain;
filter: drop-shadow(0 8px 18px rgba(43, 102, 217, 0.22));
}
@@ -465,7 +465,7 @@
}
.standalone-brand-logo {
@apply h-14 w-[70px] flex-shrink-0 object-contain;
@apply h-14 w-[70px] shrink-0 object-contain;
filter: drop-shadow(0 8px 18px rgba(43, 102, 217, 0.22));
}
+1 -1
View File
@@ -19,7 +19,7 @@
}
.input {
@apply h-12 w-full rounded-xl border px-3.5 py-2.5 outline-none;
@apply h-12 w-full rounded-xl border px-3.5 py-2.5 outline-hidden;
background: var(--panel);
border-color: rgba(74, 103, 150, 0.34);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.82);
+15 -4
View File
@@ -802,15 +802,25 @@
}
.yubikey-manage-dialog-body {
@apply mt-3 space-y-4;
@apply mt-3;
}
.yubikey-manage-dialog-body > :not([hidden]) ~ :not([hidden]) {
margin-top: 1rem;
margin-bottom: 0;
}
.settings-plain-steps {
@apply m-0 space-y-1 border-b pb-3 pl-5;
@apply m-0 border-b pb-3 pl-5;
border-color: var(--line);
color: var(--text);
}
.settings-plain-steps > :not([hidden]) ~ :not([hidden]) {
margin-top: 0.25rem;
margin-bottom: 0;
}
.yubikey-input-row {
@apply grid items-center gap-2;
grid-template-columns: minmax(0, 1fr) auto;
@@ -825,8 +835,9 @@
@apply h-9 w-9 p-0;
}
.settings-checkbox-block {
@apply space-y-2;
.settings-checkbox-block > :not([hidden]) ~ :not([hidden]) {
margin-top: 0.5rem;
margin-bottom: 0;
}
.checkbox-inline {
+3 -3
View File
@@ -132,7 +132,7 @@
}
.topbar-actions > .network-status-badge {
@apply inline-flex h-9 w-9 min-w-9 justify-center gap-0 rounded-xl p-0 text-[0];
@apply inline-flex h-9 w-9 min-w-9 justify-center gap-0 rounded-xl p-0 text-[0px];
background: color-mix(in srgb, var(--panel) 88%, transparent);
border-color: var(--line);
box-shadow: none;
@@ -144,7 +144,7 @@
.mobile-sidebar-toggle,
.mobile-lock-btn {
@apply inline-flex h-9 w-9 min-w-9 justify-center gap-0 rounded-xl p-0 text-[0];
@apply inline-flex h-9 w-9 min-w-9 justify-center gap-0 rounded-xl p-0 text-[0px];
background: color-mix(in srgb, var(--panel) 88%, transparent);
border-color: var(--line);
box-shadow: none;
@@ -451,7 +451,7 @@
}
.mobile-fab-trigger {
@apply h-9 w-9 gap-0 rounded-full p-0 text-[0];
@apply h-9 w-9 gap-0 rounded-full p-0 text-[0px];
box-shadow: 0 14px 30px rgba(37, 99, 235, 0.28);
transition: transform 180ms var(--ease-spring), box-shadow var(--dur-fast) var(--ease-out-soft);
}
+15 -4
View File
@@ -31,7 +31,12 @@
}
.skeleton-content {
@apply min-w-0 flex-1 space-y-2;
@apply min-w-0 flex-1;
}
.skeleton-content > :not([hidden]) ~ :not([hidden]) {
margin-top: 0.5rem;
margin-bottom: 0;
}
.skeleton-line {
@@ -63,13 +68,19 @@
}
.skeleton-page {
@apply h-full space-y-4 p-4;
@apply h-full p-4;
}
.skeleton-page > :not([hidden]) ~ :not([hidden]) {
margin-top: 1rem;
margin-bottom: 0;
}
.skeleton-header {
@apply mb-6;
}
.skeleton-body {
@apply space-y-3;
.skeleton-body > :not([hidden]) ~ :not([hidden]) {
margin-top: 0.75rem;
margin-bottom: 0;
}
+3 -3
View File
@@ -55,7 +55,7 @@
}
.search-input {
@apply h-12 w-full rounded-xl border px-3.5 py-2.5 text-base text-ink outline-none transition;
@apply h-12 w-full rounded-xl border px-3.5 py-2.5 text-base text-ink outline-hidden transition;
background: var(--panel);
border-color: rgba(74, 103, 150, 0.34);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.82);
@@ -416,7 +416,7 @@ select.input.duplicate-mode-toolbar-select {
}
.desktop-create-trigger {
@apply h-[34px] w-[34px] min-w-[34px] gap-0 rounded-[10px] p-0 text-[0];
@apply h-[34px] w-[34px] min-w-[34px] gap-0 rounded-[10px] p-0 text-[0px];
}
.desktop-create-trigger .btn-icon {
@@ -586,7 +586,7 @@ select.input.duplicate-mode-toolbar-select {
}
.card-brand-icon {
@apply inline-grid h-6 w-9 shrink-0 place-items-center rounded border text-[7px] font-black uppercase leading-none;
@apply inline-grid h-6 w-9 shrink-0 place-items-center rounded-sm border text-[7px] font-black uppercase leading-none;
letter-spacing: 0;
color: #1e3a8a;
background: linear-gradient(180deg, #ffffff 0%, #f4f7fb 100%);
+71 -3
View File
@@ -1,3 +1,71 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import 'tailwindcss' source(none);
@import './styles.css';
@source '../index.html';
@source './**/*.{ts,tsx}';
@custom-variant dark (&:where([data-theme='dark'], [data-theme='dark'] *));
/* Inline aliases keep utilities tied to the active light/dark design tokens. */
@theme inline {
--color-canvas: var(--bg-accent);
--color-panel: var(--panel);
--color-panel-soft: var(--panel-soft);
--color-panel-muted: var(--panel-muted);
--color-line: var(--line);
--color-line-soft: var(--line-soft);
--color-ink: var(--text);
--color-muted: var(--muted);
--color-muted-strong: var(--muted-strong);
--color-brand: var(--primary);
--color-brand-hover: var(--primary-hover);
--color-brand-strong: var(--primary-strong);
--color-danger: var(--danger);
--shadow-soft: var(--shadow-sm);
--shadow-panel: var(--shadow-md);
--shadow-elevated: var(--shadow-lg);
--font-sans: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', 'Noto Sans SC', sans-serif;
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
/* Preserve utility radii independently of tokens.css's --radius-* names. */
--radius-xs: 0.125rem;
--radius-sm: 0.25rem;
--radius-md: 0.375rem;
--radius-lg: 0.5rem;
--radius-xl: 0.75rem;
--radius-2xl: 1rem;
--radius-3xl: 1.5rem;
/* Keep line heights fixed when component styles override the font size. */
--text-xs--line-height: 1rem;
--text-sm--line-height: 1.25rem;
--text-base--line-height: 1.5rem;
--text-lg--line-height: 1.75rem;
--text-xl--line-height: 1.75rem;
--text-2xl--line-height: 2rem;
--text-3xl--line-height: 2.25rem;
--text-4xl--line-height: 2.5rem;
}
/* Retain the v3 defaults where components do not set their own values. */
@layer base {
*,
::before,
::after,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentColor);
}
input::placeholder,
textarea::placeholder {
color: var(--color-gray-400);
}
button:not(:disabled),
[role='button']:not(:disabled) {
cursor: pointer;
}
}