Files
server-26/drb-frontend/tailwind.config.ts
T
Logan CusanoandClaude Opus 5.5 7cd289874a frontend: Iris palette — graphite neutrals + indigo-violet accent
Tokens in globals.css, Tailwind gray/indigo scales remapped so the ~350
legacy raw-class uses follow the palette, light-mode override sheet moved
off slate, map accent hexes updated. Severity hues retuned for AA.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 21:38:59 -05:00

81 lines
3.5 KiB
TypeScript

import type { Config } from "tailwindcss";
const tok = (name: string) =>
`color-mix(in srgb, var(--${name}) calc(<alpha-value> * 100%), transparent)`;
const config: Config = {
content: [
"./app/**/*.{ts,tsx}",
"./components/**/*.{ts,tsx}",
],
darkMode: ["class"],
theme: {
extend: {
fontFamily: {
mono: ["var(--font-mono)", "ui-monospace", "Cascadia Code", "Source Code Pro", "monospace"],
sans: ["var(--font-sans)", "ui-sans-serif", "system-ui", "-apple-system", "Segoe UI", "Roboto", "Helvetica Neue", "Arial", "sans-serif"],
},
// Semantic tokens — defined as CSS custom properties in app/globals.css on
// :root (light) and .dark (dark). Components must use these names, never a
// raw gray-9xx, so a theme is one variable block rather than an override sheet.
// Wrapped in color-mix so opacity modifiers (bg-surface/90, bg-accent/15)
// work — a bare var() hex gives Tailwind nothing to apply alpha to, and the
// class silently generates no rule (map overlays rendered see-through).
colors: {
// "Iris" palette: the legacy raw gray-*/indigo-* classes (~350 uses)
// resolve to graphite + the brand accent instead of Tailwind's slate-blue
// defaults, so un-migrated components match the tokens above.
gray: {
50: "#F7F7F8", 100: "#EDEDEF", 200: "#E4E4E7", 300: "#C9C9D0", 400: "#A1A1AA",
500: "#7A7A85", 600: "#4A4B53", 700: "#2A2B31", 800: "#1A1B1F", 900: "#111214", 950: "#08090A",
},
indigo: {
50: "#F0F1FD", 100: "#E2E4FB", 200: "#C8CCF6", 300: "#A8AEF1", 400: "#8B93F0",
500: "#6F79E0", 600: "#5E6AD2", 700: "#4E58B8", 800: "#3F4794", 900: "#313770", 950: "#1C1F42",
},
page: tok("page"),
surface: tok("surface"),
raised: tok("raised"),
line: tok("line"),
"line-strong": tok("line-strong"),
ink: {
DEFAULT: tok("ink"),
2: tok("ink-2"),
muted: tok("ink-muted"),
},
accent: tok("accent"),
"sev-moderate": tok("sev-moderate"),
"sev-major": tok("sev-major"),
"map-bg": tok("map-bg"),
"map-block": tok("map-block"),
"map-road": tok("map-road"),
"map-water": tok("map-water"),
},
// Marketing/product type scale — used by the (marketing) surface and
// settings shell so headings read as a deliberate hierarchy rather than
// ad-hoc text-xl/text-2xl bumps.
fontSize: {
"display-lg": ["3.5rem", { lineHeight: "1.05", letterSpacing: "-0.02em", fontWeight: "700" }],
"display": ["2.75rem", { lineHeight: "1.1", letterSpacing: "-0.02em", fontWeight: "700" }],
"display-sm": ["2.125rem", { lineHeight: "1.15", letterSpacing: "-0.01em", fontWeight: "700" }],
},
boxShadow: {
card: "0 1px 2px 0 rgb(0 0 0 / 0.4), 0 1px 3px 0 rgb(0 0 0 / 0.3)",
"card-hover": "0 4px 12px 0 rgb(0 0 0 / 0.45), 0 2px 4px 0 rgb(0 0 0 / 0.3)",
glow: "0 0 0 1px rgb(94 106 210 / 0.4), 0 0 24px 0 rgb(94 106 210 / 0.25)",
},
animation: {
"fade-in": "fade-in 0.4s ease-out",
"slide-up": "slide-up 0.4s ease-out",
},
keyframes: {
"fade-in": { from: { opacity: "0" }, to: { opacity: "1" } },
"slide-up": { from: { opacity: "0", transform: "translateY(8px)" }, to: { opacity: "1", transform: "translateY(0)" } },
},
},
},
plugins: [],
};
export default config;