- Adopt BoardUI (Pro init): theme tokens, Inter, .dark mode, Button, SegmentedControl, Meter, Skeleton and ThemeToggle; remap the app's color aliases onto BoardUI tokens and swap lucide for Remix icons - Retint BoardUI's neutral ramp to cool slate with a salmon accent; drop the dotted background; raise muted text contrast - Simplify the landing page and remove the overlap explorer - Planner: explicit "I have this" toggle on grocery lines, pantry panel above the menu with the staples list spelled out, sticky aisle header fix, and a "Download PDF" plan export (jsPDF, lazy-loaded) - Recipes: replace the family cabbage soup with Cade's Cabbage Soup (adds Bone-In Ham Steak to the catalog); remove Ham, Bean & Cabbage Soup - Remove unused BoardUI components, dependencies and exports Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
222 lines
6.9 KiB
CSS
222 lines
6.9 KiB
CSS
@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 <dialog> 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;
|
|
}
|
|
}
|