Skip to main content

HTML Layout

info

HTML Layout is currently under active development.

Introduction

Standard dashboards excel at monitoring, but they aren't always built for custom formatting. HTML Layout frees you from the fixed canvas, allowing you to use HTML and CSS to build highly tailored data experiences.

Choose HTML layout when traditional canvas or tab layouts can't support your use case:

  • Storytelling & slides: Create full-screen, sequential presentations with independent section layouts.
  • Print-perfect reports: Build structured, multi-column PDFs with custom headers and footers.
  • Bespoke compositions: Design complex, nested, or asymmetric layouts that are difficult to align on a traditional grid.

How it works

An HTMLLayout dashboard uses the same blocks and interactions as a canvas or tabbed dashboard - only the view changes.

Instead of pixel coordinates, you write HTML and CSS in the content field and place blocks inline using <h-block name="..." />, which renders the block's default UI at the size its container provides.

Dashboard sales_overview {
title: 'Sales Overview'

block region_filter: CustomControlBlock { ... }
block revenue_chart: VizBlock { ... }

interactions: [ ... ]

view: HTMLLayout {
content: @html
<div style="display: flex; gap: 16px;">
<h-block name="region_filter" />
<h-block name="revenue_chart" />
</div>
;;
}
}

Examples

Newspaper

A broadsheet-style financial newspaper front page with a masthead, ticker tape, stat strip, and a three-column layout that combines live charts with formatted editorial copy.

