From 59708192eb000770ede58f21e5a397c65875eb3b Mon Sep 17 00:00:00 2001 From: Solstice Date: Tue, 9 Jun 2026 00:06:42 -0700 Subject: chore: initial project scaffolding - Tauri v2 + React + TypeScript (Vite) - Tailwind CSS v4 via @tailwindcss/vite - Zustand for state management - Design system: tokens.css, fonts, icons - tauri.conf.json: solstice, 900x640, min 700x520 - global.css imports tokens and Tailwind --- src/styles/global.css | 73 +++++++++++ src/styles/tokens.css | 354 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 427 insertions(+) create mode 100644 src/styles/global.css create mode 100644 src/styles/tokens.css (limited to 'src/styles') diff --git a/src/styles/global.css b/src/styles/global.css new file mode 100644 index 0000000..2f1d37e --- /dev/null +++ b/src/styles/global.css @@ -0,0 +1,73 @@ +@import "./tokens.css"; +@import "tailwindcss"; + +@layer base { + :root { + /* Surface colors */ + --color-ink-0: var(--ink-0); + --color-ink-1: var(--ink-1); + --color-ink-2: var(--ink-2); + --color-ink-3: var(--ink-3); + --color-ink-4: var(--ink-4); + + /* Line colors */ + --color-line-1: var(--line-1); + --color-line-2: var(--line-2); + --color-line-3: var(--line-3); + + /* Foreground */ + --color-fg-1: var(--fg-1); + --color-fg-2: var(--fg-2); + --color-fg-3: var(--fg-3); + --color-fg-4: var(--fg-4); + + /* Accent */ + --color-brass: var(--brass); + --color-brass-bright: var(--brass-bright); + --color-brass-deep: var(--brass-deep); + --color-brass-ink: var(--brass-ink); + + /* Secondary palette */ + --color-oxford: var(--oxford); + --color-oxford-light: var(--oxford-light); + --color-burgundy: var(--burgundy); + --color-burgundy-light: var(--burgundy-light); + + /* Semantic */ + --color-positive: var(--positive); + --color-positive-bg: var(--positive-bg); + --color-negative: var(--negative); + --color-negative-bg: var(--negative-bg); + --color-warning: var(--warning); + --color-warning-bg: var(--warning-bg); + --color-info: var(--info); + --color-info-bg: var(--info-bg); + + /* Border radii */ + --radius-1: var(--r-1); + --radius-2: var(--r-2); + --radius-3: var(--r-3); + --radius-4: var(--r-4); + --radius-full: var(--r-full); + + /* Shadows */ + --shadow-s1: var(--shadow-1); + --shadow-s2: var(--shadow-2); + --shadow-s3: var(--shadow-3); + --shadow-sbr: var(--shadow-brass); + } + + html, body { + background: var(--ink-0); + color: var(--fg-2); + font-family: var(--font-sans); + font-size: var(--fs-16); + line-height: var(--lh-normal); + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + } + + #root { + min-height: 100vh; + } +} diff --git a/src/styles/tokens.css b/src/styles/tokens.css new file mode 100644 index 0000000..1ccaf4a --- /dev/null +++ b/src/styles/tokens.css @@ -0,0 +1,354 @@ +/* ========================================================================= + Tyler Hoang — Colors & Type + Dark, traditional, polished. Finance-forward. + ========================================================================= */ + +/* ========================================================================= + LOCAL BRAND FONTS — all self-hosted, no network requests + ========================================================================= */ + +/* EB Garamond — variable, both axes */ +@font-face { + font-family: 'EB Garamond'; + src: url('../fonts/EBGaramond-VariableFont_wght.ttf') format('truetype-variations'), + url('../fonts/EBGaramond-VariableFont_wght.ttf') format('truetype'); + font-weight: 400 800; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: 'EB Garamond'; + src: url('../fonts/EBGaramond-Italic-VariableFont_wght.ttf') format('truetype-variations'), + url('../fonts/EBGaramond-Italic-VariableFont_wght.ttf') format('truetype'); + font-weight: 400 800; + font-style: italic; + font-display: swap; +} + +/* IBM Plex Sans — variable, both axes (wdth + wght) */ +@font-face { + font-family: 'IBM Plex Sans'; + src: url('../fonts/IBM_Plex_Sans/IBMPlexSans-VariableFont_wdth,wght.ttf') format('truetype-variations'), + url('../fonts/IBM_Plex_Sans/IBMPlexSans-VariableFont_wdth,wght.ttf') format('truetype'); + font-weight: 100 700; + font-stretch: 85% 100%; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: 'IBM Plex Sans'; + src: url('../fonts/IBM_Plex_Sans/IBMPlexSans-Italic-VariableFont_wdth,wght.ttf') format('truetype-variations'), + url('../fonts/IBM_Plex_Sans/IBMPlexSans-Italic-VariableFont_wdth,wght.ttf') format('truetype'); + font-weight: 100 700; + font-stretch: 85% 100%; + font-style: italic; + font-display: swap; +} + +/* IBM Plex Mono — static weights 300 / 400 / 500 / 600 (roman + italic) */ +@font-face { + font-family: 'IBM Plex Mono'; + src: url('../fonts/IBM_Plex_Mono/IBMPlexMono-Light.ttf') format('truetype'); + font-weight: 300; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: 'IBM Plex Mono'; + src: url('../fonts/IBM_Plex_Mono/IBMPlexMono-LightItalic.ttf') format('truetype'); + font-weight: 300; + font-style: italic; + font-display: swap; +} +@font-face { + font-family: 'IBM Plex Mono'; + src: url('../fonts/IBM_Plex_Mono/IBMPlexMono-Regular.ttf') format('truetype'); + font-weight: 400; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: 'IBM Plex Mono'; + src: url('../fonts/IBM_Plex_Mono/IBMPlexMono-Italic.ttf') format('truetype'); + font-weight: 400; + font-style: italic; + font-display: swap; +} +@font-face { + font-family: 'IBM Plex Mono'; + src: url('../fonts/IBM_Plex_Mono/IBMPlexMono-Medium.ttf') format('truetype'); + font-weight: 500; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: 'IBM Plex Mono'; + src: url('../fonts/IBM_Plex_Mono/IBMPlexMono-MediumItalic.ttf') format('truetype'); + font-weight: 500; + font-style: italic; + font-display: swap; +} +@font-face { + font-family: 'IBM Plex Mono'; + src: url('../fonts/IBM_Plex_Mono/IBMPlexMono-SemiBold.ttf') format('truetype'); + font-weight: 600; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: 'IBM Plex Mono'; + src: url('../fonts/IBM_Plex_Mono/IBMPlexMono-SemiBoldItalic.ttf') format('truetype'); + font-weight: 600; + font-style: italic; + font-display: swap; +} + +:root { + /* ---------- COLOR — Surfaces (warm-cool ink, never pure black) ---------- */ + --ink-0: #0B0E13; /* page background — deep midnight, hint of blue */ + --ink-1: #11151C; /* card / surface 1 */ + --ink-2: #181D26; /* surface 2 — popovers, raised */ + --ink-3: #222934; /* surface 3 — input fills */ + --ink-4: #2C3340; /* surface 4 — hover */ + + /* ---------- COLOR — Lines ---------- */ + --line-1: #232934; /* hairline divider */ + --line-2: #2E3645; /* default border */ + --line-3: #3D4658; /* prominent border / focus ring base */ + + /* ---------- COLOR — Foreground (warm cream — never pure white) ---------- */ + --fg-1: #F2ECDC; /* high — headings, primary text */ + --fg-2: #C7C0AE; /* mid — body text */ + --fg-3: #8E8676; /* low — secondary, captions */ + --fg-4: #5E5849; /* lowest — disabled, tertiary */ + + /* ---------- COLOR — Brand accents (restrained, traditional) ---------- */ + /* Champagne — soft, muted, never honey-gold. Confirmed by user + against the "Lumière" gold which read too yellow. */ + --brass: #C2AA7A; /* primary accent — muted champagne */ + --brass-bright: #DCC79E; /* hover / highlight — pale champagne */ + --brass-deep: #8F7A50; /* pressed — deeper champagne */ + --brass-ink: #17120A; /* on-brass foreground */ + + --oxford: #1F3D5C; /* secondary — oxford navy */ + --oxford-light: #2E5A87; + --burgundy: #6E2A2E; /* tertiary — bound-leather burgundy */ + --burgundy-light:#8B3A3F; + + /* ---------- COLOR — Semantic (financial; never neon) ---------- */ + --positive: #4F8C5E; /* gain — forest green */ + --positive-bg: #15241A; + --negative: #B5494B; /* loss — muted vermilion */ + --negative-bg: #2A1517; + --warning: #C49545; /* caution — amber */ + --warning-bg: #2A1F0F; + --info: #4A78B5; /* info — slate blue */ + --info-bg: #11202E; + + /* ---------- COLOR — Selection / focus ---------- */ + --focus-ring: rgba(194, 170, 122, 0.55); /* champagne at 55% */ + --selection-bg: rgba(194, 170, 122, 0.25); + + /* ---------- TYPE — Families ---------- */ + --font-display: 'EB Garamond', 'Source Serif Pro', 'Georgia', serif; + --font-sans: 'IBM Plex Sans', 'Helvetica Neue', system-ui, sans-serif; + --font-mono: 'IBM Plex Mono', 'SF Mono', Menlo, monospace; + + /* ---------- TYPE — Scale (modular, 1.250 — major third) ---------- */ + --fs-12: 0.75rem; /* 12 — micro / labels */ + --fs-13: 0.8125rem; /* 13 — caption */ + --fs-14: 0.875rem; /* 14 — small */ + --fs-16: 1rem; /* 16 — body */ + --fs-18: 1.125rem; /* 18 — body lg */ + --fs-20: 1.25rem; /* 20 — h6 */ + --fs-24: 1.5rem; /* 24 — h5 */ + --fs-30: 1.875rem; /* 30 — h4 */ + --fs-38: 2.375rem; /* 38 — h3 */ + --fs-48: 3rem; /* 48 — h2 */ + --fs-64: 4rem; /* 64 — h1 */ + --fs-88: 5.5rem; /* 88 — display */ + + /* ---------- TYPE — Weights ---------- */ + --w-light: 300; + --w-regular: 400; + --w-medium: 500; + --w-semibold: 600; + --w-bold: 700; + + /* ---------- TYPE — Line heights ---------- */ + --lh-tight: 1.05; + --lh-snug: 1.2; + --lh-normal: 1.45; + --lh-relaxed: 1.6; + + /* ---------- TYPE — Tracking ---------- */ + --tr-tight: -0.02em; + --tr-snug: -0.01em; + --tr-normal: 0; + --tr-wide: 0.04em; + --tr-wider: 0.12em; /* small-caps labels */ + + /* ---------- SPACING (4px base) ---------- */ + --sp-1: 4px; + --sp-2: 8px; + --sp-3: 12px; + --sp-4: 16px; + --sp-5: 24px; + --sp-6: 32px; + --sp-7: 48px; + --sp-8: 64px; + --sp-9: 96px; + --sp-10: 128px; + + /* ---------- RADII — small, never bubbly ---------- */ + --r-0: 0; + --r-1: 2px; + --r-2: 4px; + --r-3: 6px; /* cards default */ + --r-4: 8px; /* large surfaces */ + --r-full: 999px; + + /* ---------- ELEVATION — long, low, warm ---------- */ + --shadow-1: 0 1px 0 rgba(0,0,0,.4), 0 1px 2px rgba(0,0,0,.3); + --shadow-2: 0 1px 0 rgba(0,0,0,.4), 0 4px 12px rgba(0,0,0,.45); + --shadow-3: 0 2px 0 rgba(0,0,0,.5), 0 12px 32px rgba(0,0,0,.55); + --shadow-inset: inset 0 1px 0 rgba(255,255,255,.04); + --shadow-brass: 0 0 0 1px rgba(194,170,122,.35), 0 6px 20px rgba(194,170,122,.18); +} + +/* ========================================================================= + SEMANTIC TYPE STYLES + ========================================================================= */ + +body { + font-family: var(--font-sans); + font-size: var(--fs-16); + line-height: var(--lh-normal); + color: var(--fg-2); + background: var(--ink-0); + font-weight: var(--w-regular); + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; +} + +::selection { background: var(--selection-bg); color: var(--fg-1); } + +.display, h1.display { + font-family: var(--font-display); + font-size: var(--fs-88); + font-weight: var(--w-regular); + line-height: var(--lh-tight); + letter-spacing: var(--tr-tight); + color: var(--fg-1); + font-style: italic; /* EB Garamond italics are the signature move */ +} + +h1, .h1 { + font-family: var(--font-display); + font-size: var(--fs-64); + font-weight: var(--w-regular); + line-height: var(--lh-tight); + letter-spacing: var(--tr-tight); + color: var(--fg-1); + margin: 0; +} + +h2, .h2 { + font-family: var(--font-display); + font-size: var(--fs-48); + font-weight: var(--w-regular); + line-height: var(--lh-snug); + letter-spacing: var(--tr-snug); + color: var(--fg-1); + margin: 0; +} + +h3, .h3 { + font-family: var(--font-display); + font-size: var(--fs-30); + font-weight: var(--w-medium); + line-height: var(--lh-snug); + color: var(--fg-1); + margin: 0; +} + +h4, .h4 { + font-family: var(--font-sans); + font-size: var(--fs-20); + font-weight: var(--w-semibold); + line-height: var(--lh-snug); + letter-spacing: var(--tr-snug); + color: var(--fg-1); + margin: 0; +} + +h5, .h5 { + font-family: var(--font-sans); + font-size: var(--fs-16); + font-weight: var(--w-semibold); + line-height: var(--lh-snug); + color: var(--fg-1); + margin: 0; +} + +h6, .eyebrow { + font-family: var(--font-sans); + font-size: var(--fs-12); + font-weight: var(--w-semibold); + text-transform: uppercase; + letter-spacing: var(--tr-wider); + color: var(--fg-3); + margin: 0; +} + +p, .p { + font-family: var(--font-sans); + font-size: var(--fs-16); + line-height: var(--lh-relaxed); + color: var(--fg-2); + margin: 0; +} + +.lead { + font-family: var(--font-display); + font-size: var(--fs-24); + font-weight: var(--w-regular); + line-height: var(--lh-relaxed); + color: var(--fg-1); + font-style: italic; +} + +.caption { + font-family: var(--font-sans); + font-size: var(--fs-13); + line-height: var(--lh-normal); + color: var(--fg-3); +} + +.micro { + font-family: var(--font-sans); + font-size: var(--fs-12); + text-transform: uppercase; + letter-spacing: var(--tr-wider); + color: var(--fg-3); +} + +code, .code { + font-family: var(--font-mono); + font-size: 0.92em; + background: var(--ink-3); + color: var(--fg-1); + padding: 2px 6px; + border-radius: var(--r-1); + border: 1px solid var(--line-1); +} + +.tabular { font-family: var(--font-mono); font-variant-numeric: tabular-nums; } + +a { + color: var(--brass-bright); + text-decoration: none; + border-bottom: 1px solid var(--brass-deep); + transition: color .15s ease, border-color .15s ease; +} +a:hover { color: var(--fg-1); border-color: var(--brass-bright); } -- cgit v1.3-2-g0d8e