Bento Dashboard

Variable-span grid tiles, live HTMX metrics, SaaS dashboard patterns.

Technologies Demonstrated

[HTMX] hx-trigger="every 3s" polling — live metric tile updates
[HTMX] hx-swap="innerHTML" for in-place number replacement
[HTMX] hx-post form submission with inline response
[Alpine] x-data button toggle — active state with :style binding
[Alpine] Column sort indicators with Alpine x-data reactive state
[CSS] grid-column: span N — variable-width bento tiles

Color Palette

[Alpine]

Primary

#6366f1

Secondary

#8b5cf6

Accent

#10b981

Danger

#ef4444

Warning

#f59e0b

Text

#0f172a

Muted

#64748b

Click any swatch to copy hex value to clipboard.

<div class="grid grid-cols-2 sm:grid-cols-4 md:grid-cols-7 gap-4">
				@bentoSwatch("Primary", "#6366f1")
				@bentoSwatch("Secondary", "#8b5cf6")
				@bentoSwatch("Accent", "#10b981")
				@bentoSwatch("Danger", "#ef4444")
				@bentoSwatch("Warning", "#f59e0b")
				@bentoSwatch("Text", "#0f172a")
				@bentoSwatch("Muted", "#64748b")
			</div>

Typography

Display — 2.5rem / Bold

Dashboard

Heading — 1.25rem / Medium

Active Users Over Time

DM Sans Weights

Light — secondary descriptions and metadata

Regular — body text and standard content

Medium — labels, navigation, and UI text

Bold — headings and metric values

Caption — 0.8125rem

Last updated 2 minutes ago · Auto-refreshes every 3 seconds

Spacing Scale

Base unit: 4px

4px
8px
16px
24px
32px
48px
64px

Buttons

[Alpine]

Variants

Sizes

Toggle [Alpine]

state: off
<div class="bento-card space-y-6">
				<div>
					<p class="text-xs mb-3" style="color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.08em;">Variants</p>
					<div class="flex flex-wrap gap-3">
						<button class="bento-btn text-sm">Primary</button>
						<button class="bento-btn bento-btn-secondary text-sm">Secondary</button>
						<button class="bento-btn text-sm" disabled style="opacity: 0.4; cursor: not-allowed;">Disabled</button>
					</div>
				</div>
				<div>
					<p class="text-xs mb-3" style="color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.08em;">Sizes</p>
					<div class="flex flex-wrap items-center gap-3">
						<button class="bento-btn" style="font-size: 0.75rem; padding: 0.25rem 0.625rem;">Small</button>
						<button class="bento-btn text-sm">Medium</button>
						<button class="bento-btn" style="font-size: 1rem; padding: 0.75rem 1.5rem;">Large</button>
					</div>
				</div>
				<div>
					<p class="text-xs mb-3" style="color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.08em;">Toggle [Alpine]</p>
					<div x-data="{ on: false }" class="flex items-center gap-4">
						<button
							class="bento-btn text-sm"
							{ templ.Attributes{
								"@click":  "on = !on",
								":style":  "on ? 'background: var(--color-accent)' : ''",
							}... }
						>
							<span x-text="on ? 'Active ✓' : 'Toggle Me'">Toggle Me</span>
						</button>
						<span class="text-xs" style="color: var(--color-text-muted);" x-text="on ? 'state: on' : 'state: off'">state: off</span>
					</div>
				</div>
			</div>

Live Metric Tiles

[HTMX]

These tiles poll /guides/bento/metrics every 3 seconds via HTMX.

Active Users

1,247

+12% ↑

Revenue

$48.2K

+8% ↑

Error Rate

0.3%

-0.1% ↓

Response Time

142ms

+5ms →

<div
				class="bento-grid"
				hx-get="/guides/bento/metrics"
				hx-trigger="every 3s"
				hx-swap="innerHTML"
			>
				<!-- initial static tiles (replaced by HTMX on first poll) -->
				<div class="bento-card bento-span-6 flex flex-col gap-2">
					<p class="text-xs font-medium" style="color:var(--color-text-muted)">Active Users</p>
					<p class="text-2xl font-bold" style="color:var(--color-text)">1,247</p>
					<p class="text-xs font-medium" style="color:var(--color-accent)">+12% ↑</p>
				</div>
				<div class="bento-card bento-span-6 flex flex-col gap-2">
					<p class="text-xs font-medium" style="color:var(--color-text-muted)">Revenue</p>
					<p class="text-2xl font-bold" style="color:var(--color-text)">$48.2K</p>
					<p class="text-xs font-medium" style="color:var(--color-accent)">+8% ↑</p>
				</div>
				<div class="bento-card bento-span-6 flex flex-col gap-2">
					<p class="text-xs font-medium" style="color:var(--color-text-muted)">Error Rate</p>
					<p class="text-2xl font-bold" style="color:var(--color-text)">0.3%</p>
					<p class="text-xs font-medium" style="color:var(--color-danger)">-0.1% ↓</p>
				</div>
				<div class="bento-card bento-span-6 flex flex-col gap-2">
					<p class="text-xs font-medium" style="color:var(--color-text-muted)">Response Time</p>
					<p class="text-2xl font-bold" style="color:var(--color-text)">142ms</p>
					<p class="text-xs font-medium" style="color:var(--color-text-muted)">+5ms →</p>
				</div>
			</div>