Show full code
Dashboard html_newspaper {
title: 'Newspaper'

block title: TextBlock { ... }
block v_sroh: VizBlock { ... } // Users signup (column chart)
block v_7dri: VizBlock { ... } // Gross sales table
block v_np_chart: VizBlock { ... } // Users signup by quarter (column chart)
block v_3fjd: VizBlock { ... } // Returns and sales table

view: HTMLLayout {
content: @html

<style>
@import url('https://fonts.googleapis.com/css2?family=UnifrakturMaguntia&family=Playfair+Display:ital,wght@0,400;0,700;0,900;1,400;1,700&family=Source+Serif+4:ital,opsz,wght@0,8..60,300;0,8..60,400;1,8..60,300;1,8..60,400&display=swap');

.np-root {
background: #f7f3eb;
color: #1a1510;
font-family: 'Source Serif 4', Georgia, serif;
width: 100%;
max-width: 960px;
box-sizing: border-box;
margin: 0 auto;
}
.np-masthead {
border-bottom: 3px double #1a1510;
padding: 12px 20px 8px;
text-align: center;
}
.np-masthead-name {
font-family: 'UnifrakturMaguntia', serif;
font-size: 42px;
line-height: 1;
color: #1a1510;
letter-spacing: 1px;
}
.np-masthead-meta {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 10px;
letter-spacing: 1.5px;
text-transform: uppercase;
color: #7a6e5f;
margin-top: 6px;
border-top: 0.5px solid #c9bfa8;
padding-top: 6px;
}
.np-ticker {
background: #1a1510;
color: #f7f3eb;
font-family: 'Source Serif 4', serif;
font-size: 11px;
padding: 4px 20px;
display: flex;
gap: 32px;
overflow: hidden;
}
.np-ticker span { white-space: nowrap; }
.np-ticker .up { color: #4a9e5c; font-weight: 700; }
.np-ticker .dn { color: #c94040; font-weight: 700; }

.np-stat-row {
display: grid;
grid-template-columns: repeat(4, 1fr);
border-top: 1px solid #c9bfa8;
border-bottom: 1px solid #c9bfa8;
background: #ede8dc;
}
.np-stat {
padding: 10px 16px;
border-right: 0.5px solid #c9bfa8;
text-align: center;
}
.np-stat:last-child { border-right: none; }
.np-stat-label {
font-size: 9px;
text-transform: uppercase;
letter-spacing: 1.5px;
color: #7a6e5f;
margin-bottom: 3px;
}
.np-stat-value {
font-family: 'Playfair Display', serif;
font-size: 20px;
font-weight: 700;
color: #1a1510;
}
.np-stat-change { font-size: 10px; margin-top: 2px; }
.up { color: #2e7d3c; }
.dn { color: #b83232; }

.np-body {
display: grid;
grid-template-columns: 1fr 0.5px 2fr 0.5px 1fr;
padding: 0 16px;
border-bottom: 1px solid #c9bfa8;
}
.np-col-divider { background: #c9bfa8; margin: 12px 0; }
.np-col { padding: 14px 16px; }
.np-col-main { padding: 14px 20px; }

.np-kicker {
font-size: 9px;
text-transform: uppercase;
letter-spacing: 2px;
color: #8b2020;
margin-bottom: 4px;
}
.np-headline {
font-family: 'Playfair Display', Georgia, serif;
font-size: 26px;
font-weight: 900;
line-height: 1.15;
color: #0f0c08;
margin-bottom: 8px;
}
.np-headline-sm {
font-family: 'Playfair Display', Georgia, serif;
font-size: 17px;
font-weight: 700;
line-height: 1.2;
color: #0f0c08;
margin-bottom: 6px;
}
.np-headline-xs {
font-family: 'Playfair Display', Georgia, serif;
font-size: 13px;
font-weight: 700;
line-height: 1.25;
color: #1a1510;
margin-bottom: 4px;
}
.np-deck {
font-size: 12px;
font-style: italic;
color: #5a5040;
line-height: 1.5;
margin-bottom: 8px;
}
.np-body-text {
font-size: 12px;
line-height: 1.7;
color: #3a3020;
text-align: justify;
}
.np-byline {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 1px;
color: #9a8e7a;
margin-bottom: 8px;
}
.np-rule { border: none; border-top: 0.5px solid #d4c9b4; margin: 12px 0; }
.np-rule-heavy { border: none; border-top: 1px solid #c9bfa8; margin: 12px 0; }
.np-drop-cap::first-letter {
font-family: 'Playfair Display', serif;
font-size: 46px;
font-weight: 900;
float: left;
line-height: 0.85;
margin: 4px 5px 0 0;
color: #0f0c08;
}

.np-section-label {
font-size: 9px;
text-transform: uppercase;
letter-spacing: 2px;
color: #9a8e7a;
border-bottom: 1px solid #c9bfa8;
padding-bottom: 4px;
margin-bottom: 10px;
}

.np-markets-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 6px;
margin-bottom: 10px;
}
.np-market-item {
padding: 6px 8px;
background: #ede8dc;
border-left: 2px solid #c9bfa8;
}
.np-market-item.up-border { border-left-color: #2e7d3c; }
.np-market-item.dn-border { border-left-color: #b83232; }
.np-market-name {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 1px;
color: #7a6e5f;
}
.np-market-val {
font-family: 'Playfair Display', serif;
font-size: 14px;
font-weight: 700;
color: #1a1510;
}
.np-market-chg { font-size: 10px; }

.np-chart-block {
background: #ede8dc;
border-top: 1px solid #c9bfa8;
border-bottom: 1px solid #c9bfa8;
min-height: 180px;
margin: 12px 0;
}
.np-chart-block * {
font-family: 'Source Serif 4', Georgia, serif !important;
color: #1a1510 !important;
background: transparent !important;
}

.np-brief { padding: 8px 0; border-top: 0.5px solid #d4c9b4; }
.np-brief:first-child { border-top: none; padding-top: 0; }

.np-footer {
border-top: 3px double #c9bfa8;
padding: 8px 20px;
display: flex;
justify-content: space-between;
font-size: 9px;
text-transform: uppercase;
letter-spacing: 1px;
color: #b8ad98;
background: #f0ebe0;
}
</style>

<div class="np-root">

<div class="np-masthead">
<div class="np-masthead-name">The Capital Ledger</div>
<div class="np-masthead-meta">
<span>Est. 2024</span>
<span>Finance &amp; Capital Markets</span>
<span>Wednesday, May 21, 2025</span>
</div>
</div>

<div class="np-ticker">
<span>S&amp;P 500 <span class="up">▲ 5,304.72 +0.34%</span></span>
<span>DOW <span class="up">▲ 39,112.16 +0.21%</span></span>
<span>NASDAQ <span class="dn">▼ 16,737.08 −0.18%</span></span>
<span>10Y UST <span class="up">4.52%</span></span>
<span>GOLD <span class="up">▲ $2,341.50</span></span>
<span>WTI <span class="dn">▼ $77.84 −0.9%</span></span>
<span>EUR/USD <span>1.0812</span></span>
<span>BTC <span class="up">▲ $68,420</span></span>
</div>

<div class="np-stat-row">
<div class="np-stat">
<div class="np-stat-label">S&amp;P 500</div>
<div class="np-stat-value">5,304</div>
<div class="np-stat-change up">▲ +0.34%</div>
</div>
<div class="np-stat">
<div class="np-stat-label">VIX</div>
<div class="np-stat-value">13.42</div>
<div class="np-stat-change dn">▼ −0.8%</div>
</div>
<div class="np-stat">
<div class="np-stat-label">10Y Yield</div>
<div class="np-stat-value">4.52%</div>
<div class="np-stat-change up">▲ +4 bps</div>
</div>
<div class="np-stat">
<div class="np-stat-label">DXY</div>
<div class="np-stat-value">104.71</div>
<div class="np-stat-change dn">▼ −0.12%</div>
</div>
</div>

<div class="np-body">

<div class="np-col">
<div class="np-section-label">Markets</div>
<div class="np-markets-row">
<div class="np-market-item up-border">
<div class="np-market-name">AAPL</div>
<div class="np-market-val">189.40</div>
<div class="np-market-chg up">▲ +1.2%</div>
</div>
<div class="np-market-item dn-border">
<div class="np-market-name">TSLA</div>
<div class="np-market-val">174.82</div>
<div class="np-market-chg dn">▼ −2.4%</div>
</div>
<div class="np-market-item up-border">
<div class="np-market-name">NVDA</div>
<div class="np-market-val">882.15</div>
<div class="np-market-chg up">▲ +3.1%</div>
</div>
<div class="np-market-item up-border">
<div class="np-market-name">MSFT</div>
<div class="np-market-val">418.70</div>
<div class="np-market-chg up">▲ +0.7%</div>
</div>
<div class="np-market-item dn-border">
<div class="np-market-name">AMZN</div>
<div class="np-market-val">185.44</div>
<div class="np-market-chg dn">▼ −0.3%</div>
</div>
<div class="np-market-item up-border">
<div class="np-market-name">META</div>
<div class="np-market-val">501.03</div>
<div class="np-market-chg up">▲ +1.5%</div>
</div>
</div>

<hr class="np-rule-heavy">
<div class="np-section-label">Commodities</div>
<div class="np-brief">
<div class="np-headline-xs">Gold holds above $2,340</div>
<div class="np-body-text">Spot gold maintained gains as safe-haven demand persisted amid geopolitical uncertainty in the Middle East.</div>
</div>
<div class="np-brief">
<div class="np-headline-xs">Oil slips on demand outlook</div>
<div class="np-body-text">WTI crude slid 0.9% as IEA revised global demand forecasts downward for Q3, citing slowing Chinese industrial output.</div>
</div>
<div class="np-brief">
<div class="np-headline-xs">Copper nears 2-year high</div>
<div class="np-body-text">LME copper topped $9,800/t on supply tightness and renewed AI infrastructure buildout demand.</div>
</div>
</div>

<div class="np-col-divider"></div>

<div class="np-col-main">
<div class="np-kicker">Lead Story · Federal Reserve</div>
<div class="np-headline">Fed Holds Rates, Signals Single Cut in 2024 as Inflation Proves Stubborn</div>
<div class="np-deck">Minutes from May meeting reveal a divided committee; two members dissented in favour of an immediate reduction</div>
<div class="np-byline">By Staff Correspondent</div>
<div class="np-body-text np-drop-cap">
The Federal Open Market Committee voted 10–2 to hold the federal funds rate at 5.25–5.50 percent on Wednesday, marking the seventh consecutive meeting at which policymakers chose to leave borrowing costs unchanged. The decision, widely anticipated by futures markets, was accompanied by updated projections that reduced the committee's median expectation for rate cuts this year from three reductions to just one.
</div>
<div class="np-body-text" style="margin-top:8px;">
Chair Jerome Powell acknowledged that progress on inflation had "stalled somewhat" in the opening months of the year, with core PCE running above 3 percent for the fourth consecutive quarter. The committee would need "greater confidence" before reducing rates, he said.
</div>

<div class="np-chart-block">
<h-block name="v_np_chart" />
</div>

<hr class="np-rule">
<div class="np-kicker">Secondary Story · Treasury Markets</div>
<div class="np-headline-sm">Yields Climb as Auction Draws Weak Demand; 10-Year Approaches 4.60%</div>
<div class="np-body-text">Tuesday's $44 billion 10-year note auction saw the lowest bid-to-cover ratio in over a year, raising questions about appetite for long-duration paper as the fiscal deficit continues to widen. The 10-year yield rose 4 basis points to 4.52 percent.</div>
</div>

<div class="np-col-divider"></div>

<div class="np-col">
<div class="np-section-label">Analysis</div>
<div class="np-brief">
<div class="np-kicker" style="margin-bottom:2px">Opinion</div>
<div class="np-headline-xs">The soft landing is real — but fragile</div>
<div class="np-body-text">Labour markets remain resilient while inflation cools, but a single exogenous shock could snap the thread that keeps this cycle alive.</div>
</div>
<hr class="np-rule">
<div class="np-brief">
<div class="np-kicker" style="margin-bottom:2px">Earnings</div>
<div class="np-headline-xs">Big Tech beats expectations for third straight quarter</div>
<div class="np-body-text">Aggregate earnings for the Magnificent Seven rose 42% year-on-year, driven by AI cloud revenue and cost-cutting across headcount.</div>
</div>
<hr class="np-rule">
<div class="np-brief">
<div class="np-kicker" style="margin-bottom:2px">Private Equity</div>
<div class="np-headline-xs">Buyout deal volume rises 18% as credit markets ease</div>
<div class="np-body-text">Falling leveraged loan spreads and improving LP sentiment revived dealmaking, with Q1 global buyout volume reaching $98bn.</div>
</div>
<hr class="np-rule">
<div class="np-brief">
<div class="np-kicker" style="margin-bottom:2px">Crypto</div>
<div class="np-headline-xs">Spot ETH ETF approval seen by July, analysts say</div>
<div class="np-body-text">SEC's revised engagement with issuers raised approval odds to 70%, according to a Bloomberg Intelligence note published Wednesday.</div>
</div>
<hr class="np-rule">
<div class="np-brief">
<div class="np-kicker" style="margin-bottom:2px">Currency</div>
<div class="np-headline-xs">Yen slides past 157, BoJ intervention risks rise</div>
<div class="np-body-text">The yen tested fresh 34-year lows against the dollar as the Bank of Japan maintained its ultra-loose stance despite political pressure.</div>
</div>
</div>

</div>

<div class="np-footer">
<span>The Capital Ledger · All data delayed 15 minutes</span>
<span>For informational purposes only. Not financial advice.</span>
<span>© 2025 Capital Ledger Media</span>
</div>

</div>

;;
}

theme {
block {
background { bg_color: "transparent" }
border { border_width: 0 }
}
}
}

Paginated report

A two-page A4 annual report with a KPI strip, charts, and a data table. Each page uses fixed 210mm × 297mm dimensions with page-break-after: always for clean PDF output.

Show full code
Dashboard html_annual_report {
title: 'Annual Report'

block title: TextBlock { ... }
block v_sroh: VizBlock { ... } // Revenue by quarter (column chart)
block v_gender_donut: VizBlock { ... } // Gender breakdown (donut)
block v_dd7r: VizBlock { ... } // Returned vs cancelled (area chart)
block v_5eey: VizBlock { ... } // Gross sales (KPI)
block v_active_clients: VizBlock { ... }
block v_gross_margin: VizBlock { ... }
block v_nps: VizBlock { ... }
block v_cpu: VizBlock { ... } // Cost per unit (area chart)
block v_churn: VizBlock { ... } // Churn rate (area chart)
block v_deal_vel: VizBlock { ... } // Deal velocity (bar chart)

view: HTMLLayout {
content: @html

<link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&family=DM+Sans:wght@300;400;500;600&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root {
--ink: #0f0f0f;
--paper: #f7f4ef;
--accent: #e63222;
--accent-2: #1a3a5c;
--muted: #8a8278;
--rule: #d4cfc8;
--page-w: 210mm;
--page-h: 297mm;
--margin: 14mm;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
font-family: 'DM Sans', sans-serif;
color: var(--ink);
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}

.page {
width: var(--page-w);
min-height: var(--page-h);
background: var(--paper);
margin: auto;
padding: var(--margin);
position: relative;
overflow: hidden;
box-shadow: 0 8px 40px rgba(0,0,0,.18);
}

.page::before {
content: '';
position: absolute;
top: 0; right: 0;
width: 52mm; height: 52mm;
background: var(--accent-2);
clip-path: polygon(100% 0, 100% 100%, 0 0);
}

.page-header {
position: relative;
z-index: 1;
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 10mm;
padding-bottom: 5mm;
border-bottom: 2px solid var(--ink);
}

.report-title {
font-family: 'Bebas Neue', sans-serif;
font-size: 42pt;
line-height: .9;
color: var(--ink);
}

.stat-strip {
display: grid;
grid-template-columns: repeat(4, 1fr);
margin-bottom: 8mm;
}

.stat-item {
padding: 4mm 5mm;
border-right: 1.5px solid var(--ink);
}
.stat-item:last-child { border-right: none; }

.stat-label {
font-size: 6.5pt;
letter-spacing: .15em;
text-transform: uppercase;
color: var(--muted);
margin-top: 1mm;
}

.two-col {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 6mm;
margin-bottom: 8mm;
}

.three-col {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 6mm;
margin-bottom: 8mm;
}

.section-label {
font-family: 'DM Mono', monospace;
font-size: 6.5pt;
letter-spacing: .25em;
text-transform: uppercase;
color: var(--accent);
margin-bottom: 2mm;
}

.section-title {
font-family: 'Bebas Neue', sans-serif;
font-size: 18pt;
color: var(--accent-2);
margin-bottom: 4mm;
}

.page-footer {
position: absolute;
bottom: 6mm;
left: var(--margin);
right: var(--margin);
display: flex;
justify-content: space-between;
}

.footer-brand {
font-family: 'Bebas Neue', sans-serif;
font-size: 9pt;
color: var(--muted);
}

@media print {
.page { margin: 0; box-shadow: none; page-break-after: always; }
.page:last-child { page-break-after: auto; }
}
</style>

<!-- PAGE 1 -->
<div class="page">
<header class="page-header">
<div class="report-title">Annual Report</div>
</header>

<div class="stat-strip">
<div class="stat-item">
<h-block name="v_5eey" />
<div class="stat-label">Total Revenue</div>
</div>
<div class="stat-item">
<h-block name="v_active_clients" />
<div class="stat-label">Active Clients</div>
</div>
<div class="stat-item">
<h-block name="v_gross_margin" />
<div class="stat-label">Gross Margin</div>
</div>
<div class="stat-item">
<h-block name="v_nps" />
<div class="stat-label">NPS Score</div>
</div>
</div>

<div style="margin-bottom: 8mm;">
<div class="section-label">Revenue Performance</div>
<div class="section-title">Revenue by Quarter</div>
<h-block name="v_sroh" />
</div>

<div class="two-col">
<div>
<div class="section-label">Revenue Mix</div>
<div class="section-title">By Gender</div>
<h-block name="v_gender_donut" />
</div>
<div>
<div class="section-label">Returns vs Cancellations</div>
<div class="section-title">By Quarter</div>
<h-block name="v_dd7r" />
</div>
</div>

<footer class="page-footer">
<div class="footer-brand">Company Name</div>
<div>Page 01 / 02</div>
</footer>
</div>

<!-- PAGE 2 -->
<div class="page">
<header class="page-header">
<div style="font-family:'Bebas Neue',sans-serif; font-size:18pt; color:var(--accent-2);">
Operational Review
</div>
</header>

<div class="three-col">
<div>
<div class="section-label">Efficiency</div>
<div class="section-title" style="font-size:12pt;">Cost per Unit</div>
<h-block name="v_cpu" />
</div>
<div>
<div class="section-label">Retention</div>
<div class="section-title" style="font-size:12pt;">Churn Rate</div>
<h-block name="v_churn" />
</div>
<div>
<div class="section-label">Pipeline</div>
<div class="section-title" style="font-size:12pt;">Deal Velocity</div>
<h-block name="v_deal_vel" />
</div>
</div>

<footer class="page-footer">
<div class="footer-brand">Company Name</div>
<div>Page 02 / 02</div>
</footer>
</div>

;;
}

theme {
block {
background {
bg_color: "transparent"
}
border {
border_width: 0
}
}
}
}

Responsive bento grid

An asymmetric bento-style layout with three responsive breakpoints (desktop, tablet, mobile). The grid reflows automatically as the viewport narrows, with no JavaScript required — just CSS grid-template-areas and @media queries.

Show full code
Dashboard html_responsive {
title: 'Responsive Dashboard'

block title: TextBlock { ... }
block v_signup: VizBlock { ... } // Revenue by quarter (column chart)
block v_monthly: VizBlock { ... } // Monthly signups (column chart)
block v_yearly: VizBlock { ... } // Yearly signups (column chart)
block v_conversion: VizBlock { ... } // Net sales margin (KPI)
block v_metric_kpi: VizBlock { ... } // Gross sales (KPI)

view: HTMLLayout {
content: @html
<!-- ============================================================
Asymmetric Bento Dashboard — Light/Clean
Pure HTML/CSS, no JS, scoped via .bento-root prefix
Demonstrates responsiveness: resize the window to see the
layout reflow at 3 breakpoints (>1100px, 700–1100px, <700px)
============================================================ -->

<div class="bento-root">
<style>
/* ---------- Reset (scoped via prefix) ---------- */
.bento-root,
.bento-root *,
.bento-root *::before,
.bento-root *::after { box-sizing: border-box; }

/* ---------- Root container & tokens ---------- */
.bento-root {
/* Surfaces */
--b-bg: #f5f5f4;
--b-card: #ffffff;
--b-card-alt: #fafaf9;
--b-ink: #1c1917;
--b-ink-soft: #57534e;
--b-ink-faint: #a8a29e;
--b-line: #e7e5e4;

/* Accents */
--b-orange: #ea580c;
--b-blue: #0284c7;
--b-green: #16a34a;
--b-purple: #7c3aed;
--b-pink: #ec4899;
--b-yellow: #fbbf24;

--b-radius: 20px;
--b-radius-sm: 12px;
--b-gap: 14px;

--b-font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Inter, Roboto, sans-serif;
--b-font-mono: ui-monospace, "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
--b-font-display: "Inter", ui-sans-serif, system-ui, sans-serif;

display: block;
font-family: var(--b-font-sans);
color: var(--b-ink);
background: var(--b-bg);
padding: 32px;
border-radius: var(--b-radius);
position: relative;
min-height: 600px;
}

/* ---------- Top bar ---------- */
.bento-root .b-topbar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24px;
gap: 16px;
flex-wrap: wrap;
}
.bento-root .b-brand {
display: flex;
align-items: baseline;
gap: 10px;
}
.bento-root .b-logo {
font-family: var(--b-font-display);
font-size: 22px;
font-weight: 700;
letter-spacing: -0.02em;
color: var(--b-ink);
}
.bento-root .b-logo-dot {
display: inline-block;
width: 10px;
height: 10px;
background: var(--b-orange);
border-radius: 50%;
vertical-align: middle;
margin-right: 2px;
}
.bento-root .b-tag {
font-family: var(--b-font-mono);
font-size: 11px;
color: var(--b-ink-soft);
background: var(--b-card);
border: 1px solid var(--b-line);
padding: 4px 10px;
border-radius: 20px;
text-transform: uppercase;
letter-spacing: 0.08em;
}

/* Breakpoint indicator */
.bento-root .b-bp-indicator {
display: flex;
gap: 6px;
font-family: var(--b-font-mono);
font-size: 11px;
}
.bento-root .b-bp-dot {
padding: 5px 10px;
border-radius: 12px;
border: 1px solid var(--b-line);
background: var(--b-card);
color: var(--b-ink-faint);
transition: all 0.2s ease;
letter-spacing: 0.05em;
}

/* ---------- BENTO GRID ---------- */
.bento-root .b-grid {
display: grid;
gap: var(--b-gap);

/* Desktop: asymmetric grid */
grid-template-columns: repeat(6, 1fr);
grid-auto-rows: 140px;
grid-template-areas:
"hero hero hero hero stat1 stat1"
"hero hero hero hero stat2 stat2"
"chart chart team team activity activity"
"chart chart team team activity activity"
"metric metric chart2 chart2 chart2 chart2"
"metric metric chart2 chart2 chart2 chart2";
}

.bento-root .b-tile {
background: var(--b-card);
border: 1px solid var(--b-line);
border-radius: var(--b-radius);
padding: 22px;
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1),
box-shadow 0.25s ease,
border-color 0.25s ease;
animation: b-fade-in 0.6s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.bento-root .b-tile:hover {
transform: translateY(-3px);
box-shadow: 0 12px 30px -10px rgba(0,0,0,0.12);
border-color: var(--b-ink-faint);
}

/* Staggered entrance */
.bento-root .b-tile:nth-child(1) { animation-delay: 0.05s; }
.bento-root .b-tile:nth-child(2) { animation-delay: 0.10s; }
.bento-root .b-tile:nth-child(3) { animation-delay: 0.15s; }
.bento-root .b-tile:nth-child(4) { animation-delay: 0.20s; }
.bento-root .b-tile:nth-child(5) { animation-delay: 0.25s; }
.bento-root .b-tile:nth-child(6) { animation-delay: 0.30s; }
.bento-root .b-tile:nth-child(7) { animation-delay: 0.35s; }
.bento-root .b-tile:nth-child(8) { animation-delay: 0.40s; }

@keyframes b-fade-in {
from { opacity: 0; transform: translateY(12px); }
to { opacity: 1; transform: translateY(0); }
}

/* ----- grid area assignments ----- */
.bento-root .b-tile.area-hero { grid-area: hero; }
.bento-root .b-tile.area-stat1 { grid-area: stat1; }
.bento-root .b-tile.area-stat2 { grid-area: stat2; }
.bento-root .b-tile.area-chart { grid-area: chart; }
.bento-root .b-tile.area-team { grid-area: team; }
.bento-root .b-tile.area-activity { grid-area: activity; }
.bento-root .b-tile.area-metric { grid-area: metric; }
.bento-root .b-tile.area-chart2 { grid-area: chart2; }

/* ============================================================
BREAKPOINTS
============================================================ */

/* Tablet */
@media (max-width: 1100px) {
.bento-root .b-grid {
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 140px;
grid-template-areas:
"hero hero hero stat1"
"hero hero hero stat2"
"chart chart team team"
"chart chart team team"
"activity activity metric metric"
"chart2 chart2 chart2 chart2"
"chart2 chart2 chart2 chart2";
}
}

/* Mobile */
@media (max-width: 700px) {
.bento-root { padding: 18px; }
.bento-root .b-grid {
grid-template-columns: 1fr;
grid-auto-rows: auto;
grid-template-areas:
"hero"
"stat1"
"stat2"
"chart"
"team"
"activity"
"metric"
"chart2";
}
.bento-root .b-tile { min-height: 160px; }
.bento-root .b-tile.area-hero { min-height: 240px; }
}

/* Breakpoint indicator active states */
.bento-root .b-bp-dot.bp-desktop { background: var(--b-ink); color: white; border-color: var(--b-ink); }
@media (max-width: 1100px) {
.bento-root .b-bp-dot.bp-desktop { background: var(--b-card); color: var(--b-ink-faint); border-color: var(--b-line); }
.bento-root .b-bp-dot.bp-tablet { background: var(--b-ink); color: white; border-color: var(--b-ink); }
}
@media (max-width: 700px) {
.bento-root .b-bp-dot.bp-tablet { background: var(--b-card); color: var(--b-ink-faint); border-color: var(--b-line); }
.bento-root .b-bp-dot.bp-mobile { background: var(--b-ink); color: white; border-color: var(--b-ink); }
}

/* ============================================================
TILE-SPECIFIC CONTENT STYLES
============================================================ */

/* ----- HERO ----- */
.bento-root .b-tile.area-hero {
background: linear-gradient(135deg, #1c1917 0%, #292524 100%);
color: white;
border-color: transparent;
justify-content: space-between;
}
.bento-root .b-tile.area-hero::before {
content: "";
position: absolute;
top: -50%;
right: -20%;
width: 400px;
height: 400px;
background: radial-gradient(circle, rgba(234, 88, 12, 0.4), transparent 60%);
pointer-events: none;
}
.bento-root .b-hero-eyebrow {
font-family: var(--b-font-mono);
font-size: 11px;
color: rgba(255,255,255,0.6);
text-transform: uppercase;
letter-spacing: 0.15em;
position: relative;
z-index: 1;
}
.bento-root .b-hero-headline {
font-family: var(--b-font-display);
font-size: clamp(28px, 4vw, 48px);
font-weight: 700;
line-height: 1.05;
letter-spacing: -0.03em;
margin: 0;
position: relative;
z-index: 1;
}
.bento-root .b-hero-headline span {
background: linear-gradient(120deg, var(--b-orange), var(--b-yellow));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.bento-root .b-hero-row {
display: flex;
justify-content: space-between;
align-items: flex-end;
gap: 16px;
position: relative;
z-index: 1;
flex-wrap: wrap;
}
.bento-root .b-hero-stat {
font-family: var(--b-font-mono);
font-size: 12px;
color: rgba(255,255,255,0.7);
}
.bento-root .b-hero-stat b {
display: block;
font-family: var(--b-font-display);
font-size: 22px;
font-weight: 600;
color: white;
margin-bottom: 2px;
}

/* ----- STAT TILES ----- */
.bento-root .b-stat-label {
font-family: var(--b-font-mono);
font-size: 10px;
color: var(--b-ink-soft);
text-transform: uppercase;
letter-spacing: 0.12em;
margin-bottom: 8px;
}
.bento-root .b-stat-value {
font-family: var(--b-font-display);
font-size: clamp(28px, 3.5vw, 40px);
font-weight: 700;
letter-spacing: -0.03em;
line-height: 1;
}
.bento-root .b-stat-delta {
font-family: var(--b-font-mono);
font-size: 11px;
margin-top: auto;
padding-top: 12px;
}
.bento-root .b-stat-delta.up { color: var(--b-green); }
.bento-root .b-stat-delta.down { color: var(--b-orange); }

.bento-root .b-tile.area-stat1 { background: linear-gradient(135deg, #dbeafe 0%, #ffffff 100%); }
.bento-root .b-tile.area-stat2 { background: linear-gradient(135deg, #dcfce7 0%, #ffffff 100%); }

/* ----- CHART tiles ----- */
.bento-root .b-card-eyebrow {
font-family: var(--b-font-mono);
font-size: 10px;
color: var(--b-ink-faint);
text-transform: uppercase;
letter-spacing: 0.12em;
margin-bottom: 6px;
}
.bento-root .b-card-title {
font-family: var(--b-font-display);
font-size: 18px;
font-weight: 600;
letter-spacing: -0.02em;
margin: 0 0 14px 0;
}
.bento-root .b-chart {
flex: 1;
min-height: 80px;
border: 1px dashed var(--b-line);
border-radius: var(--b-radius-sm);
background-color: var(--b-card-alt);
background-image:
linear-gradient(rgba(0,0,0,0.025) 1px, transparent 1px),
linear-gradient(90deg, rgba(0,0,0,0.025) 1px, transparent 1px);
background-size: 24px 24px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
gap: 6px;
position: relative;
overflow: hidden;
}

/* ----- TEAM tile ----- */
.bento-root .b-tile.area-team {
background: linear-gradient(135deg, #fef3c7 0%, #ffffff 100%);
}
.bento-root .b-avatars {
display: flex;
margin-top: 14px;
}
.bento-root .b-avatar {
width: 44px;
height: 44px;
border-radius: 50%;
border: 3px solid white;
margin-left: -10px;
display: flex;
align-items: center;
justify-content: center;
font-family: var(--b-font-display);
font-weight: 600;
font-size: 14px;
color: white;
}
.bento-root .b-avatar:first-child { margin-left: 0; }
.bento-root .b-avatar.a1 { background: var(--b-orange); }
.bento-root .b-avatar.a2 { background: var(--b-blue); }
.bento-root .b-avatar.a3 { background: var(--b-purple); }
.bento-root .b-avatar.a4 { background: var(--b-pink); }
.bento-root .b-avatar.a5 {
background: var(--b-card);
color: var(--b-ink-soft);
border-color: var(--b-line);
font-size: 12px;
}
.bento-root .b-team-meta {
margin-top: auto;
font-family: var(--b-font-mono);
font-size: 11px;
color: var(--b-ink-soft);
padding-top: 14px;
}

/* ----- ACTIVITY tile ----- */
.bento-root .b-tile.area-activity {
background: var(--b-card-alt);
}
.bento-root .b-feed {
margin-top: 8px;
display: flex;
flex-direction: column;
gap: 10px;
font-family: var(--b-font-mono);
font-size: 12px;
overflow: hidden;
}
.bento-root .b-feed-item {
display: flex;
gap: 10px;
align-items: flex-start;
color: var(--b-ink-soft);
}
.bento-root .b-feed-dot {
width: 6px;
height: 6px;
border-radius: 50%;
margin-top: 5px;
flex-shrink: 0;
}
.bento-root .b-feed-dot.c1 { background: var(--b-green); }
.bento-root .b-feed-dot.c2 { background: var(--b-blue); }
.bento-root .b-feed-dot.c3 { background: var(--b-purple); }
.bento-root .b-feed-dot.c4 { background: var(--b-orange); }
.bento-root .b-feed-item b {
color: var(--b-ink);
font-weight: 500;
}
.bento-root .b-feed-time {
font-size: 10px;
color: var(--b-ink-faint);
margin-left: auto;
flex-shrink: 0;
}

/* ----- METRIC tile (big number) ----- */
.bento-root .b-tile.area-metric {
background: linear-gradient(135deg, var(--b-orange) 0%, #f97316 100%);
color: white;
border-color: transparent;
justify-content: space-between;
}
.bento-root .b-tile.area-metric::before {
content: "";
position: absolute;
top: -30%;
right: -30%;
width: 250px;
height: 250px;
background: radial-gradient(circle, rgba(255,255,255,0.2), transparent 60%);
pointer-events: none;
}
.bento-root .b-metric-eyebrow {
font-family: var(--b-font-mono);
font-size: 10px;
color: rgba(255,255,255,0.8);
text-transform: uppercase;
letter-spacing: 0.15em;
position: relative;
z-index: 1;
}
.bento-root .b-metric-value {
font-family: var(--b-font-display);
font-size: clamp(36px, 5vw, 56px);
font-weight: 700;
letter-spacing: -0.04em;
line-height: 1;
position: relative;
z-index: 1;
}
.bento-root .b-metric-foot {
font-family: var(--b-font-mono);
font-size: 11px;
color: rgba(255,255,255,0.85);
position: relative;
z-index: 1;
}

/* ----- Live chart overrides ----- */
.bento-root .b-chart.b-chart-live {
border: none;
background: transparent;
background-image: none;
animation: none;
align-items: stretch;
justify-content: stretch;
padding: 0;
}
.bento-root .b-chart.b-chart-live::after { display: none; }
.bento-root .b-chart.b-chart-live * {
background: transparent !important;
}
.bento-root .b-chart.b-chart-mini {
flex: 1;
min-height: 80px;
}
</style>

<!-- =================== TOP BAR =================== -->
<div class="b-topbar">
<div class="b-brand">
<div class="b-logo"><span class="b-logo-dot"></span>bento</div>
<span class="b-tag">Responsive demo</span>
</div>
<div class="b-bp-indicator">
<span class="b-bp-dot bp-desktop">DESKTOP &gt;1100</span>
<span class="b-bp-dot bp-tablet">TABLET 700-1100</span>
<span class="b-bp-dot bp-mobile">MOBILE &lt;700</span>
</div>
</div>

<!-- =================== BENTO GRID =================== -->
<div class="b-grid">

<!-- HERO tile -->
<div class="b-tile area-hero">
<div class="b-hero-eyebrow">Q2 2026 · Performance</div>
<h2 class="b-hero-headline">Revenue is up <span>+24%</span> this quarter.</h2>
<div class="b-hero-row">
<div class="b-hero-stat"><b>$4.2M</b>Total revenue</div>
<div class="b-hero-stat"><b>12,480</b>Active customers</div>
<div class="b-hero-stat"><b>98.%</b>Uptime</div>
</div>
</div>

<!-- STAT 1 -->
<div class="b-tile area-stat1">
<div class="b-stat-label">Monthly Signups</div>
<div class="b-chart b-chart-live b-chart-mini">
<h-block name="v_monthly" />
</div>
</div>

<!-- STAT 2 -->
<div class="b-tile area-stat2">
<div class="b-stat-label">Net Sales Margin</div>
<div class="b-stat-value">
<h-block name="v_conversion" />
</div>
</div>

<!-- CHART -->
<div class="b-tile area-chart">
<div class="b-card-eyebrow">Trend</div>
<h3 class="b-card-title">Revenue this quarter</h3>
<div class="b-chart b-chart-live">
<h-block name="v_signup" />
</div>
</div>

<!-- TEAM -->
<div class="b-tile area-team">
<div class="b-card-eyebrow">Collaboration</div>
<h3 class="b-card-title">Active team</h3>
<div class="b-avatars">
<div class="b-avatar a1">MR</div>
<div class="b-avatar a2">JL</div>
<div class="b-avatar a3">SK</div>
<div class="b-avatar a4">AN</div>
<div class="b-avatar a5">+8</div>
</div>
<div class="b-team-meta">12 members · 4 online now</div>
</div>

<!-- ACTIVITY -->
<div class="b-tile area-activity">
<div class="b-card-eyebrow">Live feed</div>
<h3 class="b-card-title">Recent activity</h3>
<div class="b-feed">
<div class="b-feed-item">
<span class="b-feed-dot c1"></span>
<span><b>Maria</b> closed deal #4821</span>
<span class="b-feed-time">2m</span>
</div>
<div class="b-feed-item">
<span class="b-feed-dot c2"></span>
<span><b>James</b> updated forecast</span>
<span class="b-feed-time">8m</span>
</div>
<div class="b-feed-item">
<span class="b-feed-dot c3"></span>
<span><b>Sara</b> published report</span>
<span class="b-feed-time">14m</span>
</div>
<div class="b-feed-item">
<span class="b-feed-dot c4"></span>
<span><b>Alex</b> flagged risk</span>
<span class="b-feed-time">22m</span>
</div>
</div>
</div>

<!-- METRIC (orange feature) -->
<div class="b-tile area-metric">
<div class="b-metric-eyebrow">Gross Sales</div>
<div class="b-metric-value">
<h-block name="v_metric_kpi" />
</div>
<div class="b-metric-foot">Total value of all products sold</div>
</div>

<!-- CHART 2 -->
<div class="b-tile area-chart2">
<div class="b-card-eyebrow">Channels</div>
<h3 class="b-card-title">Acquisition breakdown</h3>
<div class="b-chart b-chart-live">
<h-block name="v_yearly" />
</div>
</div>

</div>
</div>

;;
}

theme {
block {
background { bg_color: "transparent" }
border { border_width: 0 }
}
}
}

Slides

A five-slide presentation deck with CSS-only navigation using anchor links and :target. Each slide shows a live chart alongside a headline and key insight, with prev/next buttons and dot indicators.

Show full code
Dashboard html_slides {
title: 'HTML Slides'

block title: TextBlock { ... }
block v_sroh: VizBlock { ... } // Users signup (column chart)
block v_7dri: VizBlock { ... } // Orders by status (donut)
block v_s3_area: VizBlock { ... } // Returned vs cancelled (area chart)
block v_s4_bar: VizBlock { ... } // Orders by status (bar chart)
block v_s5_kpi: VizBlock { ... } // Gross sales trend (area chart)

view: HTMLLayout {
content: @html

<div class="insights">
<style>
.insights,
.insights *,
.insights *::before,
.insights *::after { box-sizing: border-box; }

.insights {
--in-bg: #0b0d12;
--in-surface: #14171f;
--in-surface-2: #1a1e28;
--in-border: #262b38;
--in-border-strong: #353b4d;
--in-text: #e6e8ee;
--in-text-dim: #8b91a3;
--in-text-faint: #5a6075;
--in-blue: #4d8cff;
--in-red: #ff5a5f;
--in-green: #2ecc71;
--in-purple: #a78bfa;
--in-amber: #f5a524;
--in-radius: 6px;
--in-font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
--in-font-mono: ui-monospace, "JetBrains Mono", "Fira Code", "SF Mono", Menlo, Consolas, monospace;
--in-font-display: "Impact", "Arial Narrow Bold", "Bebas Neue", sans-serif;

display: flex;
flex-direction: column;
font-family: var(--in-font-sans);
color: var(--in-text);
background: var(--in-bg);
padding: 28px 32px;
border-radius: var(--in-radius);
min-height: 720px;
position: relative;
overflow: hidden;
height: 100%;
}

.insights::before {
content: "";
position: absolute;
top: -200px; right: -200px;
width: 600px; height: 600px;
background: radial-gradient(circle, rgba(167,139,250,0.08), transparent 70%);
pointer-events: none;
z-index: 0;
}
.insights > * { position: relative; z-index: 1; }

/* Top bar */
.insights .in-topbar {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 18px;
margin-bottom: 24px;
border-bottom: 1px solid var(--in-border);
}
.insights .in-logo {
font-family: var(--in-font-display);
font-size: 22px;
letter-spacing: 0.05em;
font-weight: 900;
}
.insights .in-logo span { color: var(--in-red); }
.insights .in-deck-label {
color: var(--in-text-dim);
font-size: 12px;
font-family: var(--in-font-mono);
padding-left: 18px;
border-left: 1px solid var(--in-border);
letter-spacing: 0.1em;
text-transform: uppercase;
}
.insights .in-meta {
font-family: var(--in-font-mono);
font-size: 11px;
color: var(--in-text-faint);
letter-spacing: 0.1em;
text-transform: uppercase;
}

/* Slides: hidden by default, shown when targeted */
.insights .in-slide {
display: none;
flex: 1;
min-height: 560px;
flex-direction: column;
animation: in-slide-in 0.45s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.insights .in-slide:target { display: flex; }
.insights:not(:has(.in-slide:target)) #in-slide-1 { display: flex; }

@keyframes in-slide-in {
from { opacity: 0; transform: translateX(20px); }
to { opacity: 1; transform: translateX(0); }
}

/* Per-slide nav */
.insights .in-nav {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 24px;
padding-bottom: 18px;
border-bottom: 1px solid var(--in-border);
}
.insights .in-nav-left,
.insights .in-nav-right {
display: flex;
align-items: center;
gap: 12px;
}
.insights .in-counter-num {
font-family: var(--in-font-display);
font-size: 22px;
color: var(--in-text);
font-weight: 900;
}
.insights .in-counter-sep,
.insights .in-counter-total {
color: var(--in-text-faint);
font-family: var(--in-font-display);
font-size: 18px;
}
.insights .in-nav-btn {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 10px 16px;
background: var(--in-surface);
border: 1px solid var(--in-border);
border-radius: 4px;
color: var(--in-text);
text-decoration: none;
font-family: var(--in-font-mono);
font-size: 11px;
letter-spacing: 0.12em;
text-transform: uppercase;
font-weight: 500;
transition: border-color 0.2s ease, background 0.2s ease;
}
.insights .in-nav-btn.next.primary {
background: var(--in-red);
border-color: var(--in-red);
color: #fff;
}
.insights .in-nav-btn.disabled {
opacity: 0.3;
pointer-events: none;
}

/* Slide body */
.insights .in-slide-body {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 40px;
flex: 1;
align-items: stretch;
}
@media (max-width: 900px) {
.insights .in-slide-body { grid-template-columns: 1fr; }
}

/* Chart side */
.insights .in-chart {
border: 1px solid var(--in-border);
border-radius: 4px;
background: var(--in-surface);
display: flex;
align-items: stretch;
justify-content: stretch;
padding: 12px;
min-height: 360px;
}
.insights .in-chart * {
background: transparent !important;
color: var(--in-text) !important;
}

/* Insight side */
.insights .in-insight {
display: flex;
flex-direction: column;
justify-content: center;
}
.insights .in-eyebrow {
font-family: var(--in-font-mono);
font-size: 11px;
color: var(--in-red);
letter-spacing: 0.2em;
text-transform: uppercase;
margin-bottom: 18px;
}
.insights .in-headline {
font-family: var(--in-font-display);
font-size: 52px;
line-height: 0.98;
margin: 0 0 24px 0;
font-weight: 900;
}
.insights .in-lede {
font-size: 16px;
line-height: 1.6;
color: var(--in-text-dim);
margin: 0 0 28px 0;
}
.insights .in-stat {
display: flex;
align-items: baseline;
gap: 14px;
padding-top: 20px;
border-top: 1px solid var(--in-border);
}
.insights .in-stat-num {
font-family: var(--in-font-display);
font-size: 44px;
line-height: 1;
font-weight: 900;
}
.insights .in-stat-label {
font-family: var(--in-font-mono);
font-size: 11px;
color: var(--in-text-dim);
letter-spacing: 0.1em;
text-transform: uppercase;
max-width: 220px;
line-height: 1.5;
}

.insights .in-accent { color: var(--in-red); }
.insights .in-accent-blue { color: var(--in-blue); }
.insights .in-accent-green { color: var(--in-green); }
.insights .in-accent-purple { color: var(--in-purple); }
.insights .in-accent-amber { color: var(--in-amber); }

/* Dot indicators */
.insights .in-dots {
display: flex;
gap: 8px;
justify-content: center;
margin-top: 24px;
padding-top: 20px;
border-top: 1px solid var(--in-border);
}
.insights .in-dot-link {
display: block;
width: 28px;
height: 4px;
border-radius: 2px;
background: var(--in-border);
transition: background 0.25s ease, width 0.25s ease;
}
.insights:has(#in-slide-1:target) .in-dot-link[href="#in-slide-1"],
.insights:has(#in-slide-2:target) .in-dot-link[href="#in-slide-2"],
.insights:has(#in-slide-3:target) .in-dot-link[href="#in-slide-3"],
.insights:has(#in-slide-4:target) .in-dot-link[href="#in-slide-4"],
.insights:has(#in-slide-5:target) .in-dot-link[href="#in-slide-5"] {
background: var(--in-red);
width: 40px;
}
.insights:not(:has(.in-slide:target)) .in-dot-link[href="#in-slide-1"] {
background: var(--in-red);
width: 40px;
}
</style>

<!-- TOP BAR -->
<div class="in-topbar">
<div style="display:flex;align-items:center;gap:18px;">
<div class="in-logo">DASH<span>·</span>HQ</div>
<div class="in-deck-label">Deck: Q2 Insights</div>
</div>
<div class="in-meta">FY 2026 · INTERNAL</div>
</div>

<!-- SLIDE 1 -->
<section class="in-slide" id="in-slide-1">
<div class="in-nav">
<div class="in-nav-left">
<span class="in-nav-btn disabled">← Prev</span>
<span><span class="in-counter-num">01</span><span class="in-counter-sep"> / </span><span class="in-counter-total">05</span></span>
</div>
<div class="in-nav-right">
<a class="in-nav-btn next primary" href="#in-slide-2">Next →</a>
</div>
</div>
<div class="in-slide-body">
<div class="in-chart"><h-block name="v_sroh" /></div>
<div class="in-insight">
<div class="in-eyebrow">Q2 2026 · Top-line Finding</div>
<h2 class="in-headline">Revenue grew<br><span class="in-accent">faster than forecast.</span></h2>
<p class="in-lede">We exceeded plan by over 18% this quarter, driven by enterprise expansion and faster time-to-value in onboarding.</p>
<div class="in-stat">
<div class="in-stat-num in-accent-green">+18.4%</div>
<div class="in-stat-label">YoY revenue growth, vs +12% Q1 forecast</div>
</div>
</div>
</div>
</section>

<!-- SLIDE 2 -->
<section class="in-slide" id="in-slide-2">
<div class="in-nav">
<div class="in-nav-left">
<a class="in-nav-btn prev" href="#in-slide-1">← Prev</a>
<span><span class="in-counter-num">02</span><span class="in-counter-sep"> / </span><span class="in-counter-total">05</span></span>
</div>
<div class="in-nav-right">
<a class="in-nav-btn next primary" href="#in-slide-3">Next →</a>
</div>
</div>
<div class="in-slide-body">
<div class="in-chart"><h-block name="v_7dri" /></div>
<div class="in-insight">
<div class="in-eyebrow">Channel Attribution</div>
<h2 class="in-headline">Enterprise carried<br><span class="in-accent-blue">the quarter.</span></h2>
<p class="in-lede">Enterprise contracts accounted for 43.8% of new revenue, up from 31% a year ago. Mid-market held steady.</p>
<div class="in-stat">
<div class="in-stat-num in-accent-blue">43.8%</div>
<div class="in-stat-label">share of new revenue from enterprise segment</div>
</div>
</div>
</div>
</section>

<!-- SLIDE 3 -->
<section class="in-slide" id="in-slide-3">
<div class="in-nav">
<div class="in-nav-left">
<a class="in-nav-btn prev" href="#in-slide-2">← Prev</a>
<span><span class="in-counter-num">03</span><span class="in-counter-sep"> / </span><span class="in-counter-total">05</span></span>
</div>
<div class="in-nav-right">
<a class="in-nav-btn next primary" href="#in-slide-4">Next →</a>
</div>
</div>
<div class="in-slide-body">
<div class="in-chart"><h-block name="v_s3_area" /></div>
<div class="in-insight">
<div class="in-eyebrow">Customer Health</div>
<h2 class="in-headline">Retention hit a<br><span class="in-accent-green">new high.</span></h2>
<p class="in-lede">Gross retention reached 97.9% — the lowest churn in eighteen months. Expansion revenue from existing customers grew 31% YoY.</p>
<div class="in-stat">
<div class="in-stat-num in-accent-green">97.9%</div>
<div class="in-stat-label">gross revenue retention, ▲ +1.4pp vs Q1</div>
</div>
</div>
</div>
</section>

<!-- SLIDE 4 -->
<section class="in-slide" id="in-slide-4">
<div class="in-nav">
<div class="in-nav-left">
<a class="in-nav-btn prev" href="#in-slide-3">← Prev</a>
<span><span class="in-counter-num">04</span><span class="in-counter-sep"> / </span><span class="in-counter-total">05</span></span>
</div>
<div class="in-nav-right">
<a class="in-nav-btn next primary" href="#in-slide-5">Next →</a>
</div>
</div>
<div class="in-slide-body">
<div class="in-chart"><h-block name="v_s4_bar" /></div>
<div class="in-insight">
<div class="in-eyebrow">Sales Velocity</div>
<h2 class="in-headline">Cycle time<br><span class="in-accent-amber">collapsed.</span></h2>
<p class="in-lede">Average sales cycle dropped from 53 days to 42 days. The new onboarding playbook shaved meaningful time off every stage of the funnel.</p>
<div class="in-stat">
<div class="in-stat-num in-accent-amber">−11d</div>
<div class="in-stat-label">reduction in average sales cycle vs Q1</div>
</div>
</div>
</div>
</section>

<!-- SLIDE 5 -->
<section class="in-slide" id="in-slide-5">
<div class="in-nav">
<div class="in-nav-left">
<a class="in-nav-btn prev" href="#in-slide-4">← Prev</a>
<span><span class="in-counter-num">05</span><span class="in-counter-sep"> / </span><span class="in-counter-total">05</span></span>
</div>
<div class="in-nav-right">
<a class="in-nav-btn next" href="#in-slide-1">↺ Restart</a>
</div>
</div>
<div class="in-slide-body">
<div class="in-chart"><h-block name="v_s5_kpi" /></div>
<div class="in-insight">
<div class="in-eyebrow">Voice of Customer</div>
<h2 class="in-headline">NPS climbed to<br><span class="in-accent-purple">an all-time high.</span></h2>
<p class="in-lede">Net Promoter Score reached 64, up from 51 last quarter. Customer feedback highlighted faster onboarding and product reliability as the biggest drivers.</p>
<div class="in-stat">
<div class="in-stat-num in-accent-purple">64</div>
<div class="in-stat-label">NPS score, ▲ +13 vs Q1 — record high</div>
</div>
</div>
</div>
</section>

<!-- DOT INDICATORS -->
<nav class="in-dots">
<a class="in-dot-link" href="#in-slide-1" title="Slide 1"></a>
<a class="in-dot-link" href="#in-slide-2" title="Slide 2"></a>
<a class="in-dot-link" href="#in-slide-3" title="Slide 3"></a>
<a class="in-dot-link" href="#in-slide-4" title="Slide 4"></a>
<a class="in-dot-link" href="#in-slide-5" title="Slide 5"></a>
</nav>
</div>

;;
}

theme {
block {
background { bg_color: "transparent" }
border { border_width: 0 }
}
}
}

Tabbed dashboard

A four-tab dark analytics dashboard with CSS-only tab navigation using anchor links and :target. Each tab reveals a different panel (Overview, Performance, Breakdown, Activity) with KPI cards and live charts, all wired to the same shared blocks.

Show full code
Dashboard html_tabbed_report {
title: 'Tabbed Report'

block v_tab_trend: VizBlock { ... } // User signups by quarter (column chart)
block v_tab_donut: VizBlock { ... } // Orders by status (donut)
block v_tab_bar: VizBlock { ... } // Orders by status stacked (bar chart)
block v_tab_area: VizBlock { ... } // Returned vs Net Sales (area chart)
block v_tab_margin: VizBlock { ... } // Net Sales Margin trend (area chart)
block v_tab_acquisition: VizBlock { ... } // User acquisition by month (column chart)
block v_kpi_rev: VizBlock { ... } // Gross Sales (KPI)
block v_kpi_users: VizBlock { ... } // Total Users (KPI)
block v_kpi_margin: VizBlock { ... } // Net Sales Margin (KPI)
block v_kpi_return: VizBlock { ... } // Return Ratio (KPI)
block filter_date: FilterBlock { ... } // Order Date filter

view: HTMLLayout {
content: @html
<!-- ============================================================
DASH·HQ — Modern dark dashboard
Pure HTML/CSS, no JS, no @scope, no radios
Isolation: every selector prefixed with .dash-hq
Tabs: :target via anchor links (sanitizer-safe)
============================================================ -->

<div class="dash-hq">
<style>
/* ---------- Reset (scoped via prefix) ---------- */
.dash-hq,
.dash-hq *,
.dash-hq *::before,
.dash-hq *::after { box-sizing: border-box; }

/* ---------- Root container & tokens ---------- */
.dash-hq {
/* Surfaces */
--dh-bg: #0b0d12;
--dh-surface: #14171f;
--dh-surface-2: #1a1e28;
--dh-border: #262b38;
--dh-border-strong: #353b4d;

/* Text */
--dh-text: #e6e8ee;
--dh-text-dim: #8b91a3;
--dh-text-faint: #5a6075;

/* Accents */
--dh-blue: #60a5fa;
--dh-red: #fb7185;
--dh-green: #34d399;
--dh-purple: #c084fc;
--dh-amber: #fbbf24;

--dh-radius: 6px;
--dh-gap: 16px;

/* Typography */
--dh-font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
--dh-font-mono: ui-monospace, "JetBrains Mono", "Fira Code", "SF Mono", Menlo, Consolas, monospace;
--dh-font-display: "Impact", "Haettenschweiler", "Arial Narrow Bold", "Bebas Neue", sans-serif;

display: flex;
flex-direction: column;
font-family: var(--dh-font-sans);
color: var(--dh-text);
background: var(--dh-bg);
padding: 28px 32px;
border-radius: var(--dh-radius);
min-height: 600px;
position: relative;
overflow: hidden;
height: 100%;
}

/* Subtle radial glow in background */
.dash-hq::before {
content: "";
position: absolute;
top: -200px;
right: -200px;
width: 600px;
height: 600px;
background: radial-gradient(circle, rgba(77, 140, 255, 0.08), transparent 70%);
pointer-events: none;
z-index: 0;
}

/* Push real content above the glow */
.dash-hq > * { position: relative; z-index: 1; }

/* Visual order — panels precede tabs in DOM for the sibling selector trick */
.dash-hq .dh-topbar { order: 1; }
.dash-hq .dh-filters { order: 2; }
.dash-hq .dh-tabs { order: 3; }
.dash-hq .dh-header { order: 4; }
.dash-hq .dh-panel { order: 5; }

/* ---------- Top bar ---------- */
.dash-hq .dh-topbar {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 18px;
margin-bottom: 4px;
gap: 12px;
flex-wrap: wrap;
}
.dash-hq .dh-brand {
display: flex;
align-items: center;
gap: 18px;
}
.dash-hq .dh-logo {
font-family: var(--dh-font-display);
font-size: 22px;
letter-spacing: 0.05em;
color: var(--dh-text);
font-weight: 900;
}
.dash-hq .dh-logo span { color: var(--dh-red); }
.dash-hq .dh-workspace {
color: var(--dh-text-dim);
font-size: 13px;
font-family: var(--dh-font-mono);
padding-left: 18px;
border-left: 1px solid var(--dh-border);
}
.dash-hq .dh-workspace b {
color: var(--dh-text);
font-weight: 500;
margin-left: 6px;
}
.dash-hq .dh-status {
display: flex;
align-items: center;
gap: 14px;
font-family: var(--dh-font-mono);
font-size: 12px;
color: var(--dh-text-dim);
}
.dash-hq .dh-status b {
color: var(--dh-text);
font-weight: 500;
}
.dash-hq .dh-live {
background: var(--dh-red);
color: #fff;
padding: 4px 8px;
border-radius: 3px;
font-size: 11px;
letter-spacing: 0.1em;
font-weight: 700;
position: relative;
}
.dash-hq .dh-live::before {
content: "";
position: absolute;
inset: 0;
border-radius: 3px;
background: var(--dh-red);
animation: dh-pulse 2s ease-out infinite;
z-index: -1;
}
@keyframes dh-pulse {
0% { transform: scale(1); opacity: 0.7; }
100% { transform: scale(1.4); opacity: 0; }
}

/* ---------- Tabs ---------- */
.dash-hq .dh-tabs {
display: flex;
gap: 28px;
border-bottom: 1px solid var(--dh-border);
margin-bottom: 28px;
padding-bottom: 0;
}
.dash-hq .dh-tab {
position: relative;
padding: 14px 2px;
font-size: 14px;
font-weight: 500;
color: var(--dh-text-dim);
text-decoration: none;
margin-bottom: -1px;
border-bottom: 2px solid transparent;
transition: color 0.2s ease, border-color 0.2s ease;
display: flex;
align-items: center;
gap: 8px;
}
.dash-hq .dh-tab::before {
content: "";
width: 6px;
height: 6px;
border-radius: 50%;
background: transparent;
transition: background 0.2s ease, box-shadow 0.2s ease;
}
.dash-hq .dh-tab.dh-tab-live::before {
background: var(--dh-green);
box-shadow: 0 0 8px var(--dh-green);
}
.dash-hq .dh-tab:hover { color: var(--dh-text); }

/* ---------- Panel visibility ---------- */
.dash-hq .dh-panel {
display: none;
scroll-margin-top: 9999px;
animation: dh-fade-up 0.4s ease both;
}
.dash-hq .dh-panel:target { display: block; }

/* Active tab — when its target panel is shown */
.dash-hq #dh-panel-summary:target ~ .dh-tabs a[href="#dh-panel-summary"],
.dash-hq #dh-panel-performance:target ~ .dh-tabs a[href="#dh-panel-performance"],
.dash-hq #dh-panel-breakdown:target ~ .dh-tabs a[href="#dh-panel-breakdown"],
.dash-hq #dh-panel-activity:target ~ .dh-tabs a[href="#dh-panel-activity"] {
color: var(--dh-text);
border-bottom-color: var(--dh-red);
}

/* Default state — no hash means show Summary */
.dash-hq:not(:has(.dh-panel:target)) #dh-panel-summary { display: block; }
.dash-hq:not(:has(.dh-panel:target)) .dh-tabs a[href="#dh-panel-summary"] {
color: var(--dh-text);
border-bottom-color: var(--dh-red);
}

@keyframes dh-fade-up {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}

/* ---------- Header (per-panel page title) ---------- */
.dash-hq .dh-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 24px;
flex-wrap: wrap;
gap: 16px;
}
.dash-hq .dh-title {
font-family: var(--dh-font-display);
font-size: 42px;
letter-spacing: 0.04em;
margin: 0;
line-height: 1;
font-weight: 900;
}
.dash-hq .dh-subtitle {
font-family: var(--dh-font-mono);
font-size: 11px;
color: var(--dh-text-dim);
margin: 8px 0 0 0;
letter-spacing: 0.1em;
text-transform: uppercase;
}
.dash-hq .dh-date-pill {
background: var(--dh-surface);
border: 1px solid var(--dh-border);
padding: 8px 14px;
border-radius: 4px;
font-family: var(--dh-font-mono);
font-size: 13px;
color: var(--dh-text-dim);
}
.dash-hq .dh-date-pill b {
color: var(--dh-text);
font-weight: 500;
}

/* ---------- KPI cards ---------- */
.dash-hq .dh-kpis {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: var(--dh-gap);
margin-bottom: var(--dh-gap);
}
.dash-hq .dh-kpi {
background: var(--dh-surface);
border: 1px solid var(--dh-border);
border-radius: var(--dh-radius);
padding: 18px 20px;
position: relative;
overflow: hidden;
transition: transform 0.2s ease, border-color 0.2s ease;
animation: dh-fade-up 0.5s ease both;
}
.dash-hq .dh-kpi:hover {
transform: translateY(-2px);
border-color: var(--dh-border-strong);
}
.dash-hq .dh-kpi:nth-child(1) { animation-delay: 0.05s; }
.dash-hq .dh-kpi:nth-child(2) { animation-delay: 0.10s; }
.dash-hq .dh-kpi:nth-child(3) { animation-delay: 0.15s; }
.dash-hq .dh-kpi:nth-child(4) { animation-delay: 0.20s; }

/* Neon accent bar at top */
.dash-hq .dh-kpi::before {
content: "";
position: absolute;
top: 0; left: 0; right: 0;
height: 2px;
background: linear-gradient(90deg, transparent, currentColor, transparent);
color: var(--dh-blue);
opacity: 0.9;
}
.dash-hq .dh-kpi.accent-blue::before { color: var(--dh-blue); }
.dash-hq .dh-kpi.accent-red::before { color: var(--dh-red); }
.dash-hq .dh-kpi.accent-green::before { color: var(--dh-green); }
.dash-hq .dh-kpi.accent-purple::before { color: var(--dh-purple); }
.dash-hq .dh-kpi.accent-amber::before { color: var(--dh-amber); }

.dash-hq .dh-kpi-row {
display: flex;
justify-content: space-between;
align-items: flex-end;
gap: 12px;
}
.dash-hq .dh-kpi-main { min-width: 0; flex: 1; }
.dash-hq .dh-kpi-label {
font-family: var(--dh-font-mono);
font-size: 11px;
color: var(--dh-text-dim);
text-transform: uppercase;
letter-spacing: 0.12em;
margin-bottom: 12px;
}
.dash-hq .dh-kpi-value {
font-family: var(--dh-font-display);
font-size: 36px;
font-weight: 900;
line-height: 1;
letter-spacing: 0.01em;
color: var(--dh-text);
}
.dash-hq .dh-kpi-delta {
font-family: var(--dh-font-mono);
font-size: 12px;
margin-top: 14px;
}
.dash-hq .dh-kpi-delta.up { color: var(--dh-green); }
.dash-hq .dh-kpi-delta.down { color: var(--dh-red); }
.dash-hq .dh-kpi-delta span { color: var(--dh-text-faint); }

.dash-hq .dh-spark {
width: 70px;
height: 32px;
border: 1px solid var(--dh-border);
border-radius: 3px;
font-family: var(--dh-font-mono);
font-size: 9px;
color: var(--dh-text-faint);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}

/* ---------- Chart grid ---------- */
.dash-hq .dh-grid {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: var(--dh-gap);
}
.dash-hq .dh-card {
background: var(--dh-surface);
border: 1px solid var(--dh-border);
border-radius: var(--dh-radius);
padding: 20px;
display: flex;
flex-direction: column;
animation: dh-fade-up 0.5s ease both;
transition: border-color 0.2s ease;
}
.dash-hq .dh-card:hover { border-color: var(--dh-border-strong); }
.dash-hq .dh-card:nth-child(1) { animation-delay: 0.25s; }
.dash-hq .dh-card:nth-child(2) { animation-delay: 0.30s; }
.dash-hq .dh-card:nth-child(3) { animation-delay: 0.35s; }
.dash-hq .dh-card:nth-child(4) { animation-delay: 0.40s; }
.dash-hq .dh-card:nth-child(5) { animation-delay: 0.45s; }

.dash-hq .dh-card-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 18px;
}
.dash-hq .dh-card-eyebrow {
font-family: var(--dh-font-mono);
font-size: 10px;
color: var(--dh-text-faint);
text-transform: uppercase;
letter-spacing: 0.15em;
margin-bottom: 6px;
}
.dash-hq .dh-card-title {
font-family: var(--dh-font-display);
font-size: 18px;
font-weight: 900;
letter-spacing: 0.03em;
margin: 0;
color: var(--dh-text);
}
.dash-hq .dh-card-action {
color: var(--dh-blue);
font-size: 12px;
font-family: var(--dh-font-mono);
text-decoration: none;
transition: opacity 0.2s ease;
}
.dash-hq .dh-card-action:hover { opacity: 0.7; }

.dash-hq .dh-legend {
display: flex;
gap: 16px;
font-family: var(--dh-font-mono);
font-size: 11px;
color: var(--dh-text-dim);
margin-bottom: 12px;
}
.dash-hq .dh-legend-item {
display: inline-flex;
align-items: center;
gap: 6px;
}
.dash-hq .dh-legend-item::before {
content: "";
width: 12px;
height: 2px;
background: currentColor;
}
.dash-hq .dh-legend-item.dot-blue { color: var(--dh-blue); }
.dash-hq .dh-legend-item.dot-red { color: var(--dh-red); }
.dash-hq .dh-legend-item.dot-grey { color: var(--dh-text-faint); }
.dash-hq .dh-legend-item span { color: var(--dh-text-dim); }

.dash-hq .dh-col-12 { grid-column: span 12; }
.dash-hq .dh-col-8 { grid-column: span 8; }
.dash-hq .dh-col-7 { grid-column: span 7; }
.dash-hq .dh-col-6 { grid-column: span 6; }
.dash-hq .dh-col-5 { grid-column: span 5; }
.dash-hq .dh-col-4 { grid-column: span 4; }

@media (max-width: 900px) {
.dash-hq .dh-col-8, .dash-hq .dh-col-7, .dash-hq .dh-col-6,
.dash-hq .dh-col-5, .dash-hq .dh-col-4 { grid-column: span 12; }
}

/* ---------- Chart containers ---------- */
.dash-hq .dh-chart {
flex: 1;
min-height: 240px;
border: 1px dashed var(--dh-border-strong);
border-radius: 4px;
position: relative;
background-color: rgba(255, 255, 255, 0.01);
background-image:
linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
background-size: 40px 40px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
gap: 8px;
overflow: hidden;
}
.dash-hq .dh-chart.tall { min-height: 320px; }
.dash-hq .dh-chart.short { min-height: 160px; }

/* ---------- Segment bars ---------- */
.dash-hq .dh-segments {
display: flex;
flex-direction: column;
gap: 14px;
margin-top: 18px;
}
.dash-hq .dh-segment {
display: grid;
grid-template-columns: 1fr auto;
gap: 6px;
font-family: var(--dh-font-mono);
font-size: 13px;
}
.dash-hq .dh-segment-name { color: var(--dh-text); }
.dash-hq .dh-segment-pct { color: var(--dh-text); }
.dash-hq .dh-segment-bar {
grid-column: 1 / -1;
height: 4px;
border-radius: 2px;
background: var(--dh-border);
overflow: hidden;
position: relative;
}
.dash-hq .dh-segment-bar::after {
content: "";
position: absolute;
top: 0; left: 0; bottom: 0;
width: var(--w, 0%);
background: currentColor;
border-radius: 2px;
animation: dh-grow 1s cubic-bezier(0.16, 1, 0.3, 1) both;
animation-delay: 0.5s;
}
.dash-hq .dh-segment.color-blue { color: var(--dh-blue); }
.dash-hq .dh-segment.color-green { color: var(--dh-green); }
.dash-hq .dh-segment.color-purple { color: var(--dh-purple); }
.dash-hq .dh-segment.color-red { color: var(--dh-red); }
.dash-hq .dh-segment.color-amber { color: var(--dh-amber); }
@keyframes dh-grow {
from { width: 0; }
to { width: var(--w, 0%); }
}

/* ---------- Table ---------- */
.dash-hq .dh-table {
width: 100%;
border-collapse: collapse;
font-size: 13px;
font-family: var(--dh-font-mono);
}
.dash-hq .dh-table th,
.dash-hq .dh-table td {
text-align: left;
padding: 12px 14px;
border-bottom: 1px solid var(--dh-border);
}
.dash-hq .dh-table th {
font-weight: 500;
color: var(--dh-text-faint);
background: var(--dh-surface-2);
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.15em;
}
.dash-hq .dh-table tr:last-child td { border-bottom: none; }
.dash-hq .dh-table tbody tr { transition: background 0.15s ease; }
.dash-hq .dh-table tbody tr:hover { background: var(--dh-surface-2); }
.dash-hq .dh-table td { color: var(--dh-text); }
.dash-hq .dh-tag {
display: inline-block;
padding: 3px 8px;
border-radius: 3px;
font-size: 10px;
letter-spacing: 0.1em;
text-transform: uppercase;
font-weight: 500;
}
.dash-hq .dh-tag.ready { background: rgba(46, 204, 113, 0.15); color: var(--dh-green); }
.dash-hq .dh-tag.archived { background: rgba(139, 145, 163, 0.15); color: var(--dh-text-dim); }

/* ---------- Live chart overrides ---------- */
.dash-hq .dh-chart.dh-chart-live {
border: none;
background: transparent;
background-image: none;
align-items: stretch;
justify-content: stretch;
padding: 0;
}
.dash-hq .dh-chart.dh-chart-live::after { display: none; }
.dash-hq .dh-chart.dh-chart-live * {
background: transparent !important;
color: var(--dh-text) !important;
}

/* ---------- Filter bar ---------- */
.dash-hq .dac-ic-block-label { display: none; }
.dash-hq .dh-filters {
display: flex;
gap: 12px;
align-items: center;
padding-bottom: 18px;
margin-bottom: 4px;
flex-wrap: wrap;
}
.dash-hq .dac-ic-block { color: var(--dh-text) !important; }
.dash-hq .dm-filter-form {
background: var(--dh-surface) !important;
border: 1px solid var(--dh-border) !important;
border-radius: var(--dh-radius) !important;
box-shadow: none !important;
color: var(--dh-text) !important;
}
.dash-hq .h-highlightable-input,
.dash-hq .h-input {
background: var(--dh-surface-2) !important;
color: var(--dh-text) !important;
}
.dash-hq .dac-ic-block * {
font-family: var(--dh-font-mono) !important;
font-size: 12px !important;
}

/* ---------- KPI value inherits display font ---------- */
.dash-hq .dh-kpi-value .h-kpi-metric-kpi,
.dash-hq .dh-kpi-value .h-kpi-metric-kpi * {
font-family: var(--dh-font-display) !important;
font-size: 36px !important;
font-weight: 900 !important;
line-height: 1 !important;
letter-spacing: 0.01em !important;
color: var(--dh-text) !important;
background: transparent !important;
border: none !important;
padding: 0 !important;
margin: 0 !important;
}
</style>

<!-- =================== TOP BAR =================== -->
<div class="dh-topbar">
<div class="dh-brand">
<div class="dh-logo">DASH<span>·</span>HQ</div>
<div class="dh-workspace">Workspace:<b>Acme Corp</b></div>
</div>
<div class="dh-status">
<span>Last sync: <b>2 min ago</b></span>
<span class="dh-live">LIVE</span>
</div>
</div>

<!-- =================== PANELS (DOM first for sibling selector) =================== -->

<!-- ----- SUMMARY ----- -->
<section class="dh-panel" id="dh-panel-summary">
<div class="dh-header">
<div>
<h1 class="dh-title">OVERVIEW</h1>
<p class="dh-subtitle">FY 2025 · ALL SEGMENTS</p>
</div>
<div class="dh-date-pill" style="display: flex">
<span style="font-size: 16px; padding-top: 6px; padding-right: 12px">📅</span>
<h-block name="filter_date" />
</div>
</div>

<div class="dh-kpis">
<div class="dh-kpi accent-blue">
<div class="dh-kpi-label">Gross Sales</div>
<div class="dh-kpi-row">
<div class="dh-kpi-main">
<div class="dh-kpi-value"><h-block name="v_kpi_rev" /></div>
</div>
</div>
</div>
<div class="dh-kpi accent-red">
<div class="dh-kpi-label">Total Users</div>
<div class="dh-kpi-row">
<div class="dh-kpi-main">
<div class="dh-kpi-value"><h-block name="v_kpi_users" /></div>
</div>
</div>
</div>
<div class="dh-kpi accent-green">
<div class="dh-kpi-label">Net Sales Margin</div>
<div class="dh-kpi-row">
<div class="dh-kpi-main">
<div class="dh-kpi-value"><h-block name="v_kpi_margin" /></div>
</div>
</div>
</div>
<div class="dh-kpi accent-purple">
<div class="dh-kpi-label">Return Ratio</div>
<div class="dh-kpi-row">
<div class="dh-kpi-main">
<div class="dh-kpi-value"><h-block name="v_kpi_return" /></div>
</div>
</div>
</div>
</div>

<div class="dh-grid">
<div class="dh-card dh-col-7">
<div class="dh-card-header">
<div>
<div class="dh-card-eyebrow">Revenue Performance</div>
<h3 class="dh-card-title">MONTHLY TREND</h3>
</div>
<a class="dh-card-action" href="#">Export ↗</a>
</div>
<div class="dh-legend">
<span class="dh-legend-item dot-blue"><span>Revenue</span></span>
<span class="dh-legend-item dot-red"><span>Target</span></span>
<span class="dh-legend-item dot-grey"><span>Prior Year</span></span>
</div>
<div class="dh-chart tall dh-chart-live"><h-block name="v_tab_trend" /></div>
</div>
<div class="dh-card dh-col-5">
<div class="dh-card-header">
<div>
<div class="dh-card-eyebrow">Mix</div>
<h3 class="dh-card-title">REVENUE BY SEGMENT</h3>
</div>
<a class="dh-card-action" href="#">Details →</a>
</div>
<div class="dh-chart dh-chart-live"><h-block name="v_tab_donut" /></div>
<div class="dh-segments">
<div class="dh-segment color-blue">
<span class="dh-segment-name">Enterprise</span>
<span class="dh-segment-pct">43.8%</span>
<div class="dh-segment-bar" style="--w: 43.8%;"></div>
</div>
<div class="dh-segment color-green">
<span class="dh-segment-name">Mid-Market</span>
<span class="dh-segment-pct">31.2%</span>
<div class="dh-segment-bar" style="--w: 31.2%;"></div>
</div>
<div class="dh-segment color-purple">
<span class="dh-segment-name">SMB</span>
<span class="dh-segment-pct">25.0%</span>
<div class="dh-segment-bar" style="--w: 25.0%;"></div>
</div>
</div>
</div>
<div class="dh-card dh-col-4">
<div class="dh-card-header">
<div>
<div class="dh-card-eyebrow">Funnel</div>
<h3 class="dh-card-title">PIPELINE</h3>
</div>
</div>
<div class="dh-chart short dh-chart-live"><h-block name="v_tab_bar" /></div>
</div>
<div class="dh-card dh-col-4">
<div class="dh-card-header">
<div>
<div class="dh-card-eyebrow">Churn</div>
<h3 class="dh-card-title">RETENTION CURVE</h3>
</div>
</div>
<div class="dh-chart short dh-chart-live"><h-block name="v_tab_area" /></div>
</div>
<div class="dh-card dh-col-4">
<div class="dh-card-header">
<div>
<div class="dh-card-eyebrow">Sentiment</div>
<h3 class="dh-card-title">NPS TREND</h3>
</div>
</div>
<div class="dh-chart short dh-chart-live"><h-block name="v_tab_margin" /></div>
</div>
</div>
</section>

<!-- ----- PERFORMANCE ----- -->
<section class="dh-panel" id="dh-panel-performance">
<div class="dh-header">
<div>
<h1 class="dh-title">PERFORMANCE</h1>
<p class="dh-subtitle">REVENUE · LIVE METRICS</p>
</div>
<div class="dh-date-pill">📅 <b>Q1 — Q2 2026</b></div>
</div>

<div class="dh-kpis">
<div class="dh-kpi accent-blue">
<div class="dh-kpi-label">MRR</div>
<div class="dh-kpi-row">
<div class="dh-kpi-main">
<div class="dh-kpi-value">$82.1K</div>
<div class="dh-kpi-delta up">▲ +8.2% <span>MoM</span></div>
</div>
<div class="dh-spark">sparkline</div>
</div>
</div>
<div class="dh-kpi accent-green">
<div class="dh-kpi-label">ARR</div>
<div class="dh-kpi-row">
<div class="dh-kpi-main">
<div class="dh-kpi-value">$985K</div>
<div class="dh-kpi-delta up">▲ +11.7% <span>YoY</span></div>
</div>
<div class="dh-spark">sparkline</div>
</div>
</div>
<div class="dh-kpi accent-amber">
<div class="dh-kpi-label">Churn Rate</div>
<div class="dh-kpi-row">
<div class="dh-kpi-main">
<div class="dh-kpi-value">2.1%</div>
<div class="dh-kpi-delta down">▼ −0.3pp <span>vs prior</span></div>
</div>
<div class="dh-spark">sparkline</div>
</div>
</div>
</div>

<div class="dh-grid">
<div class="dh-card dh-col-12">
<div class="dh-card-header">
<div>
<div class="dh-card-eyebrow">Stacked View</div>
<h3 class="dh-card-title">REVENUE BY CHANNEL</h3>
</div>
<a class="dh-card-action" href="#">Export ↗</a>
</div>
<div class="dh-chart tall dh-chart-live"><h-block name="v_tab_trend" /></div>
</div>
<div class="dh-card dh-col-6">
<div class="dh-card-header">
<div>
<div class="dh-card-eyebrow">Distribution</div>
<h3 class="dh-card-title">PLAN BREAKDOWN</h3>
</div>
</div>
<div class="dh-chart dh-chart-live"><h-block name="v_tab_donut" /></div>
</div>
<div class="dh-card dh-col-6">
<div class="dh-card-header">
<div>
<div class="dh-card-eyebrow">Cohort</div>
<h3 class="dh-card-title">RETENTION HEATMAP</h3>
</div>
</div>
<div class="dh-chart dh-chart-live"><h-block name="v_tab_area" /></div>
</div>
</div>
</section>

<!-- ----- BREAKDOWN ----- -->
<section class="dh-panel" id="dh-panel-breakdown">
<div class="dh-header">
<div>
<h1 class="dh-title">BREAKDOWN</h1>
<p class="dh-subtitle">USER COHORTS · ACTIVITY</p>
</div>
<div class="dh-date-pill">📅 <b>Last 30 days</b></div>
</div>

<div class="dh-kpis">
<div class="dh-kpi accent-blue">
<div class="dh-kpi-label">DAU</div>
<div class="dh-kpi-row">
<div class="dh-kpi-main">
<div class="dh-kpi-value">5,210</div>
<div class="dh-kpi-delta up">▲ +6.4% <span>vs last week</span></div>
</div>
<div class="dh-spark">sparkline</div>
</div>
</div>
<div class="dh-kpi accent-purple">
<div class="dh-kpi-label">WAU</div>
<div class="dh-kpi-row">
<div class="dh-kpi-main">
<div class="dh-kpi-value">14,830</div>
<div class="dh-kpi-delta up">▲ +3.9% <span>vs last week</span></div>
</div>
<div class="dh-spark">sparkline</div>
</div>
</div>
<div class="dh-kpi accent-green">
<div class="dh-kpi-label">MAU</div>
<div class="dh-kpi-row">
<div class="dh-kpi-main">
<div class="dh-kpi-value">42,016</div>
<div class="dh-kpi-delta up">▲ +5.1% <span>vs last month</span></div>
</div>
<div class="dh-spark">sparkline</div>
</div>
</div>
<div class="dh-kpi accent-amber">
<div class="dh-kpi-label">Avg. Session</div>
<div class="dh-kpi-row">
<div class="dh-kpi-main">
<div class="dh-kpi-value">4m 12s</div>
<div class="dh-kpi-delta down">▼ −14s <span>vs last week</span></div>
</div>
<div class="dh-spark">sparkline</div>
</div>
</div>
</div>

<div class="dh-grid">
<div class="dh-card dh-col-8">
<div class="dh-card-header">
<div>
<div class="dh-card-eyebrow">Growth</div>
<h3 class="dh-card-title">USER ACQUISITION</h3>
</div>
<a class="dh-card-action" href="#">Filter ↗</a>
</div>
<div class="dh-chart tall dh-chart-live"><h-block name="v_tab_acquisition" /></div>
</div>
<div class="dh-card dh-col-4">
<div class="dh-card-header">
<div>
<div class="dh-card-eyebrow">Mix</div>
<h3 class="dh-card-title">DEVICE SPLIT</h3>
</div>
</div>
<div class="dh-chart tall dh-chart-live"><h-block name="v_tab_donut" /></div>
</div>
</div>
</section>

<!-- ----- ACTIVITY ----- -->
<section class="dh-panel" id="dh-panel-activity">
<div class="dh-header">
<div>
<h1 class="dh-title">ACTIVITY</h1>
<p class="dh-subtitle">REPORTS · AUDIT LOG</p>
</div>
<div class="dh-date-pill">📅 <b>Last 7 days</b></div>
</div>

<div class="dh-grid">
<div class="dh-card dh-col-12">
<div class="dh-card-header">
<div>
<div class="dh-card-eyebrow">Generated</div>
<h3 class="dh-card-title">RECENT REPORTS</h3>
</div>
<a class="dh-card-action" href="#">New report ↗</a>
</div>
<table class="dh-table">
<thead>
<tr>
<th>Report</th>
<th>Type</th>
<th>Generated</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr><td>Q4 Revenue Summary</td><td>Financial</td><td>2 hours ago</td><td><span class="dh-tag ready">Ready</span></td></tr>
<tr><td>User Acquisition Report</td><td>Marketing</td><td>1 day ago</td><td><span class="dh-tag ready">Ready</span></td></tr>
<tr><td>Churn Analysis</td><td>Retention</td><td>3 days ago</td><td><span class="dh-tag ready">Ready</span></td></tr>
<tr><td>Product Performance</td><td>Operational</td><td>1 week ago</td><td><span class="dh-tag archived">Archived</span></td></tr>
</tbody>
</table>
</div>
<div class="dh-card dh-col-12">
<div class="dh-card-header">
<div>
<div class="dh-card-eyebrow">Volume</div>
<h3 class="dh-card-title">REPORT TIMELINE</h3>
</div>
</div>
<div class="dh-chart short dh-chart-live"><h-block name="v_tab_bar" /></div>
</div>
</div>
</section>

<!-- =================== TABS (DOM last for sibling selector) =================== -->
<nav class="dh-tabs">
<a class="dh-tab" href="#dh-panel-summary">Summary</a>
<a class="dh-tab dh-tab-live" href="#dh-panel-performance">Performance</a>
<a class="dh-tab" href="#dh-panel-breakdown">Breakdown</a>
<a class="dh-tab" href="#dh-panel-activity">Activity</a>
</nav>
</div>

;;
}

theme {
block {
background { bg_color: "transparent" }
border { border_width: 0 }
}
}
}

Limitations

No JavaScript support: JavaScript is not supported inside HTML Layout. As an alternative, you can use CSS to cover most interactive patterns - the examples above use :target for tabs and slides, @media for responsive layouts, and CSS animations for entrance effects.

Syntax reference

For the full syntax reference:


Open Markdown
Let us know what you think about this document :)