From 32952c41784e671d5c9dbcfa853f4a2033b96f90 Mon Sep 17 00:00:00 2001 From: Agent Date: Fri, 17 Jul 2026 09:04:55 -0400 Subject: [PATCH] feat(web): adopt Modular Mind brand tokens and icons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port the design system export into the Next app: --mm-* tokens for colour, type, spacing, radius, elevation and motion, plus the branded favicon/icon set and wordmark. - Load Archivo / IBM Plex Sans / IBM Plex Mono via next/font instead of the export's Google Fonts @import, so fonts self-host (no external request, no layout shift). Plex Mono has no variable cut on Google Fonts, so its weights are listed explicitly — including 700, which --mm-text-readout needs and the export's @import omitted. - Keep base rules in @layer base. Unlayered rules outrank every Tailwind utility regardless of specificity, so the export's bare `a` rule was overriding text-colour classes and flattening the nav's active state. - Install the branded favicon at src/app/favicon.ico; the export shipped the untouched Next scaffold default there, which takes precedence over public/ and would have kept serving the old icon. - Migrate SiteNav off zinc utilities onto the tokens. --- web/public/favicon-512.png | Bin 0 -> 22180 bytes web/public/logo.svg | 4 + web/src/app/apple-icon.png | Bin 0 -> 4851 bytes web/src/app/brand-tokens.css | 208 ++++++++++++++++++++++++++++++++ web/src/app/favicon.ico | Bin 25931 -> 808 bytes web/src/app/globals.css | 16 +++ web/src/app/icon.svg | 4 + web/src/app/layout.tsx | 27 ++++- web/src/components/site-nav.tsx | 10 +- 9 files changed, 264 insertions(+), 5 deletions(-) create mode 100755 web/public/favicon-512.png create mode 100755 web/public/logo.svg create mode 100755 web/src/app/apple-icon.png create mode 100755 web/src/app/brand-tokens.css create mode 100755 web/src/app/icon.svg diff --git a/web/public/favicon-512.png b/web/public/favicon-512.png new file mode 100755 index 0000000000000000000000000000000000000000..779af488afb4a0e2b4dc320ceb00d1e4f108c28b GIT binary patch literal 22180 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 Ua3H(``~ + + + \ No newline at end of file diff --git a/web/src/app/apple-icon.png b/web/src/app/apple-icon.png new file mode 100755 index 0000000000000000000000000000000000000000..26bce163dbc49911655f30e4da8afc7159bf09db GIT binary patch literal 4851 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 Jy5ju!{{Sw6Dr*1$ literal 0 HcmV?d00001 diff --git a/web/src/app/brand-tokens.css b/web/src/app/brand-tokens.css new file mode 100755 index 0000000..da3ee35 --- /dev/null +++ b/web/src/app/brand-tokens.css @@ -0,0 +1,208 @@ +/* Modular Mind brand tokens — ported from the design system. + * Fonts are loaded via next/font in layout.tsx, which supplies the + * --font-archivo / --font-plex-sans / --font-plex-mono variables used below. */ + +/* Modular Mind — Color tokens + * Direction: Rack Panel — warm graphite anthracite surfaces (eurorack front panels), + * a single amber "signal" accent, and a tight verdict semantic set. + * Base scales first, then semantic aliases. */ +:root { + /* ---- Graphite neutrals (warm-tinted anthracite) ---- */ + --mm-black: #0c0a07; /* deepest, page void */ + --mm-graphite-950: #131009; /* page background */ + --mm-graphite-900: #1c1811; /* recessed surface */ + --mm-graphite-800: #26221b; /* panel */ + --mm-graphite-700: #302a20; /* raised panel / hover */ + --mm-graphite-600: #3a3428; /* hairline / border */ + --mm-graphite-500: #4a4335; /* strong border / divider */ + --mm-graphite-400: #6f6656; /* faint text, ticks */ + --mm-graphite-300: #a2988a; /* dim text */ + --mm-graphite-200: #d6cdbe; /* secondary text */ + --mm-graphite-100: #f2ece0; /* primary text (warm bone) */ + + /* ---- Amber signal (the one accent) ---- */ + --mm-amber-bright: #ffbe5c; /* hover / peak highlight */ + --mm-amber: #f2a63c; /* primary accent, waveform, active */ + --mm-amber-deep: #c77f22; /* pressed */ + --mm-amber-dim: #4a3418; /* accent fill / tint background */ + --mm-amber-ink: #17140f; /* text/glyph on amber fills */ + + /* ---- Verdict semantics ---- */ + --mm-caution: #f2c14e; /* dc_offset, near_silent */ + --mm-caution-dim: #40350f; + --mm-fault: #e8664e; /* clipping */ + --mm-fault-dim: #3d1c14; + --mm-good: #f2a63c; /* passing / makes sound — reuses signal amber */ + + /* ---- Semantic aliases ---- */ + --mm-bg: var(--mm-graphite-950); + --mm-surface: var(--mm-graphite-900); + --mm-panel: var(--mm-graphite-800); + --mm-panel-raised: var(--mm-graphite-700); + --mm-border: var(--mm-graphite-600); + --mm-border-strong: var(--mm-graphite-500); + --mm-divider: var(--mm-graphite-600); + + --mm-text: var(--mm-graphite-100); + --mm-text-secondary: var(--mm-graphite-200); + --mm-text-dim: var(--mm-graphite-300); + --mm-text-faint: var(--mm-graphite-400); + + --mm-accent: var(--mm-amber); + --mm-accent-hover: var(--mm-amber-bright); + --mm-accent-active: var(--mm-amber-deep); + --mm-accent-tint: var(--mm-amber-dim); + --mm-on-accent: var(--mm-amber-ink); + + --mm-signal: var(--mm-amber); /* waveform trace */ + --mm-signal-grid: rgba(242,166,60,.08); /* scope grid lines */ + + --mm-link: var(--mm-amber); + --mm-link-hover: var(--mm-amber-bright); +} + +/* Modular Mind — Typography tokens + * Archivo → display / headings (mechanical grotesque, tight) + * IBM Plex Sans → body / prose + * IBM Plex Mono → data, labels, slugs, metrics, "readouts" + * Mono carries the instrument-panel voice; use it for anything numeric or code-like. */ +:root { + /* ---- Families ---- */ + --mm-font-display: var(--font-archivo), 'Helvetica Neue', Arial, sans-serif; + --mm-font-body: var(--font-plex-sans), system-ui, sans-serif; + --mm-font-mono: var(--font-plex-mono), ui-monospace, 'SF Mono', Menlo, monospace; + + /* ---- Weights ---- */ + --mm-weight-regular: 400; + --mm-weight-medium: 500; + --mm-weight-semibold:600; + --mm-weight-bold: 700; + --mm-weight-display: 800; + + /* ---- Type scale (px) ---- */ + --mm-size-3xs: 9px; /* micro caps / ticks */ + --mm-size-2xs: 10px; /* mono labels */ + --mm-size-xs: 11px; /* meta, slugs */ + --mm-size-sm: 13px; /* body small, table */ + --mm-size-md: 15px; /* body */ + --mm-size-lg: 17px; /* card title */ + --mm-size-xl: 21px; /* section title */ + --mm-size-2xl: 28px; /* stat number / page sub */ + --mm-size-3xl: 40px; /* page title */ + --mm-size-4xl: 60px; /* hero */ + + /* ---- Line heights ---- */ + --mm-leading-tight: 1.1; + --mm-leading-snug: 1.3; + --mm-leading-normal: 1.55; + + /* ---- Letter spacing ---- */ + --mm-tracking-tight: -0.02em; /* display */ + --mm-tracking-normal: 0; + --mm-tracking-label: 0.08em; /* mono labels */ + --mm-tracking-caps: 0.14em; /* micro caps */ + + /* ---- Semantic roles ---- */ + --mm-text-hero: var(--mm-weight-display) var(--mm-size-4xl)/var(--mm-leading-tight) var(--mm-font-display); + --mm-text-title: var(--mm-weight-bold) var(--mm-size-3xl)/var(--mm-leading-tight) var(--mm-font-display); + --mm-text-section: var(--mm-weight-bold) var(--mm-size-xl)/var(--mm-leading-snug) var(--mm-font-display); + --mm-text-card: var(--mm-weight-bold) var(--mm-size-lg)/var(--mm-leading-snug) var(--mm-font-display); + --mm-text-body: var(--mm-weight-regular) var(--mm-size-md)/var(--mm-leading-normal) var(--mm-font-body); + --mm-text-body-sm: var(--mm-weight-regular) var(--mm-size-sm)/var(--mm-leading-normal) var(--mm-font-body); + --mm-text-mono: var(--mm-weight-regular) var(--mm-size-xs)/var(--mm-leading-snug) var(--mm-font-mono); + --mm-text-readout: var(--mm-weight-bold) var(--mm-size-2xl)/var(--mm-leading-tight) var(--mm-font-mono); +} + +/* Modular Mind — Spacing tokens. 4px base grid; dense instrument-panel rhythm. */ +:root { + --mm-space-0: 0; + --mm-space-1: 2px; + --mm-space-2: 4px; + --mm-space-3: 6px; + --mm-space-4: 8px; + --mm-space-5: 10px; + --mm-space-6: 12px; + --mm-space-7: 14px; + --mm-space-8: 16px; + --mm-space-10: 20px; + --mm-space-12: 24px; + --mm-space-14: 28px; + --mm-space-16: 32px; + --mm-space-20: 40px; + --mm-space-24: 48px; + --mm-space-32: 64px; + + /* Semantic */ + --mm-pad-badge: 4px 8px; + --mm-pad-button: 8px 14px; + --mm-pad-card: 16px 18px; + --mm-pad-panel: 18px; + --mm-gap-tight: 6px; + --mm-gap: 12px; + --mm-gap-loose: 20px; + + /* Layout */ + --mm-content-max: 1120px; + --mm-nav-height: 52px; +} + +/* Modular Mind — Radius tokens. Tight & technical — machined panel corners, never pill-soft. */ +:root { + --mm-radius-none: 0; + --mm-radius-xs: 2px; /* ticks, inner elements */ + --mm-radius-sm: 3px; /* badges, buttons, inputs */ + --mm-radius-md: 5px; /* cards, panels */ + --mm-radius-lg: 8px; /* large surfaces, modals */ + --mm-radius-full: 999px; /* status dots, play button only */ + + /* Semantic */ + --mm-radius-badge: var(--mm-radius-sm); + --mm-radius-button: var(--mm-radius-sm); + --mm-radius-card: var(--mm-radius-md); + --mm-radius-panel: var(--mm-radius-md); +} + +/* Modular Mind — Elevation & effects. + * Panels read like machined front panels: a faint top light-line, a seated drop shadow, + * a hairline border. The amber glow is reserved for live signal (waveform, play, active). */ +:root { + /* Border-as-elevation hairlines are the primary separation; shadows are subtle. */ + --mm-shadow-panel: + inset 0 1px 0 rgba(255,255,255,.035), + 0 1px 2px rgba(0,0,0,.5); + --mm-shadow-raised: + inset 0 1px 0 rgba(255,255,255,.05), + 0 4px 14px rgba(0,0,0,.45); + --mm-shadow-pop: + inset 0 1px 0 rgba(255,255,255,.06), + 0 12px 34px rgba(0,0,0,.55); + --mm-shadow-inset: + inset 0 1px 3px rgba(0,0,0,.5); + + /* Signal glow — amber phosphor */ + --mm-glow-signal: 0 0 12px rgba(242,166,60,.45); + --mm-glow-signal-sm:0 0 6px rgba(242,166,60,.5); + --mm-glow-fault: 0 0 10px rgba(232,102,78,.45); + + /* Focus ring */ + --mm-ring: 0 0 0 2px var(--mm-graphite-950), 0 0 0 3.5px var(--mm-amber); +} + +/* Modular Mind — Motion. Mechanical and fast: linear-ish snaps, no bounce, no float. + * Hover brightens borders/fills; press seats the element down 1px. */ +:root { + --mm-dur-instant: 80ms; /* @kind other */ + --mm-dur-fast: 130ms; /* @kind other */ + --mm-dur: 200ms; /* @kind other */ + --mm-dur-slow: 340ms; /* @kind other */ + + --mm-ease: cubic-bezier(.2,.7,.3,1); /* @kind other */ + --mm-ease-out: cubic-bezier(.16,1,.3,1); /* @kind other */ + --mm-ease-linear: linear; /* @kind other */ + + --mm-transition-control: background var(--mm-dur-fast) var(--mm-ease), + border-color var(--mm-dur-fast) var(--mm-ease), + color var(--mm-dur-fast) var(--mm-ease), + transform var(--mm-dur-instant) var(--mm-ease); +} + diff --git a/web/src/app/favicon.ico b/web/src/app/favicon.ico index 718d6fea4835ec2d246af9800eddb7ffb276240c..816a7eac93b3d1879894c0f9d76f292c0d5bad73 100644 GIT binary patch literal 808 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 LrJugUA?W`A8`#=m diff --git a/web/src/app/globals.css b/web/src/app/globals.css index f1d8c73..ef11850 100644 --- a/web/src/app/globals.css +++ b/web/src/app/globals.css @@ -1 +1,17 @@ @import "tailwindcss"; +@import "./brand-tokens.css"; + +/* Brand ground + base type (was: bg-zinc-950 / text-zinc-100 utility classes). + * These must live in @layer base: unlayered rules outrank every Tailwind + * utility, which would make `a` here override any text-colour class. */ +@layer base { + body { + background: var(--mm-bg); + color: var(--mm-text); + font: var(--mm-text-body); + -webkit-font-smoothing: antialiased; + } + a { color: var(--mm-link); text-decoration: none; } + a:hover { color: var(--mm-link-hover); } + ::selection { background: var(--mm-amber-dim); color: var(--mm-amber-bright); } +} diff --git a/web/src/app/icon.svg b/web/src/app/icon.svg new file mode 100755 index 0000000..158748a --- /dev/null +++ b/web/src/app/icon.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/web/src/app/layout.tsx b/web/src/app/layout.tsx index 2db9bc7..35e5d7a 100644 --- a/web/src/app/layout.tsx +++ b/web/src/app/layout.tsx @@ -1,7 +1,27 @@ import type { Metadata } from 'next' +import { Archivo, IBM_Plex_Sans, IBM_Plex_Mono } from 'next/font/google' import { SiteNav } from '@/components/site-nav' import './globals.css' +const archivo = Archivo({ + subsets: ['latin'], + variable: '--font-archivo', +}) + +const plexSans = IBM_Plex_Sans({ + subsets: ['latin'], + weight: ['400', '500', '600'], + variable: '--font-plex-sans', +}) + +// IBM Plex Mono has no variable cut on Google Fonts — weights must be listed. +// 700 is required by --mm-text-readout. +const plexMono = IBM_Plex_Mono({ + subsets: ['latin'], + weight: ['400', '500', '600', '700'], + variable: '--font-plex-mono', +}) + export const metadata: Metadata = { title: 'Modular Mind', description: 'An AI that learns to build modular synth patches — explore the pipeline and listen to what it makes.', @@ -9,8 +29,11 @@ export const metadata: Metadata = { export default function RootLayout({ children }: { children: React.ReactNode }) { return ( - - + +
{children}
diff --git a/web/src/components/site-nav.tsx b/web/src/components/site-nav.tsx index 299e40a..2f8150d 100644 --- a/web/src/components/site-nav.tsx +++ b/web/src/components/site-nav.tsx @@ -14,8 +14,8 @@ const links = [ export function SiteNav() { const pathname = usePathname() return ( -