Styledex
← Index

Light Rays Background

superdesignCC0-1.0Prompt onlyLanding · landingMinimal · minimalLight · lightMedium · mediumCyan · cyanVivid · vividSerif · serifGeneral · general

A minimalist showcase of a high-end WebGL light rays background effect with mouse interaction and atmospheric motion. Source: ReactBits Category: Animations & Backgrounds. Prompt author listed upstream: Jason Zhou.

NNorthwind
Product · Pricing
Specimen
Make the work feel finished

One interface, dressed in this style. Compare type, color, radius, and density.

128
Active
4.8
Score
12ms
Edge

Attribution

"Light Rays Background" from https://github.com/superdesigndev/superdesign-prompts (CC0-1.0). © Superdesign. prompts/light-rays-background @ 6c6090694520.

https://github.com/superdesigndev/superdesign-prompts · prompts/light-rays-background · 6c6090694520 · © Superdesign

Prompt

You are given a task to integrate an existing React component in the codebase
~~~/README.md
# LightRays
A high-end, high-performance WebGL light ray background effect. It creates cinematic, atmospheric lighting that responds to mouse movement and animates organically.
## Features
- **WebGL Accelerated**: Smooth 60fps performance using OGL.
- **Interactive**: Rays can tilt and follow mouse movement.
- **Customizable**: Control origin, color, spread, speed, distortion, and more.
- **Lightweight**: Zero external heavy dependencies (uses OGL).
## Dependencies
- `ogl`: ^1.0.11
- `framer-motion`: latest
- `lucide-react`: latest
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `raysOrigin` | `RaysOrigin` | `'top-center'` | The starting point of the rays |
| `raysColor` | `string` | `'#ffffff'` | The hex color of the light rays |
| `raysSpeed` | `number` | `1` | Animation speed multiplier |
| `lightSpread` | `number` | `1` | Width of the light beam |
| `rayLength` | `number` | `2` | Length of rays relative to container |
| `pulsating` | `boolean` | `false` | Enable breathing intensity effect |
| `followMouse` | `boolean` | `true` | Whether rays tilt towards mouse |
| `mouseInfluence` | `number` | `0.1` | Intensity of mouse tracking |
| `noiseAmount` | `number` | `0.0` | Amount of film grain/noise |
| `distortion` | `number` | `0.0` | Wave distortion amount |
## Usage
```tsx
import { LightRays } from '@/sd-components/f0a75623-66d9-49e2-a9a9-aacf9ca7fe87';
function MyPage() {
  return (
    <div className="relative w-full h-[600px] bg-slate-950 overflow-hidden">
      <LightRays
        raysOrigin="top-center"
        raysColor="#00ffff"
        raysSpeed={1.5}
        lightSpread={0.8}
        rayLength={1.2}
        followMouse={true}
      />
      <div className="relative z-10">
        <h1>Cinematic Lighting</h1>
      </div>
    </div>
  );
}
```
~~~
~~~/src/App.tsx
import { LightRays } from './Component';
import { motion } from 'framer-motion';
import { ArrowLeft } from 'lucide-react';
/**
 * Demo application for LightRays component.
 * Showcases a high-end atmospheric background with a minimalist interface.
 */
