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

View file

@ -1,21 +1,10 @@
import type { Metadata, Viewport } from "next";
import { Fraunces, JetBrains_Mono, Plus_Jakarta_Sans } from "next/font/google";
import { Inter, JetBrains_Mono } from "next/font/google";
import "./globals.css";
const jakarta = Plus_Jakarta_Sans({
variable: "--font-jakarta",
subsets: ["latin"],
});
const fraunces = Fraunces({
variable: "--font-fraunces",
subsets: ["latin"],
});
const jetbrainsMono = JetBrains_Mono({
variable: "--font-jb-mono",
subsets: ["latin"],
});
// BoardUI's theme reads --font-inter (sans) and --font-mono-source (mono).
const inter = Inter({ variable: "--font-inter", subsets: ["latin"], axes: ["opsz"] });
const jetbrainsMono = JetBrains_Mono({ variable: "--font-mono-source", subsets: ["latin"] });
export const metadata: Metadata = {
// Pages set just their own name ("Recipes"); the template adds the app name.
@ -25,20 +14,22 @@ export const metadata: Metadata = {
export const viewport: Viewport = {
themeColor: [
{ media: "(prefers-color-scheme: light)", color: "#faf6ef" },
{ media: "(prefers-color-scheme: dark)", color: "#0e171f" },
{ media: "(prefers-color-scheme: light)", color: "#ffffff" },
{ media: "(prefers-color-scheme: dark)", color: "#0d1219" },
],
};
const THEME_INIT_SCRIPT = `(function(){try{var t=localStorage.getItem("plan-my-meals:theme");if(t==="light"||t==="dark")document.documentElement.dataset.theme=t;}catch(e){}})();`;
// Runs before paint so the BoardUI `.dark` class is set without a flash. Carries over the
// pre-BoardUI "plan-my-meals:theme" choice once so returning users keep their theme.
const THEME_INIT_SCRIPT = `(function(){try{var s=localStorage,t=s.getItem("boardui:theme");if(!t){t=s.getItem("plan-my-meals:theme");if(t)s.setItem("boardui:theme",t);}if(t==="dark")document.documentElement.classList.add("dark");}catch(e){}})();`;
export default function RootLayout({ children }: LayoutProps<"/">) {
return (
<html lang="en" suppressHydrationWarning className={`${jakarta.variable} ${fraunces.variable} ${jetbrainsMono.variable}`}>
<html lang="en" suppressHydrationWarning className={`${inter.variable} ${jetbrainsMono.variable} antialiased`}>
<head>
<script dangerouslySetInnerHTML={{ __html: THEME_INIT_SCRIPT }} />
</head>
<body className="min-h-dvh font-sans">{children}</body>
<body className="min-h-dvh bg-background-full font-sans text-text-primary">{children}</body>
</html>
);
}