Move UI to BoardUI with slate + salmon theme; add PDF plan export

- 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>
This commit is contained in:
Cayden Schwechten 2026-11-06 16:36:33 -06:00
parent b02c7a024b
commit df5dd3a70e
56 changed files with 4749 additions and 788 deletions

61
utils/cx.ts Normal file
View file

@ -0,0 +1,61 @@
import { extendTailwindMerge } from "tailwind-merge";
/**
* Text-style classes from styles/typography.css.
*
* IMPORTANT: every text-* utility we define via @theme (e.g. `text-body-medium`,
* `text-title-1-semibold`) must be listed here. Otherwise tailwind-merge — which
* has no view of our Tailwind theme — treats them as text-color utilities and
* silently drops them when they appear in the same className as a real color
* (`text-foreground-full`, `text-text-primary`, etc).
*
* If you add or rename a text style in typography.css, mirror the change here.
*/
const TEXT_FAMILIES = [
"large-title",
"display-1",
"display-2",
"display-3",
"display-4",
"title-1",
"title-2",
"title-3",
"headline",
"body",
"body-2",
"caption-1",
"caption-2",
] as const;
const TEXT_WEIGHTS = ["regular", "medium", "semibold", "bold"] as const;
const TEXT_STYLE_SUFFIXES = TEXT_FAMILIES.flatMap((family) =>
TEXT_WEIGHTS.map((weight) => `${family}-${weight}`),
);
const twMerge = extendTailwindMerge({
extend: {
classGroups: {
"font-size": [{ text: TEXT_STYLE_SUFFIXES }],
},
},
});
/**
* Merge Tailwind classes safely. Last-write-wins on conflicting utilities.
*/
export const cx = twMerge;
/**
* Identity helper that gives the Tailwind IntelliSense extension a hook for
* sorting classes inside style objects (the extension doesn't sort inside
* plain object literals otherwise).
*/
export function sortCx<
T extends Record<
string,
string | number | Record<string, string | number | Record<string, string | number>>
>,
>(classes: T): T {
return classes;
}