export default function App() {
  return (
    <main className="relative w-full h-screen bg-[#1A1A1B] flex items-center justify-center overflow-hidden">
      {/* The background effect */}
      <LightRays
        raysOrigin="top-center"
        raysColor="#00ffff"
        raysSpeed={1.5}
        lightSpread={1.2}
        rayLength={1.8}
        followMouse={true}
        mouseInfluence={0.3}
        noiseAmount={0.03}
        distortion={0.08}
      />
      {/* Minimalist Overlay */}
      <div className="relative z-10 flex flex-col items-center text-center px-6">
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.8, ease: [0.16, 1, 0.3, 1] }}
          className="space-y-6"
        >
          <h1 className="text-5xl md:text-7xl font-medium tracking-tight text-white/90">
            LightRays
          </h1>
          <div className="h-px w-24 bg-gradient-to-r from-transparent via-[#00ffff]/50 to-transparent mx-auto" />
          <p className="text-white/40 text-lg md:text-xl font-light max-w-md mx-auto">
            High-end WebGL atmospheric lighting. Interactive, lightweight, and cinematic.
          </p>
        </motion.div>
      </div>
      {/* Required Reply Button as per instructions */}
      <motion.button
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        transition={{ delay: 1 }}
        onClick={() => window.history.back()}
        className="fixed bottom-12 right-12 z-20 flex items-center gap-2 px-6 py-3 rounded-full bg-white/5 border border-white/10 text-white/70 hover:bg-white/10 hover:text-white transition-all backdrop-blur-md group"
      >
        <ArrowLeft className="w-4 h-4 group-hover:-translate-x-1 transition-transform" />
        <span className="text-sm font-medium">Reply</span>
      </motion.button>
      {/* Subtle floating shadow container as per style guide */}
      <div className="fixed inset-24 pointer-events-none rounded-[40px] shadow-[0_0_80px_rgba(0,0,0,0.2)] border border-white/5" />
    </main>
  );
}
~~~
~~~/package.json
{
  "name": "light-rays-showcase",
  "description": "Atmospheric WebGL light rays background effect",
  "dependencies": {
    "ogl": "^1.0.11",
    "lucide-react": "latest",
    "framer-motion": "latest",
    "clsx": "latest",
    "tailwind-merge": "latest"
  }
}
~~~
~~~/src/Component.tsx
import { useRef, useEffect, useState } from 'react';
import { Renderer, Program, Triangle, Mesh } from 'ogl';
/**
 * LightRays Background Component
 *
 * A high-performance WebGL-based light ray effect that simulates atmospheric lighting.
 * Supports various origins, mouse following, and organic movement.
 */
export type RaysOrigin =
  | 'top-center'
  | 'top-left'
  | 'top-right'
  | 'right'
  | 'left'
  | 'bottom-center'
  | 'bottom-right'
  | 'bottom-left';
