/** * Sport Store — shared design tokens (Tailwind CSS v4, CSS-first configuration). * * This file is the SINGLE source of truth for the visual language of both the * storefront and the admin dashboard. Apps import it after `@import "tailwindcss"`. * * Direction: modern, premium, minimal, sport-oriented (Nike / Gymshark spirit). * High-contrast neutrals, one energetic accent, generous whitespace, tight type. */ @theme { /* ---- Brand ------------------------------------------------------------ */ /* Near-black ink, not pure black: prints and photographs better. */ --color-ink-50: oklch(0.98 0.002 260); --color-ink-100: oklch(0.95 0.003 260); --color-ink-200: oklch(0.89 0.004 260); --color-ink-300: oklch(0.78 0.005 260); --color-ink-400: oklch(0.63 0.006 260); --color-ink-500: oklch(0.51 0.007 260); --color-ink-600: oklch(0.41 0.008 260); --color-ink-700: oklch(0.32 0.009 260); --color-ink-800: oklch(0.23 0.01 260); --color-ink-900: oklch(0.16 0.011 260); --color-ink-950: oklch(0.11 0.012 260); /* Energetic accent — "volt". Used sparingly: CTAs, price, sale badges. */ --color-volt-50: oklch(0.97 0.06 125); --color-volt-100: oklch(0.94 0.11 125); --color-volt-200: oklch(0.9 0.16 125); --color-volt-300: oklch(0.86 0.2 125); --color-volt-400: oklch(0.82 0.23 125); --color-volt-500: oklch(0.76 0.24 125); --color-volt-600: oklch(0.66 0.21 125); --color-volt-700: oklch(0.54 0.17 125); --color-volt-800: oklch(0.43 0.13 125); --color-volt-900: oklch(0.35 0.1 125); /* Semantic */ --color-sale: oklch(0.58 0.21 27); --color-success: oklch(0.65 0.16 155); --color-warning: oklch(0.78 0.15 80); --color-danger: oklch(0.58 0.22 27); /* ---- Typography ------------------------------------------------------- */ --font-sans: var(--font-inter), ui-sans-serif, system-ui, -apple-system, sans-serif; --font-display: var(--font-display), var(--font-inter), ui-sans-serif, system-ui, sans-serif; --font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace; --tracking-display: -0.03em; /* ---- Layout ----------------------------------------------------------- */ --spacing-gutter: 1.25rem; --container-page: 90rem; --radius-card: 0.25rem; --radius-pill: 999px; /* ---- Motion ----------------------------------------------------------- */ --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1); --animate-rise: rise 0.5s var(--ease-out-quint) both; } /** * ---- shadcn/ui semantic layer -------------------------------------------- * * shadcn components are written against role tokens (`bg-background`, * `text-muted-foreground`, `border-input`, `ring-ring`) rather than against a * palette. This block is the adapter: it gives those roles values drawn from * the ink/volt scales above, so an unmodified component pasted from the * registry already looks like this store. * * ONE TRAP WORTH NAMING: shadcn's `--accent` is not a brand accent. It is the * subtle surface behind a hovered ghost button or a highlighted menu row. It * maps to ink-100. The brand accent stays `--color-volt-*` and is applied * deliberately — mapping volt here would turn every hover state neon. * * The store is committed to a light palette (`color-scheme: light`), so there * is no `.dark` block. shadcn's `dark:` utilities simply never match, which is * harmless and keeps the registry components paste-able unedited. */ :root { --background: var(--color-white); --foreground: var(--color-ink-950); --card: var(--color-white); --card-foreground: var(--color-ink-950); --popover: var(--color-white); --popover-foreground: var(--color-ink-950); --primary: var(--color-ink-950); --primary-foreground: var(--color-white); --secondary: var(--color-ink-100); --secondary-foreground: var(--color-ink-950); --muted: var(--color-ink-100); --muted-foreground: var(--color-ink-500); /* Hover/active surface — see the trap noted above. */ --accent: var(--color-ink-100); --accent-foreground: var(--color-ink-950); --destructive: var(--color-danger); --destructive-foreground: var(--color-white); --border: var(--color-ink-200); --input: var(--color-ink-200); --ring: var(--color-ink-950); /* Sport/streetwear geometry: near-square. Raising this rounds every registry component at once, which is the point of keeping it here. */ --radius: 0.25rem; } @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); --color-card: var(--card); --color-card-foreground: var(--card-foreground); --color-popover: var(--popover); --color-popover-foreground: var(--popover-foreground); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-secondary: var(--secondary); --color-secondary-foreground: var(--secondary-foreground); --color-muted: var(--muted); --color-muted-foreground: var(--muted-foreground); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-destructive: var(--destructive); --color-destructive-foreground: var(--destructive-foreground); --color-border: var(--border); --color-input: var(--input); --color-ring: var(--ring); --radius-sm: calc(var(--radius) - 2px); --radius-md: var(--radius); --radius-lg: calc(var(--radius) + 2px); --radius-xl: calc(var(--radius) + 6px); } @keyframes rise { from { opacity: 0; transform: translateY(0.75rem); } to { opacity: 1; transform: none; } } @layer base { :root { color-scheme: light; } html { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; } /* Sport/streetwear headings: tight, uppercase-capable, no letterspacing drift. */ h1, h2, h3 { letter-spacing: var(--tracking-display); text-wrap: balance; } ::selection { background-color: var(--color-volt-300); color: var(--color-ink-950); } }