@import "../styles/globals.css"; /* --------------------------------------------------------------------------- Plan my Meals BoardUI theme: cool slate neutrals with a salmon accent. BoardUI's surfaces, text and borders all read the neutral ramp, and every CTA / selection / focus state reads the accent ramp, so retinting these two ramps restyles the whole system (BoardUI's documented re-tint point). Accent 500/600 stay dark enough for white button labels (>= 4.5:1 blended). --------------------------------------------------------------------------- */ @theme { --color-neutral-50: oklch(98.4% 0.003 247.9); --color-neutral-100: oklch(97.4% 0.005 247.9); --color-neutral-200: oklch(93.8% 0.010 252.0); --color-neutral-300: oklch(86.9% 0.020 252.9); --color-neutral-400: oklch(70.4% 0.034 256.8); --color-neutral-500: oklch(55.4% 0.040 257.4); --color-neutral-600: oklch(44.6% 0.038 257.3); --color-neutral-700: oklch(37.2% 0.036 257.3); --color-neutral-800: oklch(26.5% 0.032 260.0); --color-neutral-900: oklch(20.5% 0.030 262.0); --color-neutral-925: oklch(16.5% 0.028 263.0); --color-neutral-950: oklch(13.0% 0.026 264.7); --color-accent-50: oklch(97.3% 0.013 27); --color-accent-100: oklch(94.0% 0.030 27); --color-accent-200: oklch(88.5% 0.060 28); --color-accent-300: oklch(81.5% 0.100 29); --color-accent-400: oklch(72.5% 0.140 30); --color-accent-500: oklch(60.5% 0.155 31); --color-accent-600: oklch(53.5% 0.150 32); --color-accent-700: oklch(46.5% 0.130 32); --color-accent-800: oklch(39.5% 0.105 32); --color-accent-900: oklch(32.0% 0.080 31); --color-accent-950: oklch(23.0% 0.055 30); } /* --------------------------------------------------------------------------- App token aliases → BoardUI semantic tokens. The app's components were written against these names; pointing them at BoardUI's tokens gives every screen the BoardUI look and its `.dark` flip. `inline` makes each utility read the BoardUI variable where it is used. --------------------------------------------------------------------------- */ @theme inline { --color-canvas: var(--color-background-full); --color-surface: var(--color-background-primary-default); --color-raised: var(--color-background-secondary-default); --color-line: var(--color-separator-border); --color-line-strong: var(--color-border-button-hover); --color-ink: var(--color-text-primary); /* BoardUI's text-tertiary (neutral-400 light / 600 dark) is ~2.5:1, too faint for body copy, so the app's two quiet text levels use their own steps that stay >= 4.5:1 (set below). */ --color-ink-muted: var(--pm-ink-muted); --color-ink-faint: var(--pm-ink-faint); /* Accent: BoardUI's accent ramp; text-on-surface uses the ghost foreground, which flips in dark. */ --color-brand-300: var(--color-button-ghost-foreground); --color-brand-600: var(--color-accent-500); --color-brand-950: var(--color-button-ghost-background); --color-brand-border: color-mix(in oklab, var(--color-accent-500) 45%, transparent); --color-on-accent: var(--color-text-white); --color-selected: var(--color-background-tertiary-default); --color-selected-line: var(--color-accent-500); --color-status-ok: var(--color-notification-success-foreground); --color-status-ok-bg: var(--color-notification-success-background); --color-status-ok-line: color-mix(in oklab, var(--color-notification-success-foreground) 45%, transparent); --color-status-warn: var(--color-status-yellow-text); --color-status-warn-bg: var(--color-status-yellow-background); --color-status-warn-line: color-mix(in oklab, var(--color-status-yellow-text) 45%, transparent); --color-status-danger: var(--color-notification-error-foreground); --color-status-danger-bg: var(--color-notification-error-background); --color-status-danger-line: color-mix(in oklab, var(--color-notification-error-foreground) 45%, transparent); /* BoardUI is single-family (Inter); the old serif display voice folds into it. */ --font-serif: var(--font-sans); } :root { --pm-ink-muted: var(--color-neutral-600); --pm-ink-faint: var(--color-neutral-500); } .dark { --pm-ink-muted: var(--color-neutral-300); --pm-ink-faint: var(--color-neutral-400); } @theme { /* Animations */ --animate-fade-in: fade-in 0.35s cubic-bezier(0.16, 1, 0.3, 1); --animate-preview-timer: preview-timer 1s linear forwards; @keyframes fade-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } } @keyframes preview-timer { from { transform: scaleX(0); } to { transform: scaleX(1); } } } @view-transition { navigation: auto; } @layer base { html { color-scheme: light; } html.dark { color-scheme: dark; } body { @apply bg-canvas text-ink antialiased selection:bg-brand-950 selection:text-ink; } /* Visible focus for keyboard users on every interactive element. */ :where(button, a, input, select, summary, [tabindex]):focus-visible { @apply outline-2 outline-offset-2 outline-border-focus-ring; } input[type="range"] { @apply accent-brand-600; } input:not([type="range"], [type="checkbox"]) { @apply bg-surface text-ink placeholder:text-ink-faint; } /* Native spring entry/exit via 2026 Baseline @starting-style */ dialog { color: var(--color-ink); transition: opacity 0.22s cubic-bezier(0.16, 1, 0.3, 1), transform 0.26s cubic-bezier(0.16, 1, 0.3, 1), display 0.26s allow-discrete, overlay 0.26s allow-discrete; opacity: 0; transform: translateY(14px) scale(0.985); } dialog[open] { opacity: 1; transform: translateY(0) scale(1); @starting-style { opacity: 0; transform: translateY(14px) scale(0.985); } } dialog.sheet-dialog { transform: translateY(100%); } dialog.sheet-dialog[open] { transform: translateY(0); @starting-style { transform: translateY(100%); } } dialog::backdrop { background-color: rgb(10 14 18 / 0); backdrop-filter: blur(0px); transition: background-color 0.24s ease, backdrop-filter 0.24s ease, display 0.24s allow-discrete, overlay 0.24s allow-discrete; } dialog[open]::backdrop { background-color: rgb(10 14 18 / 0.55); backdrop-filter: blur(2px); @starting-style { background-color: rgb(10 14 18 / 0); backdrop-filter: blur(0px); } } } /* 2026 CSS optical cap-height trimming for buttons, badges & chips */ .trim-cap { text-box-trim: trim-both; text-box-edge: cap alphabetic; } /* Market receipt serrated / perforated divider feel */ .receipt-rule { border-top: 1px dashed var(--color-line-strong); } /* Respect the OS "reduce motion" setting everywhere. */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; } }