wip: bento card layout + zinc/emerald tokens (in progress)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
body { padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom); }
|
||||
:root {
|
||||
/* ── Fonts ── */
|
||||
--font: 'DM Sans', -apple-system, system-ui, sans-serif;
|
||||
--font: 'Outfit', -apple-system, system-ui, sans-serif;
|
||||
--mono: 'JetBrains Mono', ui-monospace, monospace;
|
||||
--transition: 150ms ease;
|
||||
|
||||
@@ -56,8 +56,8 @@
|
||||
--radius-xs: 4px;
|
||||
--radius-sm: 6px;
|
||||
--radius-md: 8px;
|
||||
--radius: 12px;
|
||||
--radius-lg: 16px;
|
||||
--radius: 16px;
|
||||
--radius-lg: 20px;
|
||||
--radius-full: 9999px;
|
||||
|
||||
/* ── Elevation scale ──
|
||||
@@ -67,11 +67,12 @@
|
||||
* 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);
|
||||
/* Zinc-tinted shadows */
|
||||
--shadow-xs: 0 1px 2px rgba(24,24,27,0.04);
|
||||
--shadow-sm: 0 1px 2px rgba(24,24,27,0.04), 0 4px 8px rgba(24,24,27,0.02);
|
||||
--shadow-md: 0 2px 8px rgba(24,24,27,0.05), 0 12px 24px rgba(24,24,27,0.04);
|
||||
--shadow-lg: 0 4px 16px rgba(24,24,27,0.06), 0 24px 48px rgba(24,24,27,0.06);
|
||||
--shadow-xl: 0 8px 24px rgba(24,24,27,0.08), 0 32px 64px rgba(24,24,27,0.1);
|
||||
/* Legacy aliases */
|
||||
--card-shadow: var(--shadow-md);
|
||||
--card-shadow-sm: var(--shadow-sm);
|
||||
@@ -103,75 +104,68 @@
|
||||
--leading-loose: 1.8;
|
||||
}
|
||||
|
||||
/* ── LIGHT MODE ── */
|
||||
/* ── LIGHT MODE — Zinc + Emerald ── */
|
||||
:root {
|
||||
/* Surface hierarchy: canvas (page bg) → surface (sidebars, panels) → card (content containers) */
|
||||
--canvas: #F3F4F6;
|
||||
--canvas: #FAFAFA;
|
||||
--surface: #FFFFFF;
|
||||
--surface-secondary: #F7F8FA;
|
||||
--surface-secondary: #F4F4F5;
|
||||
--card: #FFFFFF;
|
||||
--card-secondary: #F7F8FA;
|
||||
--card-hover: #EDEEF2;
|
||||
--card-secondary: #F4F4F5;
|
||||
--card-hover: #F0F0F2;
|
||||
|
||||
/* Borders */
|
||||
--border: rgba(0,0,0,0.06);
|
||||
--border-strong: rgba(0,0,0,0.10);
|
||||
|
||||
/* Text hierarchy: 1 (headings/names) → 2 (body) → 3 (labels/meta) → 4 (placeholder/disabled) */
|
||||
--text-1: #111118;
|
||||
--text-2: #3d3d4a;
|
||||
--text-3: #6b6b78;
|
||||
--text-4: #a8a8b3;
|
||||
--text-1: #18181B;
|
||||
--text-2: #3F3F46;
|
||||
--text-3: #71717A;
|
||||
--text-4: #A1A1AA;
|
||||
|
||||
/* Accent — deep indigo */
|
||||
--accent: #4338CA;
|
||||
--accent-bg: #EEF2FF;
|
||||
--accent-dim: rgba(67,56,202,0.06);
|
||||
--accent-border: rgba(67,56,202,0.12);
|
||||
--accent-focus: rgba(67,56,202,0.14);
|
||||
/* Accent — Emerald (single, desaturated) */
|
||||
--accent: #059669;
|
||||
--accent-bg: #ECFDF5;
|
||||
--accent-dim: rgba(5,150,105,0.07);
|
||||
--accent-border: rgba(5,150,105,0.14);
|
||||
--accent-focus: rgba(5,150,105,0.16);
|
||||
|
||||
/* Semantic: success */
|
||||
--success: #059669;
|
||||
--success-bg: #ECFDF5;
|
||||
--success-dim: rgba(5,150,105,0.07);
|
||||
|
||||
/* Semantic: error */
|
||||
--error: #DC2626;
|
||||
--error-bg: #FEF2F2;
|
||||
--error-dim: rgba(220,38,38,0.06);
|
||||
|
||||
/* Semantic: warning */
|
||||
--warning: #D97706;
|
||||
--warning-bg: rgba(217,119,6,0.07);
|
||||
|
||||
/* Overlay */
|
||||
--overlay: rgba(0,0,0,0.25);
|
||||
--overlay-strong: rgba(0,0,0,0.45);
|
||||
--nav-bg: rgba(255,255,255,0.92);
|
||||
--overlay: rgba(0,0,0,0.2);
|
||||
--overlay-strong: rgba(0,0,0,0.4);
|
||||
--nav-bg: rgba(250,250,250,0.8);
|
||||
}
|
||||
|
||||
/* ── DARK MODE ── */
|
||||
/* ── DARK MODE — Zinc + Emerald ── */
|
||||
.dark {
|
||||
--canvas: #0a0a0c;
|
||||
--surface: #111114;
|
||||
--surface-secondary: #141417;
|
||||
--card: #18181c;
|
||||
--card-secondary: #141417;
|
||||
--card-hover: #1f1f24;
|
||||
--canvas: #09090B;
|
||||
--surface: #111113;
|
||||
--surface-secondary: #18181B;
|
||||
--card: #1C1C1F;
|
||||
--card-secondary: #18181B;
|
||||
--card-hover: #232326;
|
||||
|
||||
--border: rgba(255,255,255,0.07);
|
||||
--border-strong: rgba(255,255,255,0.12);
|
||||
|
||||
--text-1: #f4f4f5;
|
||||
--text-2: #a1a1aa;
|
||||
--text-3: #71717a;
|
||||
--text-4: #3f3f46;
|
||||
--text-1: #FAFAFA;
|
||||
--text-2: #A1A1AA;
|
||||
--text-3: #71717A;
|
||||
--text-4: #3F3F46;
|
||||
|
||||
--accent: #6366F1;
|
||||
--accent-bg: rgba(99,102,241,0.1);
|
||||
--accent-dim: rgba(99,102,241,0.08);
|
||||
--accent-border: rgba(99,102,241,0.14);
|
||||
--accent-focus: rgba(99,102,241,0.16);
|
||||
--accent: #34D399;
|
||||
--accent-bg: rgba(52,211,153,0.1);
|
||||
--accent-dim: rgba(52,211,153,0.08);
|
||||
--accent-border: rgba(52,211,153,0.14);
|
||||
--accent-focus: rgba(52,211,153,0.16);
|
||||
|
||||
--success: #22c55e;
|
||||
--success-bg: rgba(34,197,94,0.1);
|
||||
@@ -487,7 +481,7 @@
|
||||
|
||||
/* ── App surface (centered container) ── */
|
||||
.app-surface {
|
||||
max-width: 1200px;
|
||||
max-width: 1280px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
padding: 0 var(--sp-6);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300..700;1,9..40,300..700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
|
||||
@@ -61,17 +61,18 @@
|
||||
}
|
||||
|
||||
.budget-amount {
|
||||
font-size: var(--text-3xl);
|
||||
font-weight: 500;
|
||||
font-size: 36px;
|
||||
font-weight: 800;
|
||||
font-family: var(--mono);
|
||||
letter-spacing: -0.04em;
|
||||
color: var(--text-1);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.budget-label {
|
||||
font-size: var(--text-base);
|
||||
color: var(--text-3);
|
||||
margin-top: var(--sp-1.5);
|
||||
font-size: 12px;
|
||||
color: var(--text-4);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.budget-rows {
|
||||
@@ -92,18 +93,19 @@
|
||||
}
|
||||
|
||||
.budget-row-name {
|
||||
font-size: var(--text-base);
|
||||
color: var(--text-2);
|
||||
font-size: 13px;
|
||||
color: var(--text-3);
|
||||
}
|
||||
|
||||
.budget-row-amount {
|
||||
font-size: var(--text-base);
|
||||
font-size: 12px;
|
||||
font-family: var(--mono);
|
||||
color: var(--text-1);
|
||||
font-weight: 500;
|
||||
color: var(--text-2);
|
||||
}
|
||||
|
||||
.budget-row-amount.income {
|
||||
color: var(--success);
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
@@ -14,147 +14,139 @@
|
||||
size?: 'primary' | 'secondary';
|
||||
href: string;
|
||||
} = $props();
|
||||
|
||||
// Extract the number from title (e.g. "78 uncategorized..." → "78")
|
||||
function extractNumber(t: string): { num: string; rest: string } {
|
||||
const match = t.match(/^([\d,\.]+)\s+(.*)$/);
|
||||
if (match) return { num: match[1], rest: match[2] };
|
||||
return { num: '', rest: t };
|
||||
}
|
||||
|
||||
const parsed = $derived(extractNumber(title));
|
||||
</script>
|
||||
|
||||
<a {href} class="action-card {size} {variant}">
|
||||
<div class="action-card-left">
|
||||
<div class="action-card-icon {variant}">
|
||||
<a {href} class="bento {variant}">
|
||||
<div class="bento-top">
|
||||
<span class="bento-label">
|
||||
{#if variant === 'budget'}Budget{:else if variant === 'inventory'}Inventory{:else}Calories{/if}
|
||||
</span>
|
||||
<div class="bento-icon {variant}">
|
||||
{#if variant === 'budget'}
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>
|
||||
{:else if variant === 'inventory'}
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16.5 9.4l-9-5.19"/><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></svg>
|
||||
{:else if variant === 'fitness'}
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/></svg>
|
||||
{:else}
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="action-card-text">
|
||||
<div class="action-card-title">{title}</div>
|
||||
<div class="action-card-desc">{description}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="action-card-right">
|
||||
|
||||
{#if parsed.num}
|
||||
<div class="bento-value">{parsed.num}</div>
|
||||
<div class="bento-desc">{parsed.rest}<br>{description}</div>
|
||||
{:else}
|
||||
<div class="bento-desc-only">{title}<br>{description}</div>
|
||||
{/if}
|
||||
|
||||
<div class="bento-action">
|
||||
{action}
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18l6-6-6-6"/></svg>
|
||||
<svg width="11" height="11" viewBox="0 0 11 11" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M4 2l3.5 3.5L4 9"/></svg>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<style>
|
||||
.action-card {
|
||||
.bento {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: var(--sp-4) var(--sp-5);
|
||||
flex-direction: column;
|
||||
padding: 22px 24px;
|
||||
border-radius: var(--radius);
|
||||
background: var(--card);
|
||||
border: 1px solid var(--border);
|
||||
border-left: 3px solid var(--border);
|
||||
box-shadow: var(--shadow-xs);
|
||||
transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
border-top: 2px solid transparent;
|
||||
box-shadow: var(--shadow-sm);
|
||||
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
.action-card.budget { border-left-color: var(--accent); }
|
||||
.action-card.inventory { border-left-color: var(--error); }
|
||||
.action-card.fitness { border-left-color: var(--success); }
|
||||
|
||||
.action-card:hover {
|
||||
transform: translateY(-2px);
|
||||
.bento:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
.action-card.budget:hover { box-shadow: 0 4px 16px var(--accent-dim), var(--shadow-sm); }
|
||||
.action-card.inventory:hover { box-shadow: 0 4px 16px var(--error-dim), var(--shadow-sm); }
|
||||
.action-card.fitness:hover { box-shadow: 0 4px 16px var(--success-dim), var(--shadow-sm); }
|
||||
.bento.budget:hover { border-top-color: var(--accent); }
|
||||
.bento.inventory:hover { border-top-color: var(--error); }
|
||||
.bento.fitness:hover { border-top-color: var(--success); }
|
||||
|
||||
.action-card:active { transform: scale(0.985); }
|
||||
.bento:active { transform: scale(0.985); }
|
||||
|
||||
.action-card.primary {
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
.action-card-left {
|
||||
.bento-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--inner-gap);
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.action-card-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: var(--radius-md);
|
||||
.bento-label {
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--text-4);
|
||||
}
|
||||
|
||||
.bento-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.bento-icon.budget { background: var(--accent-dim); color: var(--accent); }
|
||||
.bento-icon.inventory { background: var(--error-dim); color: var(--error); }
|
||||
.bento-icon.fitness { background: var(--success-dim); color: var(--success); }
|
||||
.bento-icon :global(svg) { width: 14px; height: 14px; }
|
||||
|
||||
/* Icon variants — using semantic tokens for both themes */
|
||||
.action-card-icon.budget { background: var(--accent-bg); color: var(--accent); }
|
||||
.action-card-icon.inventory { background: var(--error-bg); color: var(--error); }
|
||||
.action-card-icon.fitness { background: var(--success-bg); color: var(--success); }
|
||||
|
||||
.action-card-icon :global(svg) {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.action-card-text {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.action-card-title {
|
||||
font-size: var(--text-md);
|
||||
font-weight: 600;
|
||||
.bento-value {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
font-family: var(--mono);
|
||||
letter-spacing: -0.04em;
|
||||
line-height: 1;
|
||||
color: var(--text-1);
|
||||
line-height: var(--leading-snug);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.action-card-desc {
|
||||
font-size: var(--text-sm);
|
||||
.bento-desc {
|
||||
font-size: 13px;
|
||||
color: var(--text-3);
|
||||
margin-top: var(--sp-0.5);
|
||||
line-height: 1.4;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.action-card-right {
|
||||
font-size: var(--text-sm);
|
||||
.bento-desc-only {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--text-3);
|
||||
display: flex;
|
||||
color: var(--text-2);
|
||||
line-height: 1.5;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.bento-action {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 1px;
|
||||
flex-shrink: 0;
|
||||
padding: var(--sp-1) var(--sp-2);
|
||||
border-radius: var(--radius-md);
|
||||
transition: all var(--transition);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.action-card:hover .action-card-right {
|
||||
gap: 4px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: var(--accent);
|
||||
background: var(--accent-dim);
|
||||
}
|
||||
|
||||
.action-card-right :global(svg) {
|
||||
width: var(--sp-4);
|
||||
height: var(--sp-4);
|
||||
transition: transform var(--transition);
|
||||
}
|
||||
|
||||
.action-card:hover .action-card-right :global(svg) {
|
||||
transform: translateX(2px);
|
||||
margin-top: 12px;
|
||||
letter-spacing: 0.02em;
|
||||
transition: gap 0.2s;
|
||||
}
|
||||
.bento:hover .bento-action { gap: 7px; }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.action-card {
|
||||
padding: var(--sp-4);
|
||||
gap: var(--sp-2);
|
||||
}
|
||||
|
||||
.action-card-left {
|
||||
gap: var(--sp-3);
|
||||
}
|
||||
.bento { padding: 18px 20px; }
|
||||
.bento-value { font-size: 24px; }
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -97,25 +97,25 @@
|
||||
-webkit-backdrop-filter: blur(20px) saturate(1.4);
|
||||
}
|
||||
.navbar-inner {
|
||||
max-width: 1400px;
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 52px;
|
||||
height: 48px;
|
||||
padding: 0 var(--sp-6);
|
||||
gap: var(--sp-5);
|
||||
gap: var(--sp-6);
|
||||
}
|
||||
.navbar-logo {
|
||||
font-weight: 700;
|
||||
font-size: var(--text-md);
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-2);
|
||||
gap: 7px;
|
||||
color: var(--text-1);
|
||||
flex-shrink: 0;
|
||||
letter-spacing: -0.02em;
|
||||
letter-spacing: -0.04em;
|
||||
}
|
||||
.navbar-logo svg { width: 18px; height: 18px; color: var(--accent); }
|
||||
.navbar-logo svg { width: 16px; height: 16px; color: var(--accent); }
|
||||
|
||||
.navbar-links {
|
||||
display: flex;
|
||||
@@ -124,19 +124,18 @@
|
||||
flex: 1;
|
||||
}
|
||||
.navbar-link {
|
||||
padding: 5px var(--sp-3);
|
||||
border-radius: var(--radius-md);
|
||||
font-size: var(--text-sm);
|
||||
padding: 4px 12px;
|
||||
border-radius: 6px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: var(--text-3);
|
||||
transition: all 0.15s ease;
|
||||
color: var(--text-4);
|
||||
transition: all 0.2s cubic-bezier(0.16,1,0.3,1);
|
||||
background: none;
|
||||
border: none;
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
.navbar-link:hover { color: var(--text-1); background: var(--card-hover); }
|
||||
.navbar-link:hover { color: var(--text-2); background: rgba(0,0,0,0.03); }
|
||||
.navbar-link.active {
|
||||
color: var(--accent);
|
||||
background: var(--accent-dim);
|
||||
|
||||
@@ -157,8 +157,8 @@
|
||||
|
||||
<TaskSlideOver bind:open={taskPanelOpen} onclose={() => { taskPanelOpen = false; loadTasks(); }} />
|
||||
|
||||
<!-- Action cards -->
|
||||
<div class="action-cards stagger">
|
||||
<!-- Bento row 1: Budget (wide) + Inventory (narrow) -->
|
||||
<div class="bento-row stagger">
|
||||
<DashboardActionCard
|
||||
title="{budgetUncatCount} uncategorized transactions"
|
||||
description="{budgetSpending} spent · {budgetIncome} income"
|
||||
@@ -168,12 +168,16 @@
|
||||
href="/budget"
|
||||
/>
|
||||
<DashboardActionCard
|
||||
title="{inventoryIssueCount} issue{inventoryIssueCount !== 1 ? 's' : ''} · {inventoryReviewCount} needs review"
|
||||
title="{inventoryIssueCount} issue{inventoryIssueCount !== 1 ? 's' : ''} · {inventoryReviewCount} needs review"
|
||||
description="{inventoryIssueCount + inventoryReviewCount} items need attention"
|
||||
action="View"
|
||||
variant="inventory"
|
||||
href="/inventory"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Bento row 2: Calories + Fitness detail -->
|
||||
<div class="bento-row-2 stagger">
|
||||
<DashboardActionCard
|
||||
title="{fitnessCalRemaining.toLocaleString()} calories remaining today"
|
||||
description="{fitnessCalLogged.toLocaleString()} cal logged · {fitnessProtein}g protein · {fitnessCarbs}g carbs"
|
||||
@@ -181,17 +185,15 @@
|
||||
variant="fitness"
|
||||
href="/fitness"
|
||||
/>
|
||||
<FitnessModule />
|
||||
</div>
|
||||
|
||||
<!-- Modules -->
|
||||
<!-- Modules: Budget detail (wide) + Issues (narrow) -->
|
||||
<div class="modules-grid">
|
||||
<BudgetModule />
|
||||
<div class="right-stack">
|
||||
<FitnessModule />
|
||||
<IssuesModule />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@@ -310,28 +312,29 @@
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
/* ── Action cards ── */
|
||||
.action-cards {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--sp-2);
|
||||
margin-bottom: var(--section-gap);
|
||||
/* ── Bento grids ── */
|
||||
.bento-row {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
gap: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.bento-row-2 {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* ── Modules grid ── */
|
||||
.modules-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1.3fr 0.7fr;
|
||||
gap: var(--module-gap);
|
||||
grid-template-columns: 7fr 3fr;
|
||||
gap: 10px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.right-stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--module-gap);
|
||||
}
|
||||
|
||||
/* ── Mobile ── */
|
||||
@media (max-width: 900px) {
|
||||
.dash-header {
|
||||
@@ -348,9 +351,13 @@
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.bento-row,
|
||||
.bento-row-2,
|
||||
.modules-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.bento-row > :global(*),
|
||||
.bento-row-2 > :global(*),
|
||||
.modules-grid > :global(*) {
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
|
||||
Reference in New Issue
Block a user