Sortable Data Table

[Alpine]
Name Status Amount
Project AlphaActive$12,400
Project BetaReview$8,200
Project GammaActive$31,000
Project DeltaPaused$4,100
Project EpsilonActive$19,750
Project ZetaReview$6,900
<div x-data="{ sort: 'name', dir: 'asc' }" class="bento-card overflow-x-auto">
				<table class="w-full text-sm">
					<thead>
						<tr style="border-bottom: 1px solid var(--color-border);">
							<th
								class="text-left p-3 font-medium cursor-pointer select-none"
								style="color:var(--color-text-muted)"
								{ templ.Attributes{"@click": "sort='name'; dir = dir==='asc'?'desc':'asc'"}... }
							>
								Name <span x-text="sort==='name' ? (dir==='asc' ? '↑' : '↓') : '↕'"></span>
							</th>
							<th
								class="text-left p-3 font-medium cursor-pointer select-none"
								style="color:var(--color-text-muted)"
								{ templ.Attributes{"@click": "sort='status'; dir = dir==='asc'?'desc':'asc'"}... }
							>
								Status <span x-text="sort==='status' ? (dir==='asc' ? '↑' : '↓') : '↕'"></span>
							</th>
							<th
								class="text-left p-3 font-medium cursor-pointer select-none"
								style="color:var(--color-text-muted)"
								{ templ.Attributes{"@click": "sort='amount'; dir = dir==='asc'?'desc':'asc'"}... }
							>
								Amount <span x-text="sort==='amount' ? (dir==='asc' ? '↑' : '↓') : '↕'"></span>
							</th>
						</tr>
					</thead>
					<tbody>
						for _, row := range []struct{ name, status, amount, statusColor string }{
							{"Project Alpha", "Active", "$12,400", "var(--color-accent)"},
							{"Project Beta", "Review", "$8,200", "var(--color-warning)"},
							{"Project Gamma", "Active", "$31,000", "var(--color-accent)"},
							{"Project Delta", "Paused", "$4,100", "var(--color-text-muted)"},
							{"Project Epsilon", "Active", "$19,750", "var(--color-accent)"},
							{"Project Zeta", "Review", "$6,900", "var(--color-warning)"},
						} {
							<tr style="border-bottom: 1px solid var(--color-border);">
								<td class="p-3 font-medium" style="color:var(--color-text)">{ row.name }</td>
								<td class="p-3">
									<span class="px-2 py-0.5 rounded text-xs font-medium" style={ "color:" + row.statusColor + ";background:" + row.statusColor + "18" }>{ row.status }</span>
								</td>
								<td class="p-3 font-mono text-sm" style="color:var(--color-text)">{ row.amount }</td>
							</tr>
						}
					</tbody>
				</table>
			</div>

Status Indicators

[Alpine]

Click any service to cycle status

<div
				x-data="{ statuses: [
					{ name: 'API Gateway', state: 0 },
					{ name: 'Database', state: 0 },
					{ name: 'CDN', state: 0 },
					{ name: 'Auth Service', state: 1 },
					{ name: 'Queue Worker', state: 2 }
				] }"
				class="bento-card"
			>
				<p class="text-xs mb-4" style="color: var(--color-text-muted); text-transform: uppercase; letter-spacing: 0.08em;">Click any service to cycle status</p>
				<div class="flex flex-wrap gap-3">
					<template x-for="svc in statuses" :key="svc.name">
						<button
							class="flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-all cursor-pointer"
							style="border: 1px solid var(--color-border); background: var(--color-surface);"
							{ templ.Attributes{"@click": "svc.state = (svc.state + 1) % 3"}... }
						>
							<span
								class="w-2 h-2 rounded-full"
								{ templ.Attributes{":class": "svc.state === 0 ? 'bg-emerald-500' : svc.state === 1 ? 'bg-amber-400' : 'bg-red-500'"}... }
							></span>
							<span x-text="svc.name" style="color: var(--color-text);"></span>
							<span
								class="text-xs font-normal"
								{ templ.Attributes{
									"x-text":  "svc.state === 0 ? 'Active' : svc.state === 1 ? 'Warning' : 'Down'",
									":style":  "svc.state === 0 ? 'color:var(--color-accent)' : svc.state === 1 ? 'color:var(--color-warning)' : 'color:var(--color-danger)'",
								}... }
							></span>
						</button>
					</template>
				</div>
			</div>

