/* ============================================================================ Novarix Networks — Global stylesheet ============================================================================ This file controls the visual *theme* of the site (colours, fonts, background effects, animations). Most page layout is done with Tailwind utility classes directly inside `app/page.tsx` — this file only handles things that don't fit neatly into utilities. What's in here, top to bottom: 1. Design tokens — brand colours, font, shadows (@theme block) 2. Theme variables — light + dark mode CSS variables 3. Base styles — body font, focus rings, text selection 4. Site shell + ambient — background gradient, floating orbs, grid 5. Brand wordmark swap — light/dark logo switcher 6. Intro overlay — first-visit animated logo 7. Animations — keyframes used above 8. Reduced motion — respect "prefers-reduced-motion" setting To change the brand colour palette, edit the `--color-brand-*` lines in the @theme block below. Everything else cascades from those. ============================================================================ */ @import "tailwindcss"; /* --------------------------------------------------------------------------- 1. Design tokens — registered with Tailwind v4 via @theme. These become utility classes (e.g. `bg-brand-500`, `text-ink-900`) and custom CSS variables you can use anywhere in the stylesheet. --------------------------------------------------------------------------- */ @theme { --font-sans: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; --color-brand-50: oklch(0.97 0.015 240); --color-brand-100: oklch(0.93 0.04 240); --color-brand-200: oklch(0.86 0.07 240); --color-brand-300: oklch(0.78 0.11 240); --color-brand-400: oklch(0.7 0.14 240); --color-brand-500: oklch(0.62 0.16 240); --color-brand-600: oklch(0.54 0.18 245); --color-brand-700: oklch(0.46 0.18 250); --color-ink-50: oklch(0.985 0.003 250); --color-ink-100: oklch(0.96 0.005 250); --color-ink-200: oklch(0.92 0.008 250); --color-ink-300: oklch(0.84 0.012 250); --color-ink-400: oklch(0.65 0.018 250); --color-ink-500: oklch(0.5 0.02 250); --color-ink-600: oklch(0.38 0.022 250); --color-ink-700: oklch(0.28 0.024 250); --color-ink-800: oklch(0.2 0.026 250); --color-ink-900: oklch(0.13 0.028 255); --color-ink-950: oklch(0.08 0.03 260); --radius-card: 1.25rem; --shadow-card: 0 1px 0 0 oklch(1 0 0 / 0.04) inset, 0 12px 32px -12px oklch(0 0 0 / 0.18); } /* --------------------------------------------------------------------------- 2. Theme variables (light + dark) These are the runtime CSS variables read by both this file and app/page.tsx (via classes like `bg-[var(--surface)]`). Each variable has a light value here and a dark override further down inside the `@media (prefers-color-scheme: dark)` block. --------------------------------------------------------------------------- */ :root { color-scheme: light dark; --bg: var(--color-ink-50); --surface: oklch(1 0 0 / 0.7); --surface-strong: oklch(1 0 0 / 0.92); --text: var(--color-ink-900); --text-soft: var(--color-ink-500); --border: oklch(0.13 0.028 255 / 0.1); --border-strong: oklch(0.13 0.028 255 / 0.18); --accent: var(--color-brand-500); --accent-soft: oklch(0.62 0.16 240 / 0.12); --ring: oklch(0.62 0.16 240 / 0.4); --grid: oklch(0.5 0.02 250 / 0.08); --button-bg: var(--color-ink-900); --button-fg: var(--color-ink-50); --button-hover: var(--color-ink-800); } @media (prefers-color-scheme: dark) { :root { --bg: var(--color-ink-950); --surface: oklch(0.13 0.028 255 / 0.55); --surface-strong: oklch(0.13 0.028 255 / 0.85); --text: var(--color-ink-100); --text-soft: var(--color-ink-400); --border: oklch(1 0 0 / 0.08); --border-strong: oklch(1 0 0 / 0.16); --accent: var(--color-brand-400); --accent-soft: oklch(0.7 0.14 240 / 0.18); --ring: oklch(0.7 0.14 240 / 0.5); --grid: oklch(0.84 0.012 250 / 0.06); --button-bg: var(--color-ink-100); --button-fg: var(--color-ink-950); --button-hover: var(--color-ink-50); } } /* --------------------------------------------------------------------------- 3. Base styles — applied to plain HTML elements before any classes hit. --------------------------------------------------------------------------- */ @layer base { html { background: var(--bg); scroll-behavior: smooth; } body { background: var(--bg); color: var(--text); font-family: var(--font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; overflow-x: hidden; } ::selection { background: var(--accent-soft); color: var(--text); } :focus-visible { outline: 2px solid var(--ring); outline-offset: 3px; border-radius: 4px; } } /* --------------------------------------------------------------------------- 4. Site shell + ambient effects The .site-shell class is on the
element in page.tsx. The two radial gradients here follow the user's mouse via the --mx / --my CSS variables that page.tsx writes on every mousemove. --------------------------------------------------------------------------- */ .site-shell { position: relative; isolation: isolate; min-height: 100vh; background: radial-gradient( circle at var(--mx, 50%) var(--my, 22%), oklch(0.62 0.16 240 / 0.12), transparent 20% ), radial-gradient( circle at calc(var(--mx, 50%) * 0.65) calc(var(--my, 22%) * 1.2), oklch(0.6 0.14 280 / 0.09), transparent 24% ), var(--bg); } .ambient-grid { position: absolute; inset: 0; background-image: linear-gradient(to right, var(--grid) 1px, transparent 1px), linear-gradient(to bottom, var(--grid) 1px, transparent 1px); background-size: 56px 56px; mask-image: linear-gradient(to bottom, oklch(0 0 0 / 0.5), transparent 80%); } .ambient-orb { position: absolute; border-radius: 9999px; filter: blur(80px); opacity: 0.22; animation: drift 18s ease-in-out infinite; will-change: transform; } .ambient-orb-a { width: 32rem; height: 32rem; top: 4rem; right: -10rem; background: linear-gradient( 135deg, oklch(0.7 0.14 240 / 0.55), oklch(0.6 0.14 200 / 0.1) ); } .ambient-orb-b { width: 26rem; height: 26rem; top: 28rem; left: -8rem; background: linear-gradient( 135deg, oklch(0.6 0.14 280 / 0.35), oklch(0.78 0.11 200 / 0.12) ); animation-duration: 22s; } /* --------------------------------------------------------------------------- 5. Brand wordmark colour-scheme swap The header logo has two PNG variants — a colour one for light mode and a white one for dark mode. The `brand-light` / `brand-dark` classes (set in page.tsx) live on both tags; only the matching one is shown. --------------------------------------------------------------------------- */ .brand-light { display: block; } .brand-dark { display: none; } @media (prefers-color-scheme: dark) { .brand-light { display: none; } .brand-dark { display: block; } } /* --------------------------------------------------------------------------- 6. Animations — keyframes used by the ambient orbs above. --------------------------------------------------------------------------- */ @keyframes drift { 0%, 100% { transform: translate3d(0, 0, 0) scale(1); } 50% { transform: translate3d(0, 18px, 0) scale(1.06); } } /* --------------------------------------------------------------------------- 7. Reduced motion Respects the user's OS-level "reduce motion" preference by disabling the orb drift and any transition/animation durations across the site. --------------------------------------------------------------------------- */ @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } .ambient-orb { animation: none !important; } *, *::before, *::after { transition-duration: 0ms !important; animation-duration: 0ms !important; } }