Files
platform/frontend-v2/src/app.css
Yusuf Suleman d3e250e361 Initial commit: Second Brain Platform
Complete platform with unified design system and real API integration.

Apps: Dashboard, Fitness, Budget, Inventory, Trips, Reader, Media, Settings
Infrastructure: SvelteKit + Python gateway + Docker Compose
2026-03-28 23:20:40 -05:00

462 lines
13 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@import 'tailwindcss';
/* ═══════════════════════════════════════════════
DESIGN SYSTEM — Single source of truth
RULES:
1. No raw px in component <style> blocks — use tokens
2. No raw rgba/hex colors — use semantic tokens
3. No copy-pasting base component styles — use globals
4. Surface hierarchy: canvas → surface → card
5. Text hierarchy: text-1 → text-2 → text-3 → text-4
═══════════════════════════════════════════════ */
@layer base {
:root {
/* ── Fonts ── */
--font: 'Inter', -apple-system, system-ui, sans-serif;
--mono: 'JetBrains Mono', ui-monospace, monospace;
--transition: 180ms ease;
/* ── Spacing scale (4px grid) ──
* Use these everywhere: padding, margin, gap.
* Naming: --sp-{n} where value = n × 4px
*/
--sp-0: 0px;
--sp-px: 1px;
--sp-0.5: 2px;
--sp-1: 4px;
--sp-1.5: 6px;
--sp-2: 8px;
--sp-3: 12px;
--sp-4: 16px;
--sp-5: 20px;
--sp-6: 24px;
--sp-7: 28px;
--sp-8: 32px;
--sp-10: 40px;
--sp-12: 48px;
--sp-16: 64px;
--sp-20: 80px;
/* Semantic spacing aliases */
--section-gap: var(--sp-7);
--card-pad: var(--sp-5);
--card-pad-primary: var(--sp-7);
--card-pad-secondary: var(--sp-4);
--row-gap: var(--sp-3);
--module-gap: var(--sp-5);
--row-pad-y: 14px;
--row-pad-x: var(--sp-4);
--inner-gap: var(--sp-3);
/* ── Radius scale ── */
--radius-xs: 4px;
--radius-sm: 6px;
--radius-md: 8px;
--radius: 12px;
--radius-lg: 16px;
--radius-full: 9999px;
/* ── Elevation scale ──
* xs: barely visible (row hover, inner elements)
* sm: subtle lift (secondary cards, inputs)
* md: standard card elevation
* lg: elevated (dropdowns, popovers, hero cards)
* xl: overlay (modals, slide-out panels)
*/
--shadow-xs: 0 1px 2px rgba(0,0,0,0.03);
--shadow-sm: 0 1px 3px rgba(0,0,0,0.04), 0 4px 12px rgba(0,0,0,0.04);
--shadow-md: 0 2px 6px rgba(0,0,0,0.04), 0 8px 24px rgba(0,0,0,0.06);
--shadow-lg: 0 4px 12px rgba(0,0,0,0.06), 0 16px 40px rgba(0,0,0,0.1);
--shadow-xl: 0 8px 24px rgba(0,0,0,0.08), 0 24px 60px rgba(0,0,0,0.15);
/* Legacy aliases */
--card-shadow: var(--shadow-md);
--card-shadow-sm: var(--shadow-sm);
/* ── Typography scale ──
* xs: badges, pills, tiny counters
* sm: labels, meta, captions, button text
* base: body text, list items, inputs
* md: card titles, important rows (16px avoids iOS zoom)
* lg: section headers, modal titles
* xl: page titles
* 2xl: hero headings
* 3xl: large hero numbers
*/
--text-xs: 11px;
--text-sm: 13px;
--text-base: 14px;
--text-md: 15px;
--text-lg: 17px;
--text-xl: 22px;
--text-2xl: 28px;
--text-3xl: 36px;
/* Line heights */
--leading-tight: 1.2;
--leading-snug: 1.35;
--leading-normal: 1.5;
--leading-relaxed: 1.65;
--leading-loose: 1.8;
}
/* ── LIGHT MODE ── */
:root {
/* Surface hierarchy: canvas (page bg) → surface (sidebars, panels) → card (content containers) */
--canvas: #F5F6F8;
--surface: #FFFFFF;
--surface-secondary: #FAFAFB;
--card: #FFFFFF;
--card-secondary: #FAFAFB;
--card-hover: #f0f0f3;
/* Borders */
--border: rgba(0,0,0,0.06);
--border-strong: rgba(0,0,0,0.1);
/* Text hierarchy: 1 (headings/names) → 2 (body) → 3 (labels/meta) → 4 (placeholder/disabled) */
--text-1: #1a1a1f;
--text-2: #4a4a55;
--text-3: #6b6b76;
--text-4: #b4b4bd;
/* Accent — indigo */
--accent: #4F46E5;
--accent-bg: #EEF2FF;
--accent-dim: rgba(79,70,229,0.06);
--accent-border: rgba(79,70,229,0.10);
--accent-focus: rgba(79,70,229,0.12);
/* Semantic: success */
--success: #16A34A;
--success-bg: #F0FDF4;
--success-dim: rgba(34,197,94,0.08);
/* Semantic: error */
--error: #DC2626;
--error-bg: #FEF2F2;
--error-dim: rgba(239,68,68,0.08);
/* Semantic: warning */
--warning: #d97706;
--warning-bg: rgba(245,158,11,0.08);
/* Overlay */
--overlay: rgba(0,0,0,0.3);
--overlay-strong: rgba(0,0,0,0.5);
--nav-bg: rgba(255,255,255,0.9);
}
/* ── DARK MODE ── */
.dark {
--canvas: #09090b;
--surface: #0f0f12;
--surface-secondary: #111114;
--card: #161619;
--card-secondary: #111114;
--card-hover: #1c1c20;
--border: rgba(255,255,255,0.06);
--border-strong: rgba(255,255,255,0.1);
--text-1: #fafafa;
--text-2: #a1a1aa;
--text-3: #71717a;
--text-4: #3f3f46;
--accent: #3b82f6;
--accent-bg: rgba(59,130,246,0.1);
--accent-dim: rgba(59,130,246,0.08);
--accent-border: rgba(59,130,246,0.12);
--accent-focus: rgba(59,130,246,0.15);
--success: #22c55e;
--success-bg: rgba(34,197,94,0.1);
--success-dim: rgba(34,197,94,0.08);
--error: #ef4444;
--error-bg: rgba(239,68,68,0.1);
--error-dim: rgba(239,68,68,0.08);
--warning: #f59e0b;
--warning-bg: rgba(245,158,11,0.1);
--overlay: rgba(0,0,0,0.6);
--overlay-strong: rgba(0,0,0,0.75);
--nav-bg: rgba(15,15,18,0.9);
/* Dark shadows need higher opacity */
--shadow-xs: 0 1px 2px rgba(0,0,0,0.1);
--shadow-sm: 0 1px 3px rgba(0,0,0,0.15), 0 4px 12px rgba(0,0,0,0.1);
--shadow-md: 0 2px 6px rgba(0,0,0,0.15), 0 8px 24px rgba(0,0,0,0.12);
--shadow-lg: 0 4px 12px rgba(0,0,0,0.2), 0 16px 40px rgba(0,0,0,0.2);
--shadow-xl: 0 8px 24px rgba(0,0,0,0.25), 0 24px 60px rgba(0,0,0,0.3);
}
/* ── Base resets ── */
html, body {
font-family: var(--font);
background: var(--canvas);
color: var(--text-1);
min-height: 100vh;
transition: background var(--transition), color var(--transition);
-webkit-font-smoothing: antialiased;
}
* { border-color: var(--border); }
a { color: inherit; text-decoration: none; }
button { font-family: var(--font); cursor: pointer; }
input { font-family: var(--font); }
}
/* ═══════════════════════════════════════════════
GLOBAL COMPONENT CLASSES
Use these in any component without re-declaring
═══════════════════════════════════════════════ */
/* ── Skeleton loader ── */
.skeleton {
background: linear-gradient(90deg, var(--card) 25%, var(--card-hover) 50%, var(--card) 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
border-radius: var(--radius-xs);
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
/* ── Buttons ── */
.btn-primary {
padding: var(--sp-2) var(--sp-4);
border-radius: var(--radius-md);
background: var(--accent);
color: white;
border: none;
font-size: var(--text-sm);
font-weight: 500;
cursor: pointer;
transition: all var(--transition);
}
.btn-primary:hover { opacity: 0.9; }
.btn-primary.full {
width: 100%;
padding: var(--sp-3) var(--sp-4);
font-size: var(--text-md);
font-weight: 600;
border-radius: var(--radius);
}
.btn-secondary {
padding: var(--sp-2) var(--sp-4);
border-radius: var(--radius-md);
background: var(--card-secondary);
color: var(--text-2);
border: 1px solid var(--border);
font-size: var(--text-sm);
font-weight: 500;
cursor: pointer;
transition: all var(--transition);
}
.btn-secondary:hover { background: var(--card-hover); color: var(--text-1); }
.btn-icon {
width: 36px;
height: 36px;
border-radius: var(--radius-md);
background: var(--card-secondary);
border: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
color: var(--text-3);
transition: all var(--transition);
flex-shrink: 0;
}
.btn-icon:hover { color: var(--text-1); background: var(--card-hover); }
.btn-icon svg { width: var(--sp-4); height: var(--sp-4); }
/* ── Inputs ── */
.input {
width: 100%;
padding: 10px 14px;
border-radius: var(--radius-md);
background: var(--surface-secondary);
border: 1px solid var(--border);
color: var(--text-1);
font-size: var(--text-base);
font-family: var(--font);
outline: none;
transition: border-color var(--transition);
}
.input:focus { border-color: var(--accent); }
.input::placeholder { color: var(--text-4); }
/* ── Module (card container) ──
* Use for any content block: dashboard widgets, data tables, etc.
* Variants: .primary (hero, more padding + elevation), .flush (no padding)
*/
.module {
background: var(--card);
border-radius: var(--radius);
border: 1px solid var(--border);
box-shadow: var(--shadow-md);
padding: var(--card-pad);
}
.module.primary {
padding: var(--card-pad-primary);
box-shadow: var(--shadow-lg);
}
.module.flush { padding: 0; }
.module-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: var(--sp-5);
}
.module-title {
font-size: var(--text-sm);
font-weight: 600;
color: var(--text-3);
text-transform: uppercase;
letter-spacing: 0.06em;
}
.module-action {
font-size: var(--text-sm);
color: var(--accent);
font-weight: 500;
cursor: pointer;
text-decoration: none;
}
.module-action:hover { text-decoration: underline; }
/* ── Data row ──
* Standard list item pattern: name + meta on left, value/badge on right.
* Use in transactions, inventory items, feed entries, etc.
*/
.data-row {
display: flex;
align-items: center;
gap: var(--inner-gap);
padding: var(--row-pad-y) var(--row-pad-x);
transition: background var(--transition);
}
.data-row:hover { background: var(--card-hover); }
.data-row + .data-row { border-top: 1px solid var(--border); }
.data-row:nth-child(even) { background: color-mix(in srgb, var(--surface) 68%, var(--card)); }
.data-row:nth-child(even):hover { background: var(--card-hover); }
/* ── Badges ──
* Semantic status badges. Variants: error, success, warning, accent, muted.
*/
.badge {
font-size: var(--text-xs);
font-weight: 500;
padding: 3px 10px;
border-radius: var(--radius-sm);
flex-shrink: 0;
}
.badge.error { background: var(--error-dim); color: var(--error); }
.badge.success { background: var(--success-dim); color: var(--success); }
.badge.warning { background: var(--warning-bg); color: var(--warning); }
.badge.accent { background: var(--accent-dim); color: var(--accent); }
.badge.muted { background: var(--card-hover); color: var(--text-4); }
/* ── Tabs ──
* Pill-style tab bar.
*/
.tab-bar { display: flex; gap: var(--sp-1); }
.tab {
padding: var(--sp-2) 14px;
border-radius: var(--radius-md);
font-size: var(--text-base);
font-weight: 500;
color: var(--text-3);
background: none;
border: none;
cursor: pointer;
transition: all var(--transition);
font-family: var(--font);
display: flex;
align-items: center;
gap: var(--sp-1.5);
}
.tab:hover { color: var(--text-1); background: var(--card-hover); }
.tab.active { color: var(--text-1); background: var(--card); box-shadow: var(--shadow-xs); }
.tab-badge {
font-size: var(--text-xs);
font-family: var(--mono);
background: var(--accent-dim);
color: var(--accent);
padding: 1px 6px;
border-radius: var(--radius-xs);
margin-left: var(--sp-1);
}
/* ── Section header ──
* Uppercase label above a group of content.
*/
.section-label {
font-size: var(--text-xs);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--text-3);
margin-bottom: var(--sp-1.5);
}
/* ── Page wrapper ── */
.page { padding: var(--sp-8) 0 var(--sp-20); }
.page-header { margin-bottom: var(--section-gap); }
.page-title {
font-size: var(--text-sm);
font-weight: 500;
color: var(--text-3);
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: var(--sp-1);
}
.page-greeting {
font-size: var(--text-2xl);
font-weight: 300;
color: var(--text-1);
line-height: var(--leading-tight);
}
.page-greeting strong { font-weight: 600; }
/* ── App surface (centered container) ── */
.app-surface {
max-width: 1200px;
width: 100%;
margin: 0 auto;
padding: 0 var(--sp-6);
}
/* ── Responsive ── */
@media (max-width: 768px) {
:root {
--text-xs: 12px;
--text-sm: 15px;
--text-base: 16px;
--text-md: 17px;
--text-lg: 18px;
--text-xl: 22px;
--text-2xl: 26px;
--text-3xl: 32px;
--card-pad: var(--sp-4);
--card-pad-primary: var(--sp-5);
--row-pad-y: var(--sp-4);
--section-gap: var(--sp-5);
}
.page-greeting { font-size: var(--text-xl); }
.page { padding: var(--sp-5) 0 var(--sp-20); }
.app-surface { padding: 0 var(--sp-5); }
}