@import "tailwindcss"; @plugin "@tailwindcss/typography"; @custom-variant dark (&:where(.dark, .dark *)); /* ───────────────────────────────────────────────────────────────────────── * Spacing scale: locked. * Card padding: p-6. Section gap: space-y-8. Form/control gap: gap-4. * Allowed Tailwind values: 1, 2, 3, 4, 6, 8, 10, 12. No 2.5 / 5. * Sidebar width is md:w-64 (256px); main offset matches md:pl-64. * ───────────────────────────────────────────────────────────────────────── */ :root { color-scheme: light; /* Grayscale Chrome Palette: paper white + warm beige */ --background: 0 0% 100%; --foreground: 0 0% 9%; --card: 0 0% 100%; --card-foreground: 0 0% 9%; --popover: 0 0% 100%; --popover-foreground: 0 0% 9%; --primary: 0 0% 9%; --primary-foreground: 0 0% 100%; --secondary: 40 11% 89%; /* Warm beige paper chip */ --secondary-foreground: 0 0% 9%; --muted: 40 8% 93%; --muted-foreground: 0 0% 40%; --accent: 40 8% 93%; --accent-foreground: 0 0% 9%; --destructive: 6 36% 48%; /* Muted terracotta */ --destructive-foreground: 0 0% 100%; --border: 45 5% 85%; --input: 45 5% 85%; --ring: 0 0% 9%; /* Radius */ --radius: 0.5rem; /* Success: Sage green */ --success: 155 25% 40%; --success-foreground: 0 0% 100%; /* Warning: Muted ochre */ --warning: 38 55% 50%; --warning-foreground: 0 0% 9%; --warm-accent: 38 45% 52%; /* Chart colors */ --chart-1: 155 25% 40%; --chart-2: 6 36% 48%; --chart-3: 38 55% 50%; --chart-4: 0 0% 50%; /* Custom tokens */ --font-display: var(--font-hedvig-serif), Georgia, serif; --font-body: var(--font-geist-sans), system-ui, sans-serif; /* Shadows: barely-there; chrome relies on hairline borders */ --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.03), 0 1px 1px rgba(15, 23, 42, 0.02); --shadow-md: 0 4px 12px rgba(15, 23, 42, 0.03); --shadow-lg: 0 12px 40px rgba(15, 23, 42, 0.05); /* Animation */ --ease-out: cubic-bezier(0.25, 0.46, 0.45, 0.94); --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1); --duration-fast: 150ms; --duration-base: 300ms; --duration-slow: 500ms; } .dark { color-scheme: dark; --background: 0 0% 7%; --foreground: 0 0% 87%; --card: 0 0% 11%; --card-foreground: 0 0% 87%; --popover: 0 0% 11%; --popover-foreground: 0 0% 87%; --primary: 0 0% 87%; --primary-foreground: 0 0% 7%; --secondary: 0 0% 14%; --secondary-foreground: 0 0% 87%; --muted: 0 0% 16%; --muted-foreground: 0 0% 50%; --accent: 0 0% 16%; --accent-foreground: 0 0% 87%; --destructive: 6 32% 56%; --destructive-foreground: 0 0% 100%; --border: 45 4% 18%; --input: 45 4% 18%; --ring: 0 0% 87%; --success: 155 22% 48%; --success-foreground: 0 0% 100%; --warning: 38 50% 55%; --warning-foreground: 38 50% 90%; --warm-accent: 38 42% 58%; --chart-1: 155 22% 48%; --chart-2: 6 32% 56%; --chart-3: 38 50% 55%; --chart-4: 0 0% 55%; --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.25); --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35); --shadow-lg: 0 12px 40px rgba(0, 0, 0, 0.45); } @theme inline { --color-background: hsl(var(--background)); --color-foreground: hsl(var(--foreground)); --color-card: hsl(var(--card)); --color-card-foreground: hsl(var(--card-foreground)); --color-popover: hsl(var(--popover)); --color-popover-foreground: hsl(var(--popover-foreground)); --color-primary: hsl(var(--primary)); --color-primary-foreground: hsl(var(--primary-foreground)); --color-secondary: hsl(var(--secondary)); --color-secondary-foreground: hsl(var(--secondary-foreground)); --color-muted: hsl(var(--muted)); --color-muted-foreground: hsl(var(--muted-foreground)); --color-accent: hsl(var(--accent)); --color-accent-foreground: hsl(var(--accent-foreground)); --color-destructive: hsl(var(--destructive)); --color-destructive-foreground: hsl(var(--destructive-foreground)); --color-border: hsl(var(--border)); --color-input: hsl(var(--input)); --color-ring: hsl(var(--ring)); --color-success: hsl(var(--success)); --color-success-foreground: hsl(var(--success-foreground)); --color-warning: hsl(var(--warning)); --color-warning-foreground: hsl(var(--warning-foreground)); --color-warm-accent: hsl(var(--warm-accent)); --radius-lg: var(--radius); --radius-md: calc(var(--radius) - 2px); --radius-sm: calc(var(--radius) - 4px); --font-sans: var(--font-body); --font-mono: var(--font-geist-mono), monospace; --font-serif: var(--font-display); } * { border-color: hsl(var(--border)); } body { background-color: hsl(var(--background)); color: hsl(var(--foreground)); font-family: var(--font-body); font-feature-settings: "cv02", "cv03", "cv04", "cv11"; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* Display typography - Fraunces */ .font-display { font-family: var(--font-display); font-optical-sizing: auto; } h1, h2, h3 { font-family: var(--font-display); font-weight: 500; letter-spacing: -0.015em; font-optical-sizing: auto; } /* Number styling - tabular for alignment */ .tabular-nums { font-variant-numeric: tabular-nums; } /* Text balance for better line wrapping on descriptions */ .text-balance { text-wrap: balance; } /* Safe area padding for mobile devices with notch/home indicator */ .safe-area-bottom { padding-bottom: max(0.5rem, env(safe-area-inset-bottom)); } /* Main content padding: clears bottom nav + safe area on mobile */ .safe-area-main-padding { padding-bottom: calc(5rem + env(safe-area-inset-bottom, 0px)); } /* Animation Keyframes */ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes slideUp { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } } @keyframes slideInLeft { from { opacity: 0; transform: translateX(-8px); } to { opacity: 1; transform: translateX(0); } } @keyframes scaleIn { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } } @keyframes gentlePulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } } /* Three-dot "typing" indicator used by the agent chat pre-token bubble. Each dot rides the same wave but with staggered animation-delay so the bounce reads left-to-right. */ @keyframes typingDot { 0%, 60%, 100% { transform: translateY(0); opacity: 0.35; } 30% { transform: translateY(-3px); opacity: 1; } } .animate-typing-dot { animation: typingDot 1.1s ease-in-out infinite; } @media (prefers-reduced-motion: reduce) { .animate-typing-dot { animation: gentlePulse 1.6s ease-in-out infinite; transform: none; } } /* Staggered entrance animation */ .stagger-enter > * { animation: slideUp var(--duration-slow) var(--ease-out) both; } .stagger-enter > *:nth-child(1) { animation-delay: 0ms; } .stagger-enter > *:nth-child(2) { animation-delay: 80ms; } .stagger-enter > *:nth-child(3) { animation-delay: 160ms; } .stagger-enter > *:nth-child(4) { animation-delay: 240ms; } .stagger-enter > *:nth-child(5) { animation-delay: 320ms; } .stagger-enter > *:nth-child(6) { animation-delay: 400ms; } .stagger-enter > *:nth-child(7) { animation-delay: 480ms; } .stagger-enter > *:nth-child(8) { animation-delay: 560ms; } .stagger-enter > *:nth-child(9) { animation-delay: 640ms; } .stagger-enter > *:nth-child(10) { animation-delay: 720ms; } /* Utility animations */ .animate-fade-in { animation: fadeIn var(--duration-base) var(--ease-out); } .animate-slide-up { animation: slideUp var(--duration-slow) var(--ease-out); } .animate-scale-in { animation: scaleIn var(--duration-base) var(--ease-out); } /* Soft focus states */ .focus-ring:focus-visible { outline: none; box-shadow: 0 0 0 2px hsl(var(--background)), 0 0 0 4px hsl(var(--primary) / 0.35); } /* Custom scrollbar - minimal */ ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: hsl(var(--muted-foreground) / 0.2); border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { background: hsl(var(--muted-foreground) / 0.3); } /* Hide scrollbar utility */ .scrollbar-hide { -ms-overflow-style: none; scrollbar-width: none; } .scrollbar-hide::-webkit-scrollbar { display: none; } /* Hide number input spinners */ input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } input[type="number"] { -moz-appearance: textfield; } /* Selection color */ ::selection { background: hsl(var(--primary) / 0.15); color: hsl(var(--foreground)); } .dark ::selection { background: hsl(var(--primary) / 0.3); color: hsl(var(--foreground)); } /* Respect reduced motion preference */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } .stagger-enter > * { animation: none; opacity: 1; } }