Cards & Panels

[Alpine]

Static Card

A standard dashboard tile with rounded corners, subtle shadow, and clean border. Content stays minimal.

Expandable Panel

+

Revealed content with smooth transition. Alpine handles the toggle with zero server round-trips.

expanded: true

border-radius: 12px

shadow: subtle

<div class="bento-card" style="padding: 0;" x-data="{ expanded: false }">
					<div
						class="p-5 flex items-center justify-between cursor-pointer"
						{ templ.Attributes{"@click": "expanded = !expanded"}... }
					>
						<h3 class="text-sm font-semibold" style="color: var(--color-text);">Expandable Panel</h3>
						<span
							class="text-lg transition-transform duration-200"
							style="color: var(--color-text-muted);"
							{ templ.Attributes{":class": "expanded ? 'rotate-45' : ''"}... }
						>+</span>
					</div>
					<div x-show="expanded" x-transition style="border-top: 1px solid var(--color-border);">
						<div class="p-5">
							<p class="text-sm mb-3" style="color: var(--color-text-muted);">
								Revealed content with smooth transition. Alpine handles the toggle with zero server round-trips.
							</p>
							<div class="rounded-lg p-3 text-xs font-mono" style="background: var(--color-surface-2); color: var(--color-text-muted);">
								<p>expanded: true</p>
								<p>border-radius: 12px</p>
								<p>shadow: subtle</p>
							</div>
						</div>
					</div>
				</div>

Forms

[HTMX]

Billing Cycle

<form
					hx-post="/guides/bento/demo-form"
					hx-target="#bento-form-response"
					hx-swap="innerHTML"
					class="space-y-4"
				>
					<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
						<div>
							<label class="block text-xs font-medium mb-1.5" style="color: var(--color-text-muted);" for="bento-name">Name</label>
							<input id="bento-name" name="name" type="text" placeholder="Jane Smith" class="bento-input"/>
						</div>
						<div>
							<label class="block text-xs font-medium mb-1.5" style="color: var(--color-text-muted);" for="bento-email">Email</label>
							<input id="bento-email" name="email" type="email" placeholder="jane@company.com" class="bento-input"/>
						</div>
					</div>
					<div>
						<label class="block text-xs font-medium mb-1.5" style="color: var(--color-text-muted);" for="bento-plan">Plan</label>
						<select id="bento-plan" name="plan" class="bento-input cursor-pointer">
							<option value="">— Select plan —</option>
							<option value="starter">Starter</option>
							<option value="pro">Pro</option>
							<option value="enterprise">Enterprise</option>
						</select>
					</div>
					<div class="flex items-center gap-3">
						<input type="checkbox" id="bento-analytics" name="analytics" class="w-4 h-4 cursor-pointer" style="accent-color: var(--color-primary);"/>
						<label for="bento-analytics" class="text-sm cursor-pointer" style="color: var(--color-text);">Enable analytics dashboard</label>
					</div>
					<!-- Radio buttons -->
					<div>
						<p class="text-xs font-medium mb-2" style="color: var(--color-text-muted);">Billing Cycle</p>
						<div class="space-y-2">
							<label class="flex items-center gap-3 cursor-pointer text-sm" style="color: var(--color-text);">
								<input type="radio" name="billing" value="monthly" class="w-4 h-4 cursor-pointer" style="accent-color: var(--color-primary);"/>
								Monthly
							</label>
							<label class="flex items-center gap-3 cursor-pointer text-sm" style="color: var(--color-text);">
								<input type="radio" name="billing" value="annual" checked class="w-4 h-4 cursor-pointer" style="accent-color: var(--color-primary);"/>
								Annual (save 20%)
							</label>
						</div>
					</div>
					<button type="submit" class="bento-btn text-sm">Submit via HTMX</button>
				</form>

Alerts & Notices

Success

Operation completed successfully.

Warning

Resource usage approaching limits.

Error

Failed to connect to database.