interface LightRaysProps {
  /** The starting point of the light rays */
  raysOrigin?: RaysOrigin;
  /** Primary color of the rays (hex) */
  raysColor?: string;
  /** Animation speed multiplier */
  raysSpeed?: number;
  /** Spread/width of the light beam */
  lightSpread?: number;
  /** Length of the rays relative to container size */
  rayLength?: number;
  /** Enable pulsing intensity */
  pulsating?: boolean;
  /** Distance before rays fade out */
  fadeDistance?: number;
  /** Color saturation (0 to 1) */
  saturation?: number;
  /** Whether rays should tilt towards the mouse */
  followMouse?: boolean;
  /** Intensity of mouse influence (0 to 1) */
  mouseInfluence?: number;
  /** Amount of grain/noise texture */
  noiseAmount?: number;
  /** Amount of wave distortion */
  distortion?: number;
  /** Additional CSS classes */
  className?: string;
}
const DEFAULT_COLOR = '#ffffff';
const hexToRgb = (hex: string): [number, number, number] => {
  const m = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  return m ? [parseInt(m[1], 16) / 255, parseInt(m[2], 16) / 255, parseInt(m[3], 16) / 255] : [1, 1, 1];
};
const getAnchorAndDir = (
  origin: RaysOrigin,
  w: number,
  h: number
): { anchor: [number, number]; dir: [number, number] } => {
  const outside = 0.2;
  switch (origin) {
    case 'top-left':
      return { anchor: [0, -outside * h], dir: [0.7, 0.7] };
    case 'top-right':
      return { anchor: [w, -outside * h], dir: [-0.7, 0.7] };
    case 'left':
      return { anchor: [-outside * w, 0.5 * h], dir: [1, 0] };
    case 'right':
      return { anchor: [(1 + outside) * w, 0.5 * h], dir: [-1, 0] };
    case 'bottom-left':
      return { anchor: [0, (1 + outside) * h], dir: [0.7, -0.7] };
    case 'bottom-center':
      return { anchor: [0.5 * w, (1 + outside) * h], dir: [0, -1] };
    case 'bottom-right':
      return { anchor: [w, (1 + outside) * h], dir: [-0.7, -0.7] };
    default: // "top-center"
      return { anchor: [0.5 * w, -outside * h], dir: [0, 1] };
  }
};
type Vec2 = [number, number];
type Vec3 = [number, number, number];
interface Uniforms {
  iTime: { value: number };
  iResolution: { value: Vec2 };
  rayPos: { value: Vec2 };
  rayDir: { value: Vec2 };
  raysColor: { value: Vec3 };
  raysSpeed: { value: number };
  lightSpread: { value: number };
  rayLength: { value: number };
  pulsating: { value: number };
  fadeDistance: { value: number };
  saturation: { value: number };
  mousePos: { value: Vec2 };
  mouseInfluence: { value: number };
  noiseAmount: { value: number };
  distortion: { value: number };
}
export function LightRays({
  raysOrigin = 'top-center',
  raysColor = DEFAULT_COLOR,
  raysSpeed = 1,
  lightSpread = 1,
  rayLength = 2,
  pulsating = false,
  fadeDistance = 1.0,
  saturation = 1.0,
  followMouse = true,
  mouseInfluence = 0.1,
  noiseAmount = 0.02,
  distortion = 0.05,
  className = ''
}: LightRaysProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const uniformsRef = useRef<Uniforms | null>(null);
  const rendererRef = useRef<Renderer | null>(null);
  const mouseRef = useRef({ x: 0.5, y: 0.5 });
  const smoothMouseRef = useRef({ x: 0.5, y: 0.5 });
  const animationIdRef = useRef<number | null>(null);
  const meshRef = useRef<Mesh | null>(null);
  const cleanupFunctionRef = useRef<(() => void) | null>(null);
  const [isVisible, setIsVisible] = useState(false);
  const observerRef = useRef<IntersectionObserver | null>(null);
  useEffect(() => {
    if (!containerRef.current) return;
    observerRef.current = new IntersectionObserver(
      entries => {
        const entry = entries[0];
        setIsVisible(entry.isIntersecting);
      },
      { threshold: 0.1 }
    );
    observerRef.current.observe(containerRef.current);
    return () => {
      if (observerRef.current) {
        observerRef.current.disconnect();
        observerRef.current = null;
      }
    };
  }, []);
  useEffect(() => {
    if (!isVisible || !containerRef.current) return;
    if (cleanupFunctionRef.current) {
      cleanupFunctionRef.current();
      cleanupFunctionRef.current = null;
    }
    const initializeWebGL = async () => {
      if (!containerRef.current) return;
      await new Promise(resolve => setTimeout(resolve, 10));
      if (!containerRef.current) return;
      const renderer = new Renderer({
        dpr: Math.min(window.devicePixelRatio, 2),
        alpha: true
      });
      rendererRef.current = renderer;
      const gl = renderer.gl;
      gl.canvas.style.width = '100%';
      gl.canvas.style.height = '100%';
      gl.canvas.style.display = 'block';
      while (containerRef.current.firstChild) {
        containerRef.current.removeChild(containerRef.current.firstChild);
      }
      containerRef.current.appendChild(gl.canvas);
      const vert = `
        attribute vec2 position;
        varying vec2 vUv;
        void main() {
          vUv = position * 0.5 + 0.5;
          gl_Position = vec4(position, 0.0, 1.0);
        }
      `;
      const frag = `
        precision highp float;
        uniform float iTime;
        uniform vec2  iResolution;
        uniform vec2  rayPos;
        uniform vec2  rayDir;
        uniform vec3  raysColor;
        uniform float raysSpeed;
        uniform float lightSpread;
        uniform float rayLength;
        uniform float pulsating;
        uniform float fadeDistance;
        uniform float saturation;
        uniform vec2  mousePos;
        uniform float mouseInfluence;
        uniform float noiseAmount;
        uniform float distortion;
        varying vec2 vUv;
        float noise(vec2 st) {
          return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123);
        }
        float rayStrength(vec2 raySource, vec2 rayRefDirection, vec2 coord,
                          float seedA, float seedB, float speed) {
          vec2 sourceToCoord = coord - raySource;
          vec2 dirNorm = normalize(sourceToCoord);
          float cosAngle = dot(dirNorm, rayRefDirection);
          float d = distortion * sin(iTime * 1.5 + length(sourceToCoord) * 0.005);
          float distortedAngle = cosAngle + d;
          float spreadFactor = pow(max(distortedAngle, 0.0), 1.0 / max(lightSpread, 0.001));
          float distance = length(sourceToCoord);
          float maxDistance = max(iResolution.x, iResolution.y) * rayLength;
          float lengthFalloff = clamp((maxDistance - distance) / maxDistance, 0.0, 1.0);
          float fadeFactor = fadeDistance * max(iResolution.x, iResolution.y);
          float fadeFalloff = clamp((fadeFactor - distance) / fadeFactor, 0.0, 1.0);
          float pulse = pulsating > 0.5 ? (0.85 + 0.15 * sin(iTime * speed * 4.0)) : 1.0;
          float baseStrength = clamp(
            (0.5 + 0.2 * sin(distortedAngle * seedA + iTime * speed)) +
            (0.3 + 0.2 * cos(-distortedAngle * seedB + iTime * speed * 0.8)),
            0.0, 1.0
          );
          return baseStrength * lengthFalloff * fadeFalloff * spreadFactor * pulse;
        }
        void main() {
          vec2 fragCoord = gl_FragCoord.xy;
          vec2 coord = vec2(fragCoord.x, fragCoord.y);
          vec2 finalRayDir = normalize(rayDir);
          if (mouseInfluence > 0.0) {
            vec2 mouseScreenPos = mousePos * iResolution.xy;
            vec2 mouseDirection = normalize(mouseScreenPos - rayPos);
            finalRayDir = normalize(mix(finalRayDir, mouseDirection, mouseInfluence));
          }
          float r1 = rayStrength(rayPos, finalRayDir, coord, 45.2, 31.4, 0.8 * raysSpeed);
          float r2 = rayStrength(rayPos, finalRayDir, coord, 28.5, 19.8, 1.2 * raysSpeed);
          float r3 = rayStrength(rayPos, finalRayDir, coord, 12.1, 56.2, 0.5 * raysSpeed);
          float combined = (r1 * 0.4 + r2 * 0.4 + r3 * 0.2);
          combined = pow(combined, 0.7); // Boost mid-tones for visibility
          combined *= 1.5; // Overall intensity boost
          vec3 finalColor = raysColor * combined;
          if (noiseAmount > 0.0) {
            float n = noise(coord * 0.01 + iTime * 0.05);
            finalColor *= (1.0 - noiseAmount + noiseAmount * n);
          }
          if (saturation != 1.0) {
            float gray = dot(finalColor, vec3(0.299, 0.587, 0.114));
            finalColor = mix(vec3(gray), finalColor, saturation);
          }
          gl_FragColor = vec4(finalColor, combined);
        }
      `;
      const uniforms: Uniforms = {
        iTime: { value: 0 },
        iResolution: { value: [1, 1] },
        rayPos: { value: [0, 0] },
        rayDir: { value: [0, 1] },
        raysColor: { value: hexToRgb(raysColor) },
        raysSpeed: { value: raysSpeed },
        lightSpread: { value: lightSpread },
        rayLength: { value: rayLength },
        pulsating: { value: pulsating ? 1.0 : 0.0 },
        fadeDistance: { value: fadeDistance },
        saturation: { value: saturation },
        mousePos: { value: [0.5, 0.5] },
        mouseInfluence: { value: mouseInfluence },
        noiseAmount: { value: noiseAmount },
        distortion: { value: distortion }
      };
      uniformsRef.current = uniforms;
      const geometry = new Triangle(gl);
      const program = new Program(gl, {
        vertex: vert,
        fragment: frag,
        uniforms,
        transparent: true
      });
      const mesh = new Mesh(gl, { geometry, program });
      meshRef.current = mesh;
      const updatePlacement = () => {
        if (!containerRef.current || !renderer) return;
        const { clientWidth: wCSS, clientHeight: hCSS } = containerRef.current;
        renderer.setSize(wCSS, hCSS);
        const dpr = renderer.dpr;
        const w = wCSS * dpr;
        const h = hCSS * dpr;
        uniforms.iResolution.value = [w, h];
        const { anchor, dir } = getAnchorAndDir(raysOrigin, w, h);
        uniforms.rayPos.value = anchor;
        uniforms.rayDir.value = dir;
      };
      const loop = (t: number) => {
        if (!rendererRef.current || !uniformsRef.current || !meshRef.current) return;
        uniforms.iTime.value = t * 0.001;
        if (followMouse && mouseInfluence > 0.0) {
          const smoothing = 0.95;
          smoothMouseRef.current.x = smoothMouseRef.current.x * smoothing + mouseRef.current.x * (1 - smoothing);
          smoothMouseRef.current.y = smoothMouseRef.current.y * smoothing + mouseRef.current.y * (1 - smoothing);
          uniforms.mousePos.value = [smoothMouseRef.current.x, 1.0 - smoothMouseRef.current.y];
        }
        renderer.render({ scene: mesh });
        animationIdRef.current = requestAnimationFrame(loop);
      };
      window.addEventListener('resize', updatePlacement);
      updatePlacement();
      animationIdRef.current = requestAnimationFrame(loop);
      cleanupFunctionRef.current = () => {
        if (animationIdRef.current) cancelAnimationFrame(animationIdRef.current);
        window.removeEventListener('resize', updatePlacement);
        if (renderer.gl.canvas.parentNode) {
          renderer.gl.canvas.parentNode.removeChild(renderer.gl.canvas);
        }
      };
    };
    initializeWebGL();
    return () => cleanupFunctionRef.current?.();
  }, [isVisible, raysOrigin, raysColor, raysSpeed, lightSpread, rayLength, pulsating, fadeDistance, saturation, followMouse, mouseInfluence, noiseAmount, distortion]);
  useEffect(() => {
    const handleMouseMove = (e: MouseEvent) => {
      if (!containerRef.current) return;
      const rect = containerRef.current.getBoundingClientRect();
      mouseRef.current = {
        x: (e.clientX - rect.left) / rect.width,
        y: (e.clientY - rect.top) / rect.height
      };
    };
    if (followMouse) {
      window.addEventListener('mousemove', handleMouseMove);
      return () => window.removeEventListener('mousemove', handleMouseMove);
    }
  }, [followMouse]);
  return (
    <div
      ref={containerRef}
      className={`absolute inset-0 w-full h-full pointer-events-none overflow-hidden ${className}`}
    />
  );
}
export default LightRays;
~~~
Implementation Guidelines
1. Analyze the component structure, styling, animation implementations
2. Review the component's arguments and state
3. Think through what is the best place to adopt this component/style into the design we are doing
4. Then adopt the component/design to our current system
Help me integrate this into my design

