Spaces:
Running
Running
| @import 'tailwindcss'; | |
| /* ββ Design tokens (Deep Space Glacier) ββββββββββββββββββββββββββββββββββββ */ | |
| @theme { | |
| /* Backgrounds - neutral greyscale, no hue. */ | |
| --color-bg: #0a0a0b; | |
| --color-bg-2: #0f0f10; | |
| --color-panel: #141415; | |
| --color-panel-2: #1a1a1c; | |
| --color-line: #2a2a2c; | |
| --color-line-2: #38383b; | |
| /* Text */ | |
| --color-text: #ededed; | |
| --color-muted: #8a8a8e; | |
| --color-muted-2: #a6a6aa; | |
| /* "Accents" are now just lighter/darker greys - monochrome aesthetic. | |
| Names kept so existing class references (text-cyan, etc.) still resolve. */ | |
| --color-cyan: #d4d4d8; | |
| --color-cyan-bright: #ffffff; | |
| --color-indigo: #9a9a9e; | |
| --color-amber: #b0b0b4; | |
| --color-red: #e6e6e8; | |
| --color-critical: #e6e6e8; | |
| --color-green: #6a6a6e; | |
| /* Zone-category severity - encoded by brightness, not hue. */ | |
| --color-hotspot: #efefef; | |
| --color-blindspot: #9a9a9e; | |
| --color-calm: #5a5a5e; | |
| /* Fonts */ | |
| --font-display: 'Clash Display', 'Space Grotesk', system-ui, sans-serif; | |
| --font-sans: 'Inter', system-ui, sans-serif; | |
| --font-mono: 'JetBrains Mono', 'Cascadia Code', monospace; | |
| /* shadcn-compatible aliases - let dropped-in shadcn components (e.g. the | |
| mapcn map) resolve bg-background/text-foreground/border-border/etc. | |
| against our Deep Space Glacier palette. */ | |
| --color-background: #141415; | |
| --color-foreground: #ededed; | |
| --color-popover: #141415; | |
| --color-popover-foreground: #ededed; | |
| --color-muted-foreground: #8a8a8e; | |
| --color-accent: #1f1f21; | |
| --color-border: #2a2a2c; | |
| --color-ring: #d4d4d8; | |
| /* Tokens for shadcn-style components (limelight nav, etc.). */ | |
| --color-card: #141415; | |
| --color-primary: #ededed; | |
| --color-secondary: #1a1a1c; | |
| --color-primary-foreground: #0a0a0b; | |
| --color-card-foreground: #ededed; | |
| } | |
| /* Plain token BGPattern's fade masks expect (var(--background)). Matches the | |
| page background so the masked edges blend into it. */ | |
| :root { | |
| --background: #0a0a0b; | |
| /* LimelightNav's glow shadow reads var(--primary) directly. */ | |
| --primary: #ededed; | |
| } | |
| html, | |
| body { | |
| margin: 0; | |
| padding: 0; | |
| height: 100%; | |
| background: #0a0a0b; | |
| color: #ededed; | |
| font-family: 'Inter', 'Segoe UI', system-ui, sans-serif; | |
| -webkit-font-smoothing: antialiased; | |
| text-rendering: optimizeLegibility; | |
| } | |
| #app, | |
| #root { | |
| height: 100%; | |
| } | |
| /* Lenis smooth-scroll baseline */ | |
| html.lenis, | |
| html.lenis body { | |
| height: auto; | |
| } | |
| .lenis.lenis-smooth { | |
| scroll-behavior: auto ; | |
| } | |
| .lenis.lenis-stopped { | |
| overflow: hidden; | |
| } | |
| /* Hex-grid backdrop */ | |
| .tron-grid { | |
| background-image: | |
| linear-gradient(rgba(255, 255, 255, 0.035) 1px, transparent 1px), | |
| linear-gradient(90deg, rgba(255, 255, 255, 0.035) 1px, transparent 1px); | |
| background-size: 44px 44px; | |
| } | |
| /* Slow pulse for preview hexagons */ | |
| @keyframes hexpulse { | |
| 0%, 100% { opacity: 0.85; } | |
| 50% { opacity: 0.30; } | |
| } | |
| .hex-pulse { animation: hexpulse 3.2s ease-in-out infinite; } | |
| /* Soft glow text utility */ | |
| .text-glow-cyan { text-shadow: 0 0 24px rgba(255, 255, 255, 0.35); } | |
| /* Bobbing scroll cue */ | |
| @keyframes scrollcue { | |
| 0%, 100% { transform: translateY(0); opacity: 0.5; } | |
| 50% { transform: translateY(6px); opacity: 1; } | |
| } | |
| .scroll-cue { animation: scrollcue 1.8s ease-in-out infinite; } | |
| /* Display-face helpers */ | |
| .font-display { font-family: var(--font-display); } | |
| .font-mono { font-family: var(--font-mono); } | |
| /* Section reveal - used by IntersectionObserver-driven sections */ | |
| .reveal { | |
| opacity: 0; | |
| transform: translateY(28px); | |
| transition: opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1), | |
| transform 0.8s cubic-bezier(0.22, 1, 0.36, 1); | |
| } | |
| .reveal.is-visible { | |
| opacity: 1; | |
| transform: translateY(0); | |
| } | |
| /* ββ Landing page theming ββββββββββββββββββββββββββββββββββββββββββββββββ | |
| The landing root carries data-theme="dark|light"; everything reads these | |
| vars so the night/day toggle restyles the whole page. */ | |
| .landing-root { | |
| --lp-bg: #07070a; | |
| --lp-text: #ededed; | |
| --lp-muted: #9a9a9e; | |
| --lp-eyebrow: #b8b8bc; | |
| --lp-line: #2a2a2c; | |
| --lp-section: rgba(10, 10, 11, 0.5); | |
| --lp-glow: rgba(214, 84, 44, 0.16); | |
| --lp-grid: rgba(255, 255, 255, 0.09); | |
| --lp-nav: rgba(10, 10, 11, 0.72); | |
| --lp-chip: rgba(255, 255, 255, 0.04); | |
| --lp-scrim: linear-gradient(90deg, #0a0a0b 0%, rgba(10, 10, 11, 0.8) 30%, rgba(10, 10, 11, 0) 56%); | |
| } | |
| .landing-root[data-theme='light'] { | |
| --lp-bg: #eceef2; | |
| --lp-text: #15171d; | |
| --lp-muted: #565a63; | |
| --lp-eyebrow: #6a6e77; | |
| --lp-line: rgba(0, 0, 0, 0.12); | |
| --lp-section: rgba(255, 255, 255, 0.45); | |
| --lp-glow: rgba(214, 84, 44, 0.12); | |
| --lp-grid: rgba(0, 0, 0, 0.06); | |
| --lp-nav: rgba(255, 255, 255, 0.72); | |
| --lp-chip: rgba(0, 0, 0, 0.04); | |
| --lp-scrim: linear-gradient(90deg, #eceef2 0%, rgba(236, 238, 242, 0.8) 30%, rgba(236, 238, 242, 0) 56%); | |
| } | |
| /* Premium film-grain texture - fixed, very subtle, blended over everything. */ | |
| .grain-overlay { | |
| position: fixed; | |
| inset: 0; | |
| z-index: 60; | |
| pointer-events: none; | |
| opacity: 0.03; /* Slightly lower opacity since normal blending is more visible than overlay */ | |
| background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); | |
| background-size: 160px 160px; | |
| } | |
| /* Top scroll-progress meter. */ | |
| .scroll-progress { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| height: 2px; | |
| z-index: 60; | |
| transform-origin: left center; | |
| background: linear-gradient(90deg, rgba(214,84,44,0.0), #d6542c 55%, #ff8a5c); | |
| box-shadow: 0 0 12px rgba(214,84,44,0.55); | |
| will-change: transform; | |
| } | |
| /* Glass "live" chip used for hero eyebrow. */ | |
| .live-dot { | |
| position: relative; | |
| display: inline-block; | |
| width: 6px; | |
| height: 6px; | |
| border-radius: 999px; | |
| background: #ff8a5c; | |
| box-shadow: 0 0 8px rgba(255,138,92,0.9); | |
| } | |
| .live-dot::after { | |
| content: ''; | |
| position: absolute; | |
| inset: -4px; | |
| border-radius: 999px; | |
| border: 1px solid rgba(255,138,92,0.6); | |
| animation: livePulse 2.2s ease-out infinite; | |
| } | |
| @keyframes livePulse { | |
| 0% { transform: scale(0.6); opacity: 0.9; } | |
| 100% { transform: scale(2.2); opacity: 0; } | |
| } | |
| /* Shine sweep - diagonal light pass on hover for premium buttons/cards. */ | |
| .shine { | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .shine::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: -120%; | |
| width: 80%; | |
| height: 100%; | |
| background: linear-gradient(100deg, transparent, rgba(255,255,255,0.18), transparent); | |
| transform: skewX(-18deg); | |
| transition: left 0.6s cubic-bezier(0.22, 1, 0.36, 1); | |
| pointer-events: none; | |
| } | |
| .shine:hover::before { left: 130%; } | |
| /* Animated gradient text sweep - for the hero headline accent. */ | |
| @keyframes textPan { | |
| to { background-position: 200% center; } | |
| } | |
| .text-shimmer { | |
| background-size: 200% auto; | |
| animation: textPan 7s linear infinite; | |
| } | |
| /* Gentle floating bob - for accent elements that should feel alive. */ | |
| @keyframes floaty { | |
| 0%, 100% { transform: translateY(0); } | |
| 50% { transform: translateY(-7px); } | |
| } | |
| .floaty { animation: floaty 6s ease-in-out infinite; } | |
| @media (prefers-reduced-motion: reduce) { | |
| .reveal { transition: none; opacity: 1; transform: none; } | |
| .hex-pulse { animation: none; } | |
| .text-shimmer { animation: none; } | |
| .floaty { animation: none; } | |
| .live-dot::after { animation: none; } | |
| .shine::before { transition: none; } | |
| } | |
| /* ββ Dashboard panel theming βββββββββββββββββββββββββββββββββββββββββββββ | |
| The dashboard root carries data-theme="dark|light"; panels read these vars | |
| so a single attribute flip restyles every panel to match the basemap tone. */ | |
| .twin-root { | |
| --tw-panel: rgba(17, 17, 17, 0.88); | |
| --tw-border: rgba(255, 255, 255, 0.10); | |
| --tw-text: #eaf0f7; | |
| --tw-text-strong: #ffffff; | |
| --tw-muted: #9a9a9e; | |
| --tw-hover: rgba(255, 255, 255, 0.05); | |
| --tw-scrollbar: rgba(255, 255, 255, 0.25); | |
| --tw-scrollbar-hover: rgba(255, 255, 255, 0.45); | |
| } | |
| .twin-root[data-theme='light'] { | |
| --tw-panel: rgba(249, 249, 251, 0.92); | |
| --tw-border: rgba(0, 0, 0, 0.10); | |
| --tw-text: #16181d; | |
| --tw-text-strong: #000000; | |
| --tw-muted: #5a5a5e; | |
| --tw-hover: rgba(0, 0, 0, 0.05); | |
| --tw-scrollbar: rgba(0, 0, 0, 0.3); | |
| --tw-scrollbar-hover: rgba(0, 0, 0, 0.5); | |
| } | |
| /* Thin, rounded, track-less scrollbar for the dashboard panels. */ | |
| .twin-scroll { | |
| scrollbar-width: thin; /* Firefox */ | |
| scrollbar-color: var(--tw-scrollbar) transparent; | |
| } | |
| .twin-scroll::-webkit-scrollbar { | |
| width: 6px; | |
| height: 6px; | |
| } | |
| .twin-scroll::-webkit-scrollbar-track { | |
| background: transparent; | |
| } | |
| .twin-scroll::-webkit-scrollbar-thumb { | |
| background: var(--tw-scrollbar); | |
| border-radius: 999px; | |
| } | |
| .twin-scroll::-webkit-scrollbar-thumb:hover { | |
| background: var(--tw-scrollbar-hover); | |
| } | |
| .twin-scroll::-webkit-scrollbar-button { | |
| display: none; | |
| height: 0; | |
| } | |
| /* Extra-thin (4px) scrollbar for the detail panel's inner scroll area. */ | |
| .twin-scroll-thin { | |
| scrollbar-width: thin; /* Firefox */ | |
| scrollbar-color: var(--tw-scrollbar) transparent; | |
| } | |
| .twin-scroll-thin::-webkit-scrollbar { | |
| width: 4px; | |
| } | |
| .twin-scroll-thin::-webkit-scrollbar-track { | |
| background: transparent; | |
| } | |
| .twin-scroll-thin::-webkit-scrollbar-thumb { | |
| background: var(--tw-scrollbar); | |
| border-radius: 2px; | |
| } | |
| .twin-scroll-thin::-webkit-scrollbar-button { | |
| display: none; | |
| height: 0; | |
| } | |
| /* Always-visible, grabbable scrollbar for the zone list (left panel, right | |
| side). Wider track + solid thumb so the user can drag back to the top. */ | |
| .twin-scroll-visible { | |
| scrollbar-width: auto; /* Firefox */ | |
| scrollbar-color: var(--tw-scrollbar) var(--tw-hover); | |
| overscroll-behavior: contain; | |
| } | |
| .twin-scroll-visible::-webkit-scrollbar { | |
| width: 11px; | |
| } | |
| .twin-scroll-visible::-webkit-scrollbar-track { | |
| background: var(--tw-hover); | |
| border-radius: 999px; | |
| } | |
| .twin-scroll-visible::-webkit-scrollbar-thumb { | |
| background: var(--tw-scrollbar); | |
| border-radius: 999px; | |
| border: 2px solid transparent; | |
| background-clip: padding-box; | |
| min-height: 44px; | |
| } | |
| .twin-scroll-visible::-webkit-scrollbar-thumb:hover { | |
| background: var(--tw-scrollbar-hover); | |
| background-clip: padding-box; | |
| } | |
| .twin-scroll-visible::-webkit-scrollbar-button { | |
| display: none; | |
| height: 0; | |
| } | |
| /* Hide scrollbar completely for the main page to create an immersive experience. */ | |
| html { | |
| scrollbar-width: none; /* Firefox */ | |
| } | |
| html::-webkit-scrollbar { | |
| display: none; | |
| } | |
| /* Bengaluru hub marker - soft expanding pulse halo behind the pin. */ | |
| @keyframes globehubpulse { | |
| 0% { transform: scale(0.6); opacity: 0.6; } | |
| 70% { transform: scale(1.8); opacity: 0; } | |
| 100% { transform: scale(1.8); opacity: 0; } | |
| } | |
| .globe-hub-pulse { | |
| width: 26px; | |
| height: 26px; | |
| background: radial-gradient(circle, rgba(255,255,255,0.5) 0%, rgba(255,255,255,0) 70%); | |
| animation: globehubpulse 2.6s ease-out infinite; | |
| } | |
| @media (prefers-reduced-motion: reduce) { | |
| .globe-hub-pulse { animation: none; opacity: 0.3; } | |
| } | |
| /* Police-light dot - gentle redβblue crossfade (subtle, not a harsh strobe). */ | |
| @keyframes police-light { | |
| 0% { background: #e0544e; box-shadow: 0 0 8px 1px rgba(224,84,78,0.45); } | |
| 50% { background: #5a86e0; box-shadow: 0 0 8px 1px rgba(90,134,224,0.45); } | |
| 100% { background: #e0544e; box-shadow: 0 0 8px 1px rgba(224,84,78,0.45); } | |
| } | |
| .police-light { | |
| animation: police-light 3.4s ease-in-out infinite; | |
| } | |
| @media (prefers-reduced-motion: reduce) { | |
| .police-light { animation: none; background: #d4d4d8; box-shadow: 0 0 12px rgba(255,255,255,0.5); } | |
| } | |