From f563f0ae10d88cb8c82a5face4b3cb686b44a090 Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 18 Aug 2026 18:19:25 -0500 Subject: [PATCH] refactor(tokens): sanitize and remove all third-party branding references across design tokens, styles, components, and docs --- docs/site-spec/meez-home-measurements.md | 207 ------------------ scripts/extract-meez-tokens.js | 83 ------- src/application/pages/app/archive.astro | 2 +- src/application/pages/app/index.astro | 4 +- .../pages/app/inventory/[id].astro | 6 +- .../pages/app/inventory/index.astro | 6 +- src/application/pages/app/recipes/[id].astro | 2 +- src/components/RecipeCalculator.tsx | 12 +- src/components/WorkspaceFilterBar.tsx | 2 +- src/lib/icons.ts | 2 +- src/styles/base.css | 4 +- src/styles/components/entity-directory.css | 42 ++-- src/styles/components/inventory.css | 6 +- src/styles/components/recipe-books.css | 4 +- src/styles/components/recipe-edit.css | 44 ++-- src/styles/components/recipe-view.css | 92 ++++---- src/styles/components/tabs.css | 4 +- src/styles/components/tooltips.css | 56 ++--- src/styles/layout.css | 12 +- src/styles/responsive.css | 10 +- src/styles/tokens.css | 103 +++++---- 21 files changed, 206 insertions(+), 497 deletions(-) delete mode 100644 docs/site-spec/meez-home-measurements.md delete mode 100644 scripts/extract-meez-tokens.js diff --git a/docs/site-spec/meez-home-measurements.md b/docs/site-spec/meez-home-measurements.md deleted file mode 100644 index da67afb..0000000 --- a/docs/site-spec/meez-home-measurements.md +++ /dev/null @@ -1,207 +0,0 @@ -# meez home page measurements - -Live measurements of the meez recipe home page -(`https://app.getmeez.com/home?type=recipe`) used as the styling target for -the Formulation app home page. Measured 2026-08-14 with an authenticated -relay-browser tab at a 1440×900 viewport, via `getComputedStyle` and -`getBoundingClientRect`. Re-measure before trusting these values on a new -design pass. - -## Global - -| Property | Value | -|---|---| -| body background | `#f3f3f3` | -| font family | `CircularCustCapNum, sans-serif` (proprietary; Formulation uses the Inter fallback stack) | -| base font | 16px / weight 300 / line-height 20px | -| text color | `#050841` | - -## Header (sticky top bar) - -- Height 80px, background `#fbfbfb`, no border, no shadow, z-index 1100. -- Inner toolbar: padding `0 24px`, min-height 48px. - -### Search box - -- Container: 504 × 40px, background `#fff`, border 1px solid `#f3f3f3`, - border-radius 4px, padding `0 12px`. -- Icon: 18px, `#8283a0`. -- Input: 16px / weight 400, line-height 23px, padding `8px 0 6px`, - color `rgba(0,0,0,.87)`; placeholder `#a5a9c1`. - -### New button - -- Height 32px, border-radius 100px, background `#3d5df6`, white text, - 16px / weight 500, padding `0 12px`. -- "add" icon 18px, 8px gap to label. - -### New dropdown - -- Paper: 375px wide, border-radius 4px, no border, MUI elevation-2 shadow: - `0 2px 1px -1px rgba(0,0,0,.2), 0 1px 1px 0 rgba(0,0,0,.14), 0 1px 3px 0 rgba(0,0,0,.12)`. -- List padding `22px 0`; items min-height 43.4px, padding `8px 25px`. -- Item icon: 24px, `#a5a9c1`. Label: 16px / weight 500, `#050841`. -- Hover background `#f1f5fe`. - -## Workspace layout - -- Content column 1120px wide, centered; page wrapper padding `0 32px 32px`. -- Tabs row starts ≈26px below the header; table header ≈46px below the tabs row. - -### Tab chips (workspace pills) - -- Chip: 40px tall, border-radius 99px, padding `8px 16px 8px 12px`, - gap 8px, 16px / weight 400, color `rgba(0,0,0,.87)`. -- Inactive: background `#fff`, border 1px solid `#ececec`. -- Active: background `#DBE4FF`, no border. -- No hover change (hover state identical to resting state). -- Icon: 20px circle, white SVG with 1.5px inner padding. Per type: - - recipe `#3C4679` - - ingredient `#3F908A` - - book `#F3A642` - - purchase `#3F908A` -- Label: 16px / weight 500, `#050841`, 8px right margin. -- Count: 13px / weight 500, `#a5a9c1`. - -### Filter chip - -- Transparent background, border-radius 20px, padding 10px. -- Funnel SVG 15×18 (viewBox `0 0 18 21`), `#050841`. -- Text 15px / weight 400, `#050841`. Border stays transparent on hover. - -## Directory table - -- Header row: 56.66px, background `#fbfbfb`, border-bottom 1px solid - `#f3f3f3`, grid gap 8px, no padding; checkbox cell 36px with 8px left padding. -- Column titles: 14px / weight 400, `#a5a9c1`, line-height 21px. -- Sort icon: 18px, `#a5a9c1`. -- Data row: 56.66px, background `#fff`, border-bottom 1px solid `#f3f3f3`, - gap 8px, no padding. **No hover background.** -- Selected row background `#f1f5fe`. -- meez columns: 36 (checkbox) | 112 (type) | 560 (name) | 112 (owner) | - 224 (last viewed) | 36 (actions). Formulation clones only checkbox, type, - name, and actions — Owner/Last Viewed are explicitly out of scope. -- Name text: 15px / weight 500, `#050841`, line-height 22.5px. The wrapping - link is `#3d5df6` but the name paragraph overrides it. -- Row type icon: 24px circle, white 20px SVG, same per-type colors as tabs. -- Checkbox: 20×20; unchecked outline `#ececec`, checked fill `#3d5df6` - with white check. -- Row action button (more_vert): 24×24, `#a5a9c1`, border-radius 50%, - hover background `rgba(0,0,0,.04)`. - -### Row action menu - -- Paper: 275px, border-radius 4px, elevation-2 shadow, list padding `8px 0`. -- Items: min-height 47.4px, padding `10px 30px`, label 16px / weight 500 - `#050841`, icon 24px `#a5a9c1`. -- Hover `#f1f5fe` (verified with real mouse input). Delete item `#f63d48`. - -### Delete dialog - -- Paper: 700px, border-radius 10px, padding `30px 38px`, MUI elevation-24 - shadow: - `0 11px 15px -7px rgba(0,0,0,.2), 0 24px 38px 3px rgba(0,0,0,.14), 0 9px 46px 8px rgba(0,0,0,.12)`. -- Backdrop `rgba(0,0,0,.5)`. -- Title: 28px / weight 700, `#202962`, line-height 39px. -- Subtitle: 15px / weight 400, `#050841`. -- Cancel: transparent, 15px / weight 500, `#050841`, 52px gap to Delete. -- Delete: `#f63d48` pill, 16px / weight 500, padding `16px 24px`, - min-width 250px, height 48px, border-radius 100px. - -## Dropdown panels (filter / item-type menus) - -- 300px wide, border-radius 4px, no border, elevation-2 shadow, - padding `14px 0`. -- Labels: 14px; hover `#f1f5fe`. Apply button `#3d5df6`. - -## Measurement cautions - -- MUI hover states (menu items, chips) only appear with real mouse input - (CDP mouse events), not synthetic `mouseover` dispatch. -- The relay tab cannot screenshot while not visible; use computed styles - and rects. -- Re-measure on any new pass: these are point-in-time values from one - authenticated account's render. - -## Recipe read view (`/recipes/{id}/steps`) - -Measured on the same account (recipe "Marinated Pork Belly"), same viewport -rules apply. Formulation's counterpart: `/app/recipes/{id}/` (read mode). - -### Header (48px, background `#fbfbfb`) - -- Breadcrumb links "Home / Recipes": 12px / weight 400, `#202962`, - line-height 22.5px; "/" separators `#95969c`, margin 0 4px. -- Edit button: white pill, 1px `#3d5df6` border, radius 100px, height 32px, - padding 0 12px, text 15px / weight 500 `#3d5df6`, edit icon 16px with 8px - right margin. -- Share button (not cloned): `#050841` pill, white 16px / weight 500. - -### Layout - -- Body `#f3f3f3`; content wrapper starts 16px below the header. -- Two 50/50 columns, both background `#fbfbfb`; right column has a 1px - `#f3f3f3` left border. Left padding `0 36px 35px`, right `0 32px 32px`. -- meez keeps both columns at 1027px viewport width (stacking breakpoint is - lower than Formulation's old 1280px). - -### Left column (formula) - -- Title: 28px / weight 900, `#050841`, line-height 42px; owner line - 12px / weight 500 directly below. -- Batch/yield row: labels 14px / weight 400 `#050841` with 15px right - padding; "1x" batch value 14px / weight 500 with `#a5a9c1` underline; - yield value 15px / weight 500. -- Ingredient table: no header row, no row borders. Component heading rows - 18px / weight 500, line-height 27px, bottom border `#fdfdfd`. Ingredient - rows 40.66px tall, cell padding 8px 0 (name cell +10px left). Quantity - number 15px / weight 300, unit 14px. Name link 15px / weight 400, - `rgba(0,0,0,.87)`. - -### Right column (tabs + method) - -- Tab bar: 48px, at the top of the column. Tabs: icon 24px in a 45px box - (8px padding, 5px right margin), label 13px / weight 400 `#050841`, - padding 0 10px 0 0, 1px `#f3f3f3` right border between tabs. - Active: background `#f1f5fe` + 1px `#3d5df6` bottom border. -- Panel heading row: h2 22px / weight 700, line-height 33px; step count - 16px / weight 700 `#a5a9c1` with 8px left margin; 34px bottom margin. -- Step section headings: 18px / weight 500, line-height 27px. -- Steps: number 16px / weight 700, text 16px / weight 300, `#050841`; - separators 1px `#f3f3f3` with 16px vertical margins. -- Additional details: heading 18px / weight 500; label 14px / weight 500, - value 15px / weight 500, `#050841`. - -### Tab icons (Material paths, white-on-inherit) - -- Prep Method: list icon, viewBox 24 (`M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 - 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5m0-6c-.83 0-1.5.67-1.5 - 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5m0 12c-.83 0-1.5.68-1.5 - 1.5s.68 1.5 1.5 1.5 1.5-.68 1.5-1.5-.67-1.5-1.5-1.5M7 19h14v-2H7zm0-6h14 - v-2H7zm0-8v2h14V5z`). -- Cost: attach_money icon, viewBox 24. -- UoM Equivalency: custom balance icon, viewBox 24. -- Nutrition: custom heart icon, viewBox 20×18. -### Cost panel (`/recipes/{id}/cost`, measured in the second pass) - -- Panel padding `35px 32px 0` (same `#fbfbfb` column). -- h2 22px / weight 700, line-height 33px; description 14px / weight 400 - `#95969c`; ≈20px gap before the list. -- Column header row: padding `0 0 4px 14px`, bottom border `#f3f3f3`, - labels 12px / weight 500 `#a5a9c1`; "Expand all | Collapse all" links - 12px / weight 500 `#3d5df6`. -- Rows (MUI accordions): min-height 48px, summary padding `12px 32px`, - name 15px / weight 400 `#050841`, cost value 15px / weight 400. - Detail labels ("Purchase Item Name", etc.) 14px / weight 400 `#a5a9c1`. - -### UoM Equivalency panel (`/recipes/{id}/equivalency`) - -- h2 "U of M Equivalency" 22px / weight 700, line-height 33px. -- Description 14px muted `#95969c`. -- Equivalency matrix: three value columns (Weight / Volume / Each) with - "=" separators; columns ≈124px wide, 79.5px tall. - -### Nutrition tab - -Gated ("Upgrade" teaser) on the measured account — no read-mode nutrition -panel exists in meez to match. diff --git a/scripts/extract-meez-tokens.js b/scripts/extract-meez-tokens.js deleted file mode 100644 index dfcc262..0000000 --- a/scripts/extract-meez-tokens.js +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Meez Design Token & Style Extractor - * - * Paste this snippet into the DevTools Console while viewing Meez - * (e.g. https://app.getmeez.com/home?type=recipe or a recipe detail page). - * It will collect computed styles, layout metrics, and SVG icons and copy - * a formatted JSON report to your clipboard. - */ -(() => { - const getStyle = (el, prop) => el ? window.getComputedStyle(el).getPropertyValue(prop) : null; - - const extractComponent = (selector, name) => { - const el = document.querySelector(selector); - if (!el) return null; - const style = window.getComputedStyle(el); - const rect = el.getBoundingClientRect(); - return { - name, - selector, - dimensions: { width: rect.width, height: rect.height }, - typography: { - fontFamily: style.fontFamily, - fontSize: style.fontSize, - fontWeight: style.fontWeight, - lineHeight: style.lineHeight, - letterSpacing: style.letterSpacing, - color: style.color, - }, - surface: { - backgroundColor: style.backgroundColor, - borderRadius: style.borderRadius, - border: `${style.borderWidth} ${style.borderStyle} ${style.borderColor}`, - boxShadow: style.boxShadow, - }, - spacing: { - padding: style.padding, - margin: style.margin, - gap: style.gap, - } - }; - }; - - // Collect key UI elements on current page - const report = { - url: window.location.href, - timestamp: new Date().toISOString(), - global: { - bodyBackground: getStyle(document.body, 'background-color'), - fontFamily: getStyle(document.body, 'font-family'), - fontSize: getStyle(document.body, 'font-size'), - color: getStyle(document.body, 'color'), - }, - components: { - header: extractComponent('header, [role="banner"], .MuiAppBar-root', 'Header / Top Bar'), - searchBox: extractComponent('input[type="search"], input[placeholder*="Search"]', 'Search Input'), - newButton: extractComponent('button:has(svg), a:has(svg)', 'New Button'), - tableHeader: extractComponent('[role="rowgroup"] [role="row"]:first-child, thead tr', 'Table Header'), - tableRow: extractComponent('[role="rowgroup"] [role="row"]:not(:first-child), tbody tr:first-child', 'Table Data Row'), - tabPillActive: extractComponent('.MuiChip-root, [role="tab"][aria-selected="true"]', 'Active Tab / Pill'), - }, - svgIcons: Array.from(document.querySelectorAll('svg')).slice(0, 30).map((svg, idx) => ({ - index: idx, - viewBox: svg.getAttribute('viewBox'), - width: svg.getAttribute('width') || svg.clientWidth, - height: svg.getAttribute('height') || svg.clientHeight, - fill: getStyle(svg, 'fill') || getStyle(svg, 'color'), - paths: Array.from(svg.querySelectorAll('path')).map(p => p.getAttribute('d')), - ariaLabel: svg.getAttribute('aria-label') || svg.closest('button, a')?.getAttribute('aria-label') || '' - })) - }; - - console.log('=== MEEZ EXTRACTED TOKENS ===', report); - const jsonStr = JSON.stringify(report, null, 2); - if (navigator.clipboard) { - navigator.clipboard.writeText(jsonStr).then(() => { - console.log('✅ Tokens copied to clipboard!'); - }).catch(() => { - console.log('Copy to clipboard failed. Access report via window.__meezReport'); - }); - } - window.__meezReport = report; - return report; -})(); diff --git a/src/application/pages/app/archive.astro b/src/application/pages/app/archive.astro index b23c6ef..55aa46a 100644 --- a/src/application/pages/app/archive.astro +++ b/src/application/pages/app/archive.astro @@ -523,7 +523,7 @@ function formatDeleteDate(dateStr: string | null) { border: 1px solid #dfe3ec; border-radius: 999px; color: #3d5df6; - font-family: var(--meez-font-sans); + font-family: var(--fmt-font-sans); font-size: 13px; font-weight: 500; cursor: pointer; diff --git a/src/application/pages/app/index.astro b/src/application/pages/app/index.astro index bd61dfe..6afa085 100644 --- a/src/application/pages/app/index.astro +++ b/src/application/pages/app/index.astro @@ -61,14 +61,14 @@ const type = ["recipe","ingredient","book","purchase"].includes(requested ?? "") ? requested : (query ? undefined : "recipe"); -// Recipe attention filters (Meez spec) +// Recipe attention filters const emptyRecipe=Astro.url.searchParams.get("empty_recipe")==="1"; const missingYield=Astro.url.searchParams.get("missing_yield")==="1"; const placeholderSteps=Astro.url.searchParams.get("placeholder_steps")==="1"; const attentionRecipe=Astro.url.searchParams.get("attention")==="1"; const recipeFilterActive=emptyRecipe||missingYield||placeholderSteps||attentionRecipe; -// Ingredient attention filters (Meez spec) +// Ingredient attention filters const unused=Astro.url.searchParams.get("unused")==="1"; const missingCost=Astro.url.searchParams.get("missing_cost")==="1"; const noPurchase=Astro.url.searchParams.get("no_purchase")==="1" || Astro.url.searchParams.get("no_usda")==="1"; diff --git a/src/application/pages/app/inventory/[id].astro b/src/application/pages/app/inventory/[id].astro index 787db89..7d810bc 100644 --- a/src/application/pages/app/inventory/[id].astro +++ b/src/application/pages/app/inventory/[id].astro @@ -439,7 +439,7 @@ const isCompleted = count.status === "completed"; background: white; border-radius: 999px; cursor: pointer; - font-family: var(--meez-font-sans); + font-family: var(--fmt-font-sans); font-size: 14px; font-weight: 500; color: #050841; @@ -457,7 +457,7 @@ const isCompleted = count.status === "completed"; border: none; border-radius: 999px; cursor: pointer; - font-family: var(--meez-font-sans); + font-family: var(--fmt-font-sans); font-size: 14px; font-weight: 500; transition: background 0.12s ease; @@ -630,7 +630,7 @@ const isCompleted = count.status === "completed"; background: white; border: 1px solid #050841; border-radius: 999px; - font-family: var(--meez-font-sans); + font-family: var(--fmt-font-sans); font-weight: 500; font-size: 14px; color: #050841; diff --git a/src/application/pages/app/inventory/index.astro b/src/application/pages/app/inventory/index.astro index c2aff16..5848532 100644 --- a/src/application/pages/app/inventory/index.astro +++ b/src/application/pages/app/inventory/index.astro @@ -262,7 +262,7 @@ database.close(); color: white; border: none; border-radius: 999px; - font-family: var(--meez-font-sans); + font-family: var(--fmt-font-sans); font-weight: 500; font-size: 14px; cursor: pointer; @@ -474,7 +474,7 @@ database.close(); background: transparent; border-radius: 999px; cursor: pointer; - font-family: var(--meez-font-sans); + font-family: var(--fmt-font-sans); font-size: 14px; font-weight: 500; color: #8b93a7; @@ -491,7 +491,7 @@ database.close(); border: none; border-radius: 999px; cursor: pointer; - font-family: var(--meez-font-sans); + font-family: var(--fmt-font-sans); font-size: 14px; font-weight: 500; transition: background 0.12s ease; diff --git a/src/application/pages/app/recipes/[id].astro b/src/application/pages/app/recipes/[id].astro index 116b912..9d02034 100644 --- a/src/application/pages/app/recipes/[id].astro +++ b/src/application/pages/app/recipes/[id].astro @@ -313,7 +313,7 @@ const recipeTabIcon = (name: string) => getTabIconHtml(name as TabIconKey); - + For example, if your recipe yields 1 quart, weighs 850 grams, and each portion is 85 grams, toggle off the standard conversion and enter '850 grams = 1 quart = 10 portions'. diff --git a/src/components/RecipeCalculator.tsx b/src/components/RecipeCalculator.tsx index aed2a35..c1c98e7 100644 --- a/src/components/RecipeCalculator.tsx +++ b/src/components/RecipeCalculator.tsx @@ -180,7 +180,7 @@ export default function RecipeCalculator({ components, units, basisUnitId, yield