---
"Light Rays Background" from https://github.com/superdesigndev/superdesign-prompts (CC0-1.0). © Superdesign. prompts/light-rays-background @ 6c6090694520.
powered by Styledex — https://styledex.dev

Tokens

DTCG

{
  "$schema": "https://www.designtokens.org/schemas/2025.10/format.json",
  "$description": "Light Rays Background. \"Light Rays Background\" from https://github.com/superdesigndev/superdesign-prompts (CC0-1.0). © Superdesign. prompts/light-rays-background @ 6c6090694520.",
  "$extensions": {
    "dev.styledex": {
      "id": "superdesign-light-rays-background",
      "license": "CC0-1.0",
      "attribution": "\"Light Rays Background\" from https://github.com/superdesigndev/superdesign-prompts (CC0-1.0). © Superdesign. prompts/light-rays-background @ 6c6090694520.",
      "banner": "powered by Styledex — https://styledex.dev"
    }
  },
  "color": {
    "background": {
      "$type": "color",
      "$value": "#ffffff"
    },
    "foreground": {
      "$type": "color",
      "$value": "#1a1a1b"
    },
    "card": {
      "$type": "color",
      "$value": "#ffffff"
    },
    "card-foreground": {
      "$type": "color",
      "$value": "#1a1a1b"
    },
    "primary": {
      "$type": "color",
      "$value": "#00ffff"
    },
    "primary-foreground": {
      "$type": "color",
      "$value": "#1c1917"
    },
    "secondary": {
      "$type": "color",
      "$value": "#1a1a1b"
    },
    "secondary-foreground": {
      "$type": "color",
      "$value": "#1a1a1b"
    },
    "accent": {
      "$type": "color",
      "$value": "#00ffff"
    },
    "accent-foreground": {
      "$type": "color",
      "$value": "#1c1917"
    },
    "muted": {
      "$type": "color",
      "$value": "#f0f0f0"
    },
    "muted-foreground": {
      "$type": "color",
      "$value": "#6a6a6b"
    },
    "border": {
      "$type": "color",
      "$value": "#dbdbdb"
    },
    "destructive": {
      "$type": "color",
      "$value": "#dc2626"
    },
    "ring": {
      "$type": "color",
      "$value": "#00ffff"
    }
  },
  "font": {
    "sans": {
      "$type": "fontFamily",
      "$value": [
        "ui-sans-serif",
        "system-ui",
        "sans-serif"
      ]
    },
    "serif": {
      "$type": "fontFamily",
      "$value": [
        "ui-serif",
        "Georgia",
        "serif"
      ]
    },
    "mono": {
      "$type": "fontFamily",
      "$value": [
        "ui-monospace",
        "SFMono-Regular",
        "Menlo",
        "monospace"
      ]
    }
  },
  "radius": {
    "base": {
      "$type": "dimension",
      "$value": "0.5rem"
    }
  },
  "spacing": {
    "base": {
      "$type": "dimension",
      "$value": "1rem"
    }
  },
  "shadow": {
    "base": {
      "$type": "shadow",
      "$value": "0 1px 2px rgba(0,0,0,0.06), 0 8px 24px rgba(0,0,0,0.04)"
    }
  }
}

