From a57fea4590a959d5b2d7eae6ba25748f597f6d1b Mon Sep 17 00:00:00 2001 From: Ilia Mashkov Date: Fri, 6 Mar 2026 23:06:58 +0300 Subject: [PATCH] feat(design-system): add brutalist design tokens and Tailwind v4 theme from Figma prototype --- src/app/styles/app.css | 277 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) diff --git a/src/app/styles/app.css b/src/app/styles/app.css index f1d8c73..6a8dc2e 100644 --- a/src/app/styles/app.css +++ b/src/app/styles/app.css @@ -1 +1,278 @@ @import "tailwindcss"; + +/* ============================================================ + FONTS + ============================================================ */ +@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght,SOFT,WONK@0,9..144,100..900,0..100,0..1;1,9..144,100..900,0..100,0..1&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,100..900;1,100..900&display=swap'); + +/* ============================================================ + DESIGN TOKENS + ============================================================ */ +:root { + /* Typography scale — Augmented Fourth (×1.414) */ + --font-size-base: 16px; + --text-xs: 0.707rem; /* 11.31px */ + --text-sm: 0.840rem; /* 13.44px */ + --text-base: 1rem; /* 16px */ + --text-lg: 1.414rem; /* 22.62px */ + --text-xl: 2rem; /* 32px */ + --text-2xl: 2.828rem; /* 45.25px */ + --text-3xl: 4rem; /* 64px */ + --text-4xl: 5.657rem; /* 90.51px */ + --text-5xl: 8rem; /* 128px */ + + /* Font families */ + --font-heading: 'Fraunces', serif; + --font-body: 'Public Sans', sans-serif; + + /* Font weights */ + --font-weight-heading: 900; + --font-weight-body: 600; + --font-weight-normal: 400; + + /* Line heights */ + --line-height-tight: 1.2; + --line-height-normal: 1.5; + + /* Fraunces variable font axes */ + --fraunces-wonk: 1; + --fraunces-soft: 0; + + /* Palette — Sanzo Wada inspired */ + --ochre-clay: #D9B48F; + --slate-indigo: #3B4A59; + --burnt-oxide: #A64B35; + --carbon-black: #121212; + + /* Semantic color aliases */ + --background: var(--ochre-clay); + --foreground: var(--carbon-black); + --card: var(--ochre-clay); + --card-foreground: var(--carbon-black); + --primary: var(--burnt-oxide); + --primary-foreground: var(--ochre-clay); + --secondary: var(--slate-indigo); + --secondary-foreground: var(--ochre-clay); + --muted: var(--slate-indigo); + --muted-foreground: var(--ochre-clay); + --accent: var(--burnt-oxide); + --accent-foreground: var(--ochre-clay); + --destructive: #d4183d; + --destructive-foreground:#ffffff; + --border: var(--carbon-black); + --ring: var(--carbon-black); + + /* Spacing — 8pt linear scale */ + --space-1: 0.5rem; /* 8px */ + --space-2: 1rem; /* 16px */ + --space-3: 1.5rem; /* 24px */ + --space-4: 2rem; /* 32px */ + --space-5: 2.5rem; /* 40px */ + --space-6: 3rem; /* 48px */ + --space-8: 4rem; /* 64px */ + --space-10: 5rem; /* 80px */ + --space-12: 6rem; /* 96px */ + --space-16: 8rem; /* 128px */ + --space-20: 10rem; /* 160px */ + + /* Borders */ + --border-width: 3px; + --radius: 0px; + + /* Brutalist hard shadows */ + --shadow-brutal-sm: 4px 4px 0 var(--carbon-black); + --shadow-brutal: 8px 8px 0 var(--carbon-black); + --shadow-brutal-lg: 12px 12px 0 var(--carbon-black); +} + +/* ============================================================ + TAILWIND v4 THEME REGISTRATION + ============================================================ */ +@theme inline { + /* Colors */ + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-border: var(--border); + --color-ring: var(--ring); + + /* Palette direct access */ + --color-ochre-clay: var(--ochre-clay); + --color-slate-indigo: var(--slate-indigo); + --color-burnt-oxide: var(--burnt-oxide); + --color-carbon-black: var(--carbon-black); + + /* Border radius (zero for brutalist aesthetic) */ + --radius-sm: var(--radius); + --radius-md: var(--radius); + --radius-lg: var(--radius); + + /* Box shadows */ + --shadow-brutal-sm: var(--shadow-brutal-sm); + --shadow-brutal: var(--shadow-brutal); + --shadow-brutal-lg: var(--shadow-brutal-lg); + + /* Font families */ + --font-heading: var(--font-heading); + --font-body: var(--font-body); +} + +/* ============================================================ + BASE LAYER — GLOBAL ELEMENT DEFAULTS + ============================================================ */ +@layer base { + html { + font-size: var(--font-size-base); + } + + body { + background-color: var(--background); + color: var(--foreground); + font-family: var(--font-body); + font-weight: var(--font-weight-body); + line-height: var(--line-height-tight); + overflow-x: hidden; + position: relative; + } + + /* Paper grain texture overlay */ + body::before { + content: ''; + position: fixed; + inset: 0; + background-image: + repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,0,0,.02) 2px, rgba(0,0,0,.02) 4px), + repeating-linear-gradient(90deg, transparent, transparent 2px, rgba(0,0,0,.02) 2px, rgba(0,0,0,.02) 4px); + opacity: .4; + pointer-events: none; + z-index: 1; + } + + /* Ensure page content renders above texture */ + body > * { + position: relative; + z-index: 2; + } + + h1, .h1 { font-size: var(--text-4xl); } + h2, .h2 { font-size: var(--text-3xl); } + h3, .h3 { font-size: var(--text-2xl); } + h4, .h4 { font-size: var(--text-xl); } + h5, .h5 { font-size: var(--text-lg); } + + h1, h2, h3, h4, h5, + .h1, .h2, .h3, .h4, .h5 { + font-family: var(--font-heading); + font-weight: var(--font-weight-heading); + line-height: var(--line-height-tight); + font-variation-settings: 'WONK' var(--fraunces-wonk), 'SOFT' var(--fraunces-soft); + color: var(--carbon-black); + margin: 0; + } + + p { + font-family: var(--font-body); + font-size: var(--text-base); + font-weight: var(--font-weight-body); + line-height: var(--line-height-tight); + color: var(--carbon-black); + margin: 0; + } + + label { + font-family: var(--font-body); + font-size: var(--text-sm); + font-weight: var(--font-weight-body); + text-transform: uppercase; + letter-spacing: .05em; + line-height: var(--line-height-tight); + } + + button { + font-family: var(--font-body); + font-size: var(--text-base); + font-weight: var(--font-weight-body); + line-height: var(--line-height-tight); + cursor: pointer; + } + + input, textarea, select { + font-family: var(--font-body); + font-size: var(--text-base); + font-weight: var(--font-weight-body); + line-height: var(--line-height-tight); + } + + blockquote { + font-family: var(--font-heading); + font-size: var(--text-xl); + font-weight: var(--font-weight-heading); + font-variation-settings: 'WONK' var(--fraunces-wonk), 'SOFT' var(--fraunces-soft); + line-height: var(--line-height-tight); + border-left: var(--border-width) solid var(--carbon-black); + padding-left: var(--space-4); + margin: var(--space-6) 0; + } + + a { + color: var(--burnt-oxide); + text-decoration: none; + border-bottom: 2px solid var(--carbon-black); + transition: border-bottom-width .15s ease; + } + + a:hover { + border-bottom-width: 4px; + } +} + +/* ============================================================ + BRUTALIST UTILITY CLASSES + ============================================================ */ +.brutal-border { border: var(--border-width) solid var(--carbon-black); } +.brutal-border-top { border-top: var(--border-width) solid var(--carbon-black); } +.brutal-border-bottom { border-bottom: var(--border-width) solid var(--carbon-black); } +.brutal-border-left { border-left: var(--border-width) solid var(--carbon-black); } +.brutal-border-right { border-right: var(--border-width) solid var(--carbon-black); } + +.brutal-shadow { box-shadow: var(--shadow-brutal); } +.brutal-shadow-sm { box-shadow: var(--shadow-brutal-sm); } +.brutal-shadow-lg { box-shadow: var(--shadow-brutal-lg); } + +/* ============================================================ + GRID UTILITIES + ============================================================ */ +.grid-muller { + display: grid; + gap: var(--space-3); + grid-template-columns: repeat(4, 1fr); +} + +@media (min-width: 1024px) { + .grid-muller { + grid-template-columns: repeat(12, 1fr); + } +} + +/* ============================================================ + ANIMATION + ============================================================ */ +@keyframes fadeInUp { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } +} + +.animate-fade-in-up { + animation: fadeInUp .5s cubic-bezier(.4, 0, .2, 1); +}