feat(08-01): define MD3 color tokens and flash prevention script
- Add @custom-variant dark directive for .dark class-based toggling - Define 15 CSS custom property token pairs (light/dark) in @layer base - Map all tokens to Tailwind utility classes via @theme with var() references - Include warning/success tokens (amber + green) for ReviewStep coverage - Add body transition with prefers-reduced-motion guard - Add inline blocking script in index.html head to prevent FOUC
This commit is contained in:
+22
@@ -2,6 +2,28 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
try {
|
||||||
|
var stored = localStorage.getItem('r2b-theme');
|
||||||
|
var effective;
|
||||||
|
if (stored === 'dark') {
|
||||||
|
effective = 'dark';
|
||||||
|
} else if (stored === 'light') {
|
||||||
|
effective = 'light';
|
||||||
|
} else {
|
||||||
|
effective = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||||
|
? 'dark'
|
||||||
|
: 'light';
|
||||||
|
}
|
||||||
|
if (effective === 'dark') {
|
||||||
|
document.documentElement.classList.add('dark');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// localStorage unavailable (private mode, etc.) — leave light as default
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Ready2Blob</title>
|
<title>Ready2Blob</title>
|
||||||
|
|||||||
@@ -1 +1,69 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
/* Override built-in dark variant to use .dark class instead of prefers-color-scheme */
|
||||||
|
@custom-variant dark (&:where(.dark, .dark *));
|
||||||
|
|
||||||
|
/* Raw color values — overridden per theme */
|
||||||
|
@layer base {
|
||||||
|
:root {
|
||||||
|
--r2b-primary: #4338CA; /* indigo-700 */
|
||||||
|
--r2b-on-primary: #FFFFFF;
|
||||||
|
--r2b-surface: #F9FAFB; /* gray-50 */
|
||||||
|
--r2b-on-surface: #111827; /* gray-900 */
|
||||||
|
--r2b-surface-variant: #1F2937; /* gray-800 — code blocks */
|
||||||
|
--r2b-on-surface-variant: #F3F4F6; /* gray-100 — text on code blocks */
|
||||||
|
--r2b-surface-container: #FFFFFF; /* card/form backgrounds */
|
||||||
|
--r2b-on-surface-container: #374151; /* gray-700 — labels, secondary text */
|
||||||
|
--r2b-outline: #D1D5DB; /* gray-300 — borders */
|
||||||
|
--r2b-error: #EF4444; /* red-500 */
|
||||||
|
--r2b-on-error: #FFFFFF;
|
||||||
|
--r2b-success: #15803D; /* green-700 */
|
||||||
|
--r2b-on-success: #F0FDF4; /* green-50 */
|
||||||
|
--r2b-warning: #D97706; /* amber-600 */
|
||||||
|
--r2b-on-warning: #FFFBEB; /* amber-50 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--r2b-primary: #A5B4FC; /* indigo-300 */
|
||||||
|
--r2b-on-primary: #1E1B4B; /* indigo-950 */
|
||||||
|
--r2b-surface: #111827; /* gray-900 */
|
||||||
|
--r2b-on-surface: #F9FAFB; /* gray-50 */
|
||||||
|
--r2b-surface-variant: #0F172A; /* slate-900 — code blocks */
|
||||||
|
--r2b-on-surface-variant: #E5E7EB; /* gray-200 */
|
||||||
|
--r2b-surface-container: #1F2937; /* gray-800 — card/form backgrounds */
|
||||||
|
--r2b-on-surface-container: #D1D5DB; /* gray-300 — labels, secondary text */
|
||||||
|
--r2b-outline: #4B5563; /* gray-600 — borders */
|
||||||
|
--r2b-error: #FCA5A5; /* red-300 */
|
||||||
|
--r2b-on-error: #7F1D1D; /* red-900 */
|
||||||
|
--r2b-success: #86EFAC; /* green-300 */
|
||||||
|
--r2b-on-success: #14532D; /* green-900 */
|
||||||
|
--r2b-warning: #FCD34D; /* amber-300 */
|
||||||
|
--r2b-on-warning: #78350F; /* amber-900 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Smooth theme transitions — disabled for users with reduced-motion preference */
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
body {
|
||||||
|
transition: background-color 200ms ease, color 200ms ease, border-color 200ms ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wire raw values to Tailwind utility classes */
|
||||||
|
@theme {
|
||||||
|
--color-primary: var(--r2b-primary);
|
||||||
|
--color-on-primary: var(--r2b-on-primary);
|
||||||
|
--color-surface: var(--r2b-surface);
|
||||||
|
--color-on-surface: var(--r2b-on-surface);
|
||||||
|
--color-surface-variant: var(--r2b-surface-variant);
|
||||||
|
--color-on-surface-variant: var(--r2b-on-surface-variant);
|
||||||
|
--color-surface-container: var(--r2b-surface-container);
|
||||||
|
--color-on-surface-container: var(--r2b-on-surface-container);
|
||||||
|
--color-outline: var(--r2b-outline);
|
||||||
|
--color-error: var(--r2b-error);
|
||||||
|
--color-on-error: var(--r2b-on-error);
|
||||||
|
--color-success: var(--r2b-success);
|
||||||
|
--color-on-success: var(--r2b-on-success);
|
||||||
|
--color-warning: var(--r2b-warning);
|
||||||
|
--color-on-warning: var(--r2b-on-warning);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user