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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user