-
-
-
+
);
diff --git a/web/src/styles/globals.css b/web/src/styles/globals.css
index f2d357d..a67f031 100644
--- a/web/src/styles/globals.css
+++ b/web/src/styles/globals.css
@@ -8,115 +8,182 @@
}
body {
- font-family: "Inter", system-ui, -apple-system, sans-serif;
- background: linear-gradient(135deg, #0a0e1a 0%, #0f172a 50%, #0c1220 100%);
+ font-family: "IBM Plex Sans", system-ui, sans-serif;
+ background: #0d0d0f;
+ color: #e8e5e0;
min-height: 100vh;
+ position: relative;
+ }
+
+ /* Subtle film grain overlay */
+ body::after {
+ content: "";
+ position: fixed;
+ inset: 0;
+ z-index: 9999;
+ pointer-events: none;
+ opacity: 0.022;
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
+ background-size: 256px 256px;
}
::-webkit-scrollbar {
- width: 6px;
- height: 6px;
+ width: 4px;
+ height: 4px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
- background: rgba(148, 163, 184, 0.2);
- border-radius: 3px;
+ background: #2a2a2e;
+ border-radius: 0;
}
::-webkit-scrollbar-thumb:hover {
- background: rgba(148, 163, 184, 0.4);
+ background: #38383d;
+ }
+
+ ::selection {
+ background: #e8a44a40;
+ color: #e8e5e0;
}
}
@layer components {
- .glass-card {
- @apply relative overflow-hidden rounded-2xl border border-white/[0.06]
- bg-white/[0.03] backdrop-blur-md shadow-xl shadow-black/20;
+ /* ── Card System ─────────────────────────────────────────── */
+ .deck-card {
+ @apply relative bg-base-50 border border-base-300 overflow-hidden;
+ border-radius: 0;
}
- .glass-card-hover {
- @apply glass-card transition-all duration-300
- hover:border-white/[0.12] hover:bg-white/[0.05]
- hover:shadow-2xl hover:shadow-black/30
- hover:-translate-y-0.5;
- }
-
- .glass-card::before {
+ .deck-card::before {
content: "";
position: absolute;
- inset: 0;
- border-radius: inherit;
- background: linear-gradient(
- 135deg,
- rgba(255, 255, 255, 0.04) 0%,
- transparent 50%
- );
- pointer-events: none;
+ top: 0;
+ left: 0;
+ width: 2px;
+ height: 100%;
+ background: #2a2a2e;
+ transition: background 0.2s ease;
}
- .accent-glow {
- position: relative;
+ .deck-card:hover::before {
+ background: #e8a44a;
}
- .accent-glow::after {
+
+ .deck-card[data-accent="gold"]::before { background: #e8a44a; }
+ .deck-card[data-accent="mint"]::before { background: #4ae8a8; }
+ .deck-card[data-accent="cherry"]::before { background: #e85a5a; }
+ .deck-card[data-accent="iris"]::before { background: #a87aec; }
+ .deck-card[data-accent="azure"]::before { background: #5ab4e8; }
+
+ /* Corner markers — technical drawing accent */
+ .corner-marks {
+ @apply relative;
+ }
+ .corner-marks::before,
+ .corner-marks::after {
content: "";
position: absolute;
- inset: -1px;
- border-radius: inherit;
- opacity: 0;
- transition: opacity 0.3s;
+ width: 8px;
+ height: 8px;
+ border-color: #4a4a50;
+ border-style: solid;
pointer-events: none;
+ z-index: 2;
}
- .accent-glow:hover::after {
- opacity: 1;
+ .corner-marks::before {
+ top: -1px;
+ right: -1px;
+ border-width: 1px 1px 0 0;
+ }
+ .corner-marks::after {
+ bottom: -1px;
+ left: -1px;
+ border-width: 0 0 1px 1px;
}
- .stat-value {
- @apply text-3xl font-bold tracking-tight;
- font-family: "JetBrains Mono", monospace;
+ /* ── Section Headers ─────────────────────────────────────── */
+ .section-label {
+ @apply flex items-center gap-3 mb-5;
+ }
+ .section-number {
+ @apply font-mono text-[10px] font-semibold tracking-widest text-base-500 uppercase;
+ }
+ .section-title {
+ @apply font-serif italic text-lg text-base-900 tracking-tight;
+ }
+ .section-rule {
+ @apply flex-1 h-px bg-base-300;
}
- .stat-label {
- @apply text-xs font-medium uppercase tracking-wider text-slate-400;
+ /* ── Data Values ─────────────────────────────────────────── */
+ .data-value {
+ @apply font-mono font-semibold tracking-tight;
+ }
+ .data-label {
+ @apply text-[10px] font-mono uppercase tracking-[0.15em] text-base-600;
}
- .badge {
- @apply inline-flex items-center rounded-full px-2.5 py-0.5 text-[10px]
- font-semibold uppercase tracking-wider;
+ .data-glow-gold { text-shadow: 0 0 20px #e8a44a33, 0 0 40px #e8a44a15; }
+ .data-glow-mint { text-shadow: 0 0 20px #4ae8a833, 0 0 40px #4ae8a815; }
+ .data-glow-cherry { text-shadow: 0 0 20px #e85a5a33, 0 0 40px #e85a5a15; }
+
+ /* ── Tags/Badges ─────────────────────────────────────────── */
+ .tag {
+ @apply inline-flex items-center px-2 py-0.5 text-[10px] font-mono font-medium uppercase tracking-wider border;
+ border-radius: 0;
}
- .progress-bar {
- @apply h-1.5 rounded-full bg-slate-800 overflow-hidden;
+ /* ── Tabs ─────────────────────────────────────────────────── */
+ .tab-btn {
+ @apply px-3 py-1.5 text-xs font-mono font-medium tracking-wider uppercase transition-all duration-150 cursor-pointer select-none border;
+ border-radius: 0;
+ }
+ .tab-btn.active {
+ @apply bg-gold/10 border-gold/40 text-gold;
+ }
+ .tab-btn:not(.active) {
+ @apply bg-transparent border-base-300 text-base-600 hover:text-base-800 hover:border-base-400;
}
- .progress-fill {
- @apply h-full rounded-full transition-all duration-700 ease-out;
+ /* ── Progress ────────────────────────────────────────────── */
+ .bar-track {
+ @apply h-1 bg-base-200 overflow-hidden;
+ border-radius: 0;
+ }
+ .bar-fill {
+ @apply h-full transition-all duration-700 ease-out;
+ border-radius: 0;
}
- .category-tab {
- @apply px-3 py-1.5 rounded-lg text-xs font-medium transition-all duration-200
- cursor-pointer select-none;
+ /* ── Scan-line loader ────────────────────────────────────── */
+ .scan-loader {
+ @apply h-px bg-base-200 overflow-hidden relative;
}
- .category-tab.active {
- @apply bg-white/10 text-white;
+ .scan-loader::after {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 40%;
+ height: 100%;
+ background: linear-gradient(90deg, transparent, #e8a44a, transparent);
+ animation: scan 1.5s ease-in-out infinite;
}
- .category-tab:not(.active) {
- @apply text-slate-400 hover:text-slate-200 hover:bg-white/5;
+
+ /* ── Dividers ────────────────────────────────────────────── */
+ .divider {
+ @apply border-none h-px bg-base-300 my-6;
}
}
@layer utilities {
- .text-gradient {
- @apply bg-clip-text text-transparent;
- }
-
.line-clamp-2 {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
-
.line-clamp-3 {
display: -webkit-box;
-webkit-line-clamp: 3;
diff --git a/web/tailwind.config.js b/web/tailwind.config.js
index 4ffa1ca..7db3979 100644
--- a/web/tailwind.config.js
+++ b/web/tailwind.config.js
@@ -4,28 +4,73 @@ export default {
theme: {
extend: {
colors: {
- surface: {
- 50: "rgba(255,255,255,0.05)",
- 100: "rgba(255,255,255,0.08)",
- 200: "rgba(255,255,255,0.12)",
+ base: {
+ DEFAULT: "#0d0d0f",
+ 50: "#161618",
+ 100: "#1c1c1f",
+ 200: "#232326",
+ 300: "#2a2a2e",
+ 400: "#38383d",
+ 500: "#4a4a50",
+ 600: "#6b6966",
+ 700: "#8a8783",
+ 800: "#b0ada8",
+ 900: "#e8e5e0",
+ },
+ gold: {
+ DEFAULT: "#e8a44a",
+ dim: "#e8a44a80",
+ glow: "#e8a44a33",
+ muted: "#c4884a",
+ },
+ mint: {
+ DEFAULT: "#4ae8a8",
+ dim: "#4ae8a880",
+ glow: "#4ae8a833",
+ },
+ cherry: {
+ DEFAULT: "#e85a5a",
+ dim: "#e85a5a80",
+ glow: "#e85a5a33",
+ },
+ iris: {
+ DEFAULT: "#a87aec",
+ dim: "#a87aec80",
+ glow: "#a87aec33",
+ },
+ azure: {
+ DEFAULT: "#5ab4e8",
+ dim: "#5ab4e880",
+ glow: "#5ab4e833",
},
},
- backdropBlur: {
- xs: "2px",
+ fontFamily: {
+ serif: ['"Instrument Serif"', "Georgia", "serif"],
+ sans: ['"IBM Plex Sans"', "system-ui", "sans-serif"],
+ mono: ['"IBM Plex Mono"', "Menlo", "monospace"],
},
animation: {
- "fade-in": "fadeIn 0.5s ease-out",
- "slide-up": "slideUp 0.4s ease-out",
- "pulse-slow": "pulse 3s ease-in-out infinite",
+ "fade-in": "fadeIn 0.4s ease-out both",
+ "slide-in": "slideIn 0.3s ease-out both",
+ "scan": "scan 1.5s ease-in-out infinite",
+ "glow-pulse": "glowPulse 2s ease-in-out infinite",
},
keyframes: {
fadeIn: {
- "0%": { opacity: "0", transform: "translateY(8px)" },
+ "0%": { opacity: "0", transform: "translateY(6px)" },
"100%": { opacity: "1", transform: "translateY(0)" },
},
- slideUp: {
- "0%": { opacity: "0", transform: "translateY(16px)" },
- "100%": { opacity: "1", transform: "translateY(0)" },
+ slideIn: {
+ "0%": { opacity: "0", transform: "translateX(-8px)" },
+ "100%": { opacity: "1", transform: "translateX(0)" },
+ },
+ scan: {
+ "0%, 100%": { transform: "translateX(-100%)" },
+ "50%": { transform: "translateX(100%)" },
+ },
+ glowPulse: {
+ "0%, 100%": { opacity: "0.5" },
+ "50%": { opacity: "1" },
},
},
},