CSS

/* powered by Styledex — https://styledex.dev */
/* "Light Rays Background" from https://github.com/superdesigndev/superdesign-prompts (CC0-1.0). © Superdesign. prompts/light-rays-background @ 6c6090694520. */
:root {
  --background: #ffffff;
  --foreground: #1a1a1b;
  --card: #ffffff;
  --card-foreground: #1a1a1b;
  --primary: #00ffff;
  --primary-foreground: #1c1917;
  --secondary: #1a1a1b;
  --secondary-foreground: #1a1a1b;
  --accent: #00ffff;
  --accent-foreground: #1c1917;
  --muted: #f0f0f0;
  --muted-foreground: #6a6a6b;
  --border: #dbdbdb;
  --destructive: #dc2626;
  --ring: #00ffff;
  --radius: 0.5rem;
  --font-sans: ui-sans-serif, system-ui, sans-serif;
  --font-serif: ui-serif, Georgia, serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
  --spacing: 1rem;
  --shadow: 0 1px 2px rgba(0,0,0,0.06), 0 8px 24px rgba(0,0,0,0.04);
}

Tailwind

/* powered by Styledex — https://styledex.dev */
/* "Light Rays Background" from https://github.com/superdesigndev/superdesign-prompts (CC0-1.0). © Superdesign. prompts/light-rays-background @ 6c6090694520. */
/** Tailwind theme extend for Light Rays Background (superdesign-light-rays-background) */
module.exports = {
  "theme": {
    "extend": {
      "colors": {
        "background": "#ffffff",
        "foreground": "#1a1a1b",
        "card": "#ffffff",
        "primary": "#00ffff",
        "primary-foreground": "#1c1917",
        "secondary": "#1a1a1b",
        "accent": "#00ffff",
        "muted": "#f0f0f0",
        "border": "#dbdbdb",
        "destructive": "#dc2626",
        "ring": "#00ffff"
      },
      "borderRadius": {
        "lg": "0.5rem"
      },
      "fontFamily": {
        "sans": [
          "ui-sans-serif",
          "system-ui",
          "sans-serif"
        ],
        "serif": [
          "ui-serif",
          "Georgia",
          "serif"
        ],
        "mono": [
          "ui-monospace",
          "SFMono-Regular",
          "Menlo",
          "monospace"
        ]
      },
      "boxShadow": {
        "styledex": "0 1px 2px rgba(0,0,0,0.06), 0 8px 24px rgba(0,0,0,0.04)"
      }
    }
  }
};

shadcn

/* powered by Styledex — https://styledex.dev */
/* "Light Rays Background" from https://github.com/superdesigndev/superdesign-prompts (CC0-1.0). © Superdesign. prompts/light-rays-background @ 6c6090694520. */
@layer base {
:root {
  --background: #ffffff;
  --foreground: #1a1a1b;
  --card: #ffffff;
  --card-foreground: #1a1a1b;
  --primary: #00ffff;
  --primary-foreground: #1c1917;
  --secondary: #1a1a1b;
  --secondary-foreground: #1a1a1b;
  --accent: #00ffff;
  --accent-foreground: #1c1917;
  --muted: #f0f0f0;
  --muted-foreground: #6a6a6b;
  --border: #dbdbdb;
  --destructive: #dc2626;
  --ring: #00ffff;
  --radius: 0.5rem;
  --font-sans: ui-sans-serif, system-ui, sans-serif;
  --font-serif: ui-serif, Georgia, serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
  --spacing: 1rem;
  --shadow: 0 1px 2px rgba(0,0,0,0.06), 0 8px 24px rgba(0,0,0,0.04);
}
}