@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Syne:wght@600;700;800&display=swap'); @tailwind base; @tailwind components; @tailwind utilities; /* ── Skip Navigation Link (Accessibility) ───────────────────────── */ .skip-link { position: absolute; top: -100%; left: 1rem; z-index: 9999; padding: 0.5rem 1rem; background: #10b981; color: #000; font-weight: 600; border-radius: 0 0 0.5rem 0.5rem; text-decoration: none; transition: top 0.2s; } .skip-link:focus { top: 0; } @layer base { :root { --color-bg: #040815; --color-surface: #0b1123; --color-surface-2: #141c33; --color-surface-3: #1e284a; --color-border: rgba(255, 255, 255, 0.06); --color-border-strong: rgba(255, 255, 255, 0.14); --color-text: #f8fafc; --color-text-muted: #94a3b8; --color-text-faint: #475569; --color-accent: #10b981; --color-accent-dim: rgba(16, 185, 129, 0.1); /* score colors */ --color-good: #10b981; --color-warn: #f59e0b; --color-danger: #ef4444; } * { border-color: var(--color-border); box-sizing: border-box; } html { scroll-behavior: smooth; font-size: 16px; } body { font-family: 'Inter', system-ui, -apple-system, sans-serif; background-color: var(--color-bg); color: var(--color-text); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; min-height: 100vh; } h1, h2, h3 { font-family: 'Syne', 'Inter', sans-serif; letter-spacing: -0.03em; line-height: 1.1; } ::-webkit-scrollbar { width: 4px; height: 4px; } ::-webkit-scrollbar-track { background: #000; } ::-webkit-scrollbar-thumb { background: #333; border-radius: 2px; } ::-webkit-scrollbar-thumb:hover { background: #555; } input[type='number']::-webkit-outer-spin-button, input[type='number']::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } input[type='number'] { -moz-appearance: textfield; } } @layer components { /* ── Cards ── */ .glass-card { background: var(--color-surface); border: 1px solid rgba(255, 255, 255, 0.08); border-radius: 1rem; } .glass-card-hover { @apply glass-card transition-all duration-300 cursor-pointer; } .glass-card-hover:hover { background: var(--color-surface-2); border-color: rgba(255, 255, 255, 0.2); transform: translateY(-2px); box-shadow: 0 20px 60px rgba(0, 0, 0, 0.8); } /* ── Typography ── */ .gradient-text { background: linear-gradient(135deg, #10b981 0%, #06b6d4 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .gradient-text-warm { background: linear-gradient(135deg, #f59e0b 0%, #ef4444 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } /* ── Glow ── */ .glow-eco { box-shadow: 0 0 30px rgba(255, 255, 255, 0.1), 0 0 60px rgba(255, 255, 255, 0.04); } .glow-blue { box-shadow: 0 0 30px rgba(255, 255, 255, 0.08); } /* ── Buttons ── */ .btn-primary { @apply relative overflow-hidden inline-flex items-center justify-center gap-2; @apply px-6 py-3 rounded-xl font-semibold transition-all duration-200; background: linear-gradient(135deg, #10b981 0%, #059669 100%); color: #ffffff; font-size: 0.9375rem; box-shadow: 0 4px 20px rgba(16, 185, 129, 0.25); } .btn-primary::after { content: ''; position: absolute; inset: 0; background: linear-gradient(135deg, rgba(255, 255, 255, 0.15), transparent); opacity: 0; transition: opacity 0.2s; border-radius: inherit; } .btn-primary:hover::after { opacity: 1; } .btn-primary:hover { transform: translateY(-1px); box-shadow: 0 8px 30px rgba(16, 185, 129, 0.45); } .btn-primary:active { transform: translateY(0); } .btn-secondary { @apply inline-flex items-center justify-center gap-2 px-6 py-3 rounded-xl font-semibold transition-all duration-200; background: transparent; border: 1px solid rgba(255, 255, 255, 0.15); color: #ffffff; font-size: 0.9375rem; } .btn-secondary:hover { background: rgba(255, 255, 255, 0.06); border-color: rgba(255, 255, 255, 0.35); } /* ── Form inputs ── */ .input-field { @apply w-full rounded-xl px-4 py-3 transition-all duration-200 focus:outline-none; background: var(--color-surface-2); border: 1px solid rgba(255, 255, 255, 0.08); color: #ffffff; font-size: 0.9375rem; } .input-field:hover { border-color: rgba(255, 255, 255, 0.15); } .input-field:focus { background: var(--color-surface-3); border-color: rgba(255, 255, 255, 0.4); box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.05); } .input-field::placeholder { color: rgba(255, 255, 255, 0.2); } .select-field { @apply input-field cursor-pointer; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 14px center; padding-right: 42px; } .select-field option { background: #111; color: #fff; } .form-label { @apply block text-sm font-medium mb-2; color: #888; letter-spacing: 0.01em; } /* ── Badges ── */ .eco-badge { @apply inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-semibold; background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.15); color: #ffffff; letter-spacing: 0.05em; text-transform: uppercase; } .badge-high { @apply inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-xs font-semibold; background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.15); color: #ffffff; } .badge-medium { @apply inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-xs font-semibold; background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.1); color: #bbbbbb; } .badge-low { @apply inline-flex items-center gap-1 px-2.5 py-0.5 rounded-full text-xs font-semibold; background: rgba(255, 255, 255, 0.03); border: 1px solid rgba(255, 255, 255, 0.08); color: #777777; } /* ── Stat ── */ .stat-number { @apply text-3xl font-bold; font-family: 'Syne', sans-serif; color: #ffffff; } /* ── Skeleton ── */ .skeleton { background: linear-gradient( 90deg, rgba(255, 255, 255, 0.03) 25%, rgba(255, 255, 255, 0.07) 50%, rgba(255, 255, 255, 0.03) 75% ); background-size: 200% 100%; animation: shimmer 1.8s ease-in-out infinite; border-radius: 0.5rem; } /* ── Divider ── */ .section-divider { height: 1px; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent); margin: 1.75rem 0; } /* ── Progress ── */ .progress-bar { @apply h-1.5 rounded-full overflow-hidden; background: rgba(255, 255, 255, 0.06); } .progress-bar-fill { @apply h-full rounded-full transition-all duration-700 ease-out; background: #ffffff; } /* ── Step indicator ── */ .step-active { background: #ffffff; box-shadow: 0 0 20px rgba(255, 255, 255, 0.25); } .step-complete { background: rgba(255, 255, 255, 0.12); border: 1px solid rgba(255, 255, 255, 0.3); } .step-inactive { background: transparent; border: 1px solid rgba(255, 255, 255, 0.1); } /* ── Nav ── */ .nav-link-active { color: #ffffff; background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.15); } .nav-link { color: #666666; background: transparent; border: 1px solid transparent; transition: all 0.2s; } .nav-link:hover { color: #ffffff; background: rgba(255, 255, 255, 0.04); } /* ── Animated underline ── */ .animated-underline { position: relative; } .animated-underline::after { content: ''; position: absolute; bottom: -2px; left: 0; width: 0; height: 1px; background: #ffffff; transition: width 0.3s ease; } .animated-underline:hover::after { width: 100%; } /* ── Ticker / animated number ── */ .ticker { font-family: 'Syne', monospace; font-variant-numeric: tabular-nums; transition: all 0.6s ease; } /* ── Dynamic scan line ── */ .scan-line { position: relative; overflow: hidden; } .scan-line::before { content: ''; position: absolute; top: -100%; left: 0; right: 0; height: 100%; background: linear-gradient( 180deg, transparent 0%, rgba(255, 255, 255, 0.03) 50%, transparent 100% ); animation: scan 4s ease-in-out infinite; } @keyframes scan { 0% { top: -100%; } 100% { top: 200%; } } /* ── Blinking cursor ── */ .cursor-blink::after { content: '|'; animation: blink 1s step-end infinite; color: #ffffff; margin-left: 2px; } @keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } } /* ── Animated border ── */ .animated-border { position: relative; } .animated-border::before { content: ''; position: absolute; inset: -1px; border-radius: inherit; padding: 1px; background: linear-gradient( 135deg, rgba(255, 255, 255, 0.3), transparent, rgba(255, 255, 255, 0.1) ); background-size: 200% 200%; animation: borderRotate 4s linear infinite; -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: 0; transition: opacity 0.3s; } .animated-border:hover::before { opacity: 1; } } /* ── Keyframes ── */ @keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } } @keyframes borderRotate { 0% { background-position: 0% 50%; } 100% { background-position: 200% 50%; } } @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } } @keyframes slide-up { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } @keyframes slide-right { from { opacity: 0; transform: translateX(-12px); } to { opacity: 1; transform: translateX(0); } } @keyframes float { 0%, 100% { transform: translateY(0px); } 50% { transform: translateY(-10px); } } @keyframes pulse-slow { 0%, 100% { opacity: 0.3; } 50% { opacity: 0.6; } } @keyframes count-up { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } @keyframes expand-width { from { width: 0; } to { width: var(--target-width, 100%); } } .animate-fade-in { animation: fade-in 0.4s ease-out forwards; } .animate-slide-up { animation: slide-up 0.45s ease-out forwards; } .animate-slide-right { animation: slide-right 0.4s ease-out forwards; } .animate-float { animation: float 5s ease-in-out infinite; } .animate-pulse-slow { animation: pulse-slow 3s ease-in-out infinite; } .animate-spin { animation: spin 0.8s linear infinite; } .animate-count { animation: count-up 0.5s ease-out forwards; } @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* ── Recharts overrides ── */ .recharts-tooltip-wrapper .recharts-default-tooltip { background: #111111 !important; border: 1px solid rgba(255, 255, 255, 0.15) !important; border-radius: 12px !important; } .recharts-default-tooltip .recharts-tooltip-label { color: #888 !important; font-size: 12px !important; } /* ── Focus rings ── */ *:focus-visible { outline: 1px solid rgba(255, 255, 255, 0.5); outline-offset: 2px; border-radius: 6px; } /* ── Range input ── */ input[type='range'] { -webkit-appearance: none; height: 4px; border-radius: 2px; background: rgba(255, 255, 255, 0.08); outline: none; } input[type='range']::-webkit-slider-thumb { -webkit-appearance: none; width: 16px; height: 16px; border-radius: 50%; background: #ffffff; cursor: pointer; box-shadow: 0 0 8px rgba(255, 255, 255, 0.3); transition: box-shadow 0.2s; } input[type='range']::-webkit-slider-thumb:hover { box-shadow: 0 0 16px rgba(255, 255, 255, 0.5); } /* ── Dynamic grid bg ── */ .grid-bg { background-image: linear-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px); background-size: 48px 48px; } /* ── Progress fill (moved from inline dangerouslySetInnerHTML) ── */ @keyframes progressFill { from { width: 0%; } to { width: 98%; } } /* ── Accessibility: prefers-reduced-motion ── */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-delay: -1ms !important; animation-duration: 1ms !important; animation-iteration-count: 1 !important; background-attachment: initial !important; scroll-behavior: auto !important; transition-duration: 0s !important; transition-delay: 0s !important; } }