John Doe
Founder & design system
Owns downstage.css, tokens, and docs. Calm interfaces, clean code.
08 — Apps
Layout shells for sign in, sign up, password recovery, and a two-factor code step. Wire forms to your backend; markup and classes are presentation-only.
Use your work email and password.
<div class="auth-shell">
<div class="auth-card auth-card-wide">
<div class="auth-brand">
<svg class="icon icon-lg" aria-hidden="true"><use href="downstage-icons.svg#hash" /></svg>
Brand
</div>
<h3 class="auth-title">Sign in</h3>
<p class="auth-subtitle">Use your work email and password.</p>
<form class="auth-form" action="#" method="post">
<div class="field">
<label class="label">Email</label>
<input class="input" type="email" name="email" autocomplete="username" required>
</div>
<div class="field">
<label class="label">Password</label>
<input class="input" type="password" name="password" autocomplete="current-password" required>
</div>
<div class="auth-links-row">
<label class="check">
<input type="checkbox" name="remember">
<span>Remember me</span>
</label>
<a href="#">Forgot password?</a>
</div>
<div class="auth-actions">
<button type="submit" class="btn btn-primary btn-block">Sign in</button>
</div>
</form>
<div class="auth-footer">
No account? <a href="#">Create one</a>
</div>
</div>
</div>
Sign up with your email. We will send a verification link.
<div class="auth-shell">
<div class="auth-card auth-card-wide">
<h3 class="auth-title">Create account</h3>
<p class="auth-subtitle">Sign up with your email.</p>
<form class="auth-form" action="#" method="post">
<div class="field">
<label class="label">Full name</label>
<input class="input" type="text" name="name" autocomplete="name" required>
</div>
<div class="field">
<label class="label">Email</label>
<input class="input" type="email" name="email" autocomplete="email" required>
</div>
<div class="field">
<label class="label">Password</label>
<input class="input" type="password" name="password" autocomplete="new-password" required minlength="8">
<span class="help">At least 8 characters.</span>
</div>
<label class="check">
<input type="checkbox" name="terms" required>
<span>I agree to the terms and privacy policy</span>
</label>
<div class="auth-actions">
<button type="submit" class="btn btn-primary btn-block">Sign up</button>
</div>
</form>
<div class="auth-footer">
Already have an account? <a href="#">Sign in</a>
</div>
</div>
</div>
Enter your email and we will send reset instructions.
<div class="auth-shell">
<div class="auth-card">
<h3 class="auth-title">Reset password</h3>
<p class="auth-subtitle">Enter your email and we will send reset instructions.</p>
<form class="auth-form" action="#" method="post">
<div class="field">
<label class="label">Email</label>
<input class="input" type="email" name="email" autocomplete="email" required>
</div>
<div class="auth-actions">
<button type="submit" class="btn btn-primary btn-block">Send reset link</button>
<a href="#" class="btn btn-ghost btn-block">Back to sign in</a>
</div>
</form>
</div>
</div>
Enter the 6-digit code from your authenticator app.
<div class="auth-shell">
<div class="auth-card">
<h3 class="auth-title">Two-factor authentication</h3>
<p class="auth-subtitle">Enter the 6-digit code from your authenticator app.</p>
<form class="auth-form" action="#" method="post">
<div class="auth-otp" role="group" aria-label="One-time code">
<input class="input" type="text" inputmode="numeric" maxlength="1" aria-label="Digit 1">
<input class="input" type="text" inputmode="numeric" maxlength="1" aria-label="Digit 2">
<input class="input" type="text" inputmode="numeric" maxlength="1" aria-label="Digit 3">
<input class="input" type="text" inputmode="numeric" maxlength="1" aria-label="Digit 4">
<input class="input" type="text" inputmode="numeric" maxlength="1" aria-label="Digit 5">
<input class="input" type="text" inputmode="numeric" maxlength="1" aria-label="Digit 6">
</div>
<p class="help text-center">Alternatively, use a backup code below.</p>
<div class="field">
<label class="label">Backup code</label>
<input class="input" type="text" name="backup" placeholder="XXXX-XXXX">
</div>
<div class="auth-actions">
<button type="submit" class="btn btn-primary btn-block">Verify</button>
</div>
</form>
</div>
</div>
20 — Data
Stat cards and minimal SVG charts for data-driven UIs.
<!-- Stat cards -->
<div class="dashboard-grid">
<div class="stat-card">
<div class="stat-label">Revenue</div>
<div class="stat-value">$48.2k</div>
<div class="stat-change is-up">
<svg class="icon icon-sm"><use href="downstage-icons.svg#trending-up" /></svg>
+12.5%
</div>
</div>
<!-- repeat .stat-card for each metric -->
</div>
<!-- Charts row: line + donut -->
<div class="grid mt-6">
<div class="col-8">
<div class="chart-card">
<div class="chart-header">
<div>
<div class="chart-title">Traffic overview</div>
<div class="chart-subtitle">Last 12 months</div>
</div>
</div>
<div class="chart-canvas">
<svg class="chart-line-svg" viewBox="0 0 400 160" preserveAspectRatio="none">
<path class="chart-line-area" d="M0,120 L100,80 L200,70 L300,30 L400,35 L400,160 L0,160Z" />
<path class="chart-line-path" d="M0,120 L100,80 L200,70 L300,30 L400,35" />
</svg>
</div>
<div class="chart-legend">
<span class="chart-legend-item"><span class="chart-legend-dot"></span> Visitors</span>
</div>
</div>
</div>
<div class="col-4">
<div class="chart-card">
<div class="chart-header">
<div>
<div class="chart-title">Sources</div>
<div class="chart-subtitle">This month</div>
</div>
</div>
<div class="chart-canvas">
<svg class="chart-donut-svg" viewBox="0 0 120 120">
<circle class="chart-donut-ring" cx="60" cy="60" r="48" stroke="var(--text)" stroke-dasharray="180 302" />
<circle class="chart-donut-ring" cx="60" cy="60" r="48" stroke="var(--brand-primary)" stroke-dasharray="90 302" />
<text class="chart-donut-center" x="60" y="57">73%</text>
<text class="chart-donut-label" x="60" y="74">organic</text>
</svg>
</div>
</div>
</div>
</div>
<!-- Bar chart -->
<div class="chart-card mt-6">
<div class="chart-header">
<div>
<div class="chart-title">Monthly performance</div>
<div class="chart-subtitle">Revenue per month (K)</div>
</div>
</div>
<div class="chart-canvas">
<div class="chart-bar-group">
<div class="chart-bar" style="height:40%"></div>
<div class="chart-bar" style="height:65%"></div>
<div class="chart-bar is-accent" style="height:90%"></div>
<!-- repeat for each month -->
</div>
</div>
</div>
21 — Components
Project cards in a responsive grid. Use .portfolio-item as a block or wrap
the
whole card in <a>. Optional .portfolio-item--featured spans two columns on
wide
viewports.
Design system and UI kit for internal tools. Tokens, components, and documentation in one place.
Marketing site with editorial layouts and a restrained palette.
This very design system — minimal Nordic components, zero dependencies.
<div class="portfolio">
<!-- Featured item spans two columns -->
<a href="#" class="portfolio-item portfolio-item--featured">
<div class="portfolio-media">
<img src="project-hero.jpg" alt="Project preview">
</div>
<div class="portfolio-body">
<span class="portfolio-meta">Product · 2025</span>
<h3 class="portfolio-title">Project name</h3>
<p class="portfolio-desc">Short description of the project.</p>
<div class="portfolio-tags">
<span class="badge">UI</span>
<span class="badge badge-info">React</span>
</div>
</div>
<div class="portfolio-footer">
<span class="text-subtle text-sm">Case study</span>
<span class="portfolio-link">
View
<svg class="icon" aria-hidden="true"><use href="downstage-icons.svg#arrow-right" /></svg>
</span>
</div>
</a>
<!-- Standard item -->
<a href="#" class="portfolio-item">
<div class="portfolio-media">
<img src="project-thumb.jpg" alt="Project preview">
</div>
<div class="portfolio-body">
<span class="portfolio-meta">Web · 2024</span>
<h3 class="portfolio-title">Another project</h3>
<p class="portfolio-desc">Brief project summary.</p>
</div>
<div class="portfolio-footer">
<span class="text-subtle text-sm">Category</span>
<span class="portfolio-link">
View
<svg class="icon" aria-hidden="true"><use href="downstage-icons.svg#arrow-right" /></svg>
</span>
</div>
</a>
</div>
Compact variant on --bg: horizontal rules
only,
no card chrome — same idea as .table-minimal and .input-minimal. Use .portfolio.portfolio--minimal
and
.portfolio-item--minimal.
Tile server with a palette aligned to the design system.
Approval flows and real-time notifications.
<div class="portfolio portfolio--minimal">
<a href="#" class="portfolio-item portfolio-item--minimal">
<div class="portfolio-media">
<img src="project-thumb.jpg" alt="Project preview">
</div>
<div class="portfolio-body">
<span class="portfolio-meta">Category · 2025</span>
<h3 class="portfolio-title">Project name</h3>
<p class="portfolio-desc">Short description.</p>
<div class="portfolio-tags">
<span class="badge">Tag</span>
</div>
</div>
<div class="portfolio-footer">
<span class="text-subtle text-sm">Type</span>
<span class="portfolio-link">
View
<svg class="icon" aria-hidden="true"><use href="downstage-icons.svg#arrow-right" /></svg>
</span>
</div>
</a>
</div>
22 — Components
Article teasers with .blog-card inside .blog-list--grid or a
vertical
.blog-list. Meta line supports date, category, and reading time.
How we structure CSS variables so light, dark, and brand swaps stay predictable.
No build step, no npm — just HTML, CSS, and a thin layer of JS where it helps.
Portfolio grid, blog cards, and tighter focus styles across components.
<div class="blog-list blog-list--grid">
<a href="#" class="blog-card">
<div class="blog-card-media">
<img src="post-cover.jpg" alt="Post cover">
</div>
<div class="blog-card-body">
<div class="blog-card-meta">
<time datetime="2026-03-12">12 Mar 2026</time>
<span class="badge badge-info">Tutorial</span>
<span>6 min read</span>
</div>
<h3 class="blog-card-title">Article title</h3>
<p class="blog-card-excerpt">Short excerpt or summary.</p>
<div class="blog-card-footer">
<span class="text-subtle text-sm">Author</span>
<span class="blog-read-more">
Read
<svg class="icon" aria-hidden="true"><use href="downstage-icons.svg#arrow-right" /></svg>
</span>
</div>
</div>
</a>
<!-- repeat .blog-card -->
</div>
Same card pattern in a vertical .blog-list for archive pages.
Labels, errors, and focus order — a short list we use before shipping.
Progressive enhancement and fewer moving parts in production.
<div class="blog-list blog-list--narrow">
<a href="#" class="blog-card blog-card--compact">
<div class="blog-card-body">
<div class="blog-card-meta">
<time datetime="2025-11-02">2 Nov 2025</time>
<span class="badge badge-warning">Draft</span>
</div>
<h3 class="blog-card-title">Article title</h3>
<p class="blog-card-excerpt">Short excerpt.</p>
<div class="blog-card-footer">
<span class="text-subtle text-sm">Category</span>
<span class="blog-read-more">
Read
<svg class="icon" aria-hidden="true"><use href="downstage-icons.svg#arrow-right" /></svg>
</span>
</div>
</div>
</a>
<!-- repeat .blog-card.blog-card--compact -->
</div>
List with .blog-list--minimal and .blog-card--minimal: thumbnail on the left (on wide viewports), no heavy shadow
or
full border.
When removing the outer chrome improves scan and density.
Align vertical rhythm between teasers and pagination.
<div class="blog-list blog-list--grid blog-list--minimal">
<a href="#" class="blog-card blog-card--minimal">
<div class="blog-card-media">
<img src="thumb.jpg" alt="Post thumbnail">
</div>
<div class="blog-card-body">
<div class="blog-card-meta">
<time datetime="2026-04-01">1 Apr 2026</time>
<span class="badge">Notes</span>
<span>4 min</span>
</div>
<h3 class="blog-card-title">Article title</h3>
<p class="blog-card-excerpt">Short excerpt.</p>
<div class="blog-card-footer">
<span class="text-subtle text-sm">Category</span>
<span class="blog-read-more">
Read
<svg class="icon" aria-hidden="true"><use href="downstage-icons.svg#arrow-right" /></svg>
</span>
</div>
</div>
</a>
<!-- repeat .blog-card.blog-card--minimal -->
</div>
23 — Components
Stack of outbound links — useful for a "link in bio" page or a compact resources list.
Use
.link-list + a.link-item
<div class="link-list">
<a href="#" class="link-item">
<span class="link-item-icon" aria-hidden="true">
<svg class="icon"><use href="downstage-icons.svg#github" /></svg>
</span>
<span class="link-item-body">
<span class="link-item-title">GitHub</span>
<span class="link-item-desc">Source and issues</span>
</span>
<span class="link-item-arrow" aria-hidden="true">
<svg class="icon"><use href="downstage-icons.svg#external-link" /></svg>
</span>
</a>
<!-- repeat .link-item -->
</div>
24 — Components
Profile block with photo, role line, bio, and social icons. Markup uses
.about,
.about-media, and .about-content.
Designer & developer · Bergamo, Italy
I build calm interfaces and design systems that stay out of the way. downstage.css is a small, token-driven toolkit for sites and apps that value clarity over noise — Nordic-inspired restraint, no build step required.
When I'm not shipping UI, I'm probably refining typography, hiking, or chasing good espresso.
<div class="about">
<div class="about-media">
<img src="portrait.jpg" alt="Portrait">
</div>
<div class="about-content">
<header>
<h3 class="about-name">John Doe</h3>
<p class="about-role">Designer & developer</p>
</header>
<p class="about-bio">Bio paragraph.</p>
<div class="about-social" aria-label="Social profiles">
<a href="#" aria-label="Website">
<svg class="icon"><use href="downstage-icons.svg#globe" /></svg>
</a>
<a href="#" aria-label="GitHub">
<svg class="icon"><use href="downstage-icons.svg#github" /></svg>
</a>
<a href="#" aria-label="Email">
<svg class="icon"><use href="downstage-icons.svg#mail" /></svg>
</a>
</div>
</div>
</div>
25 — Components
People grid with photo, role, and short bio. Classes: .team-grid,
.team-card, .team-avatar, .team-name, .team-role,
.team-bio, optional .team-links.
Founder & design system
Owns downstage.css, tokens, and docs. Calm interfaces, clean code.
Product design
Wireframes, prototypes, and accessibility. Keeps components and real pages aligned.
<div class="team-grid">
<article class="team-card">
<div class="team-avatar">
<img src="avatar.jpg" alt="Portrait">
</div>
<h3 class="team-name">John Doe</h3>
<p class="team-role">Role title</p>
<p class="team-bio">Short bio text.</p>
<div class="team-links" aria-label="Profile links">
<a href="#" aria-label="Website">
<svg class="icon"><use href="downstage-icons.svg#globe" /></svg>
</a>
<a href="#" aria-label="GitHub">
<svg class="icon"><use href="downstage-icons.svg#github" /></svg>
</a>
</div>
</article>
<!-- repeat .team-card -->
</div>
27 — Components
Mini e-commerce patterns: product grid, product page, cart rows, and payment step. Markup and CSS only — wire logic to your backend or payment provider.
<div class="shop-grid">
<article class="shop-card">
<a href="#" class="shop-card-hit" aria-label="Product — view">
<div class="shop-card-media">
<span class="shop-card-badge"><span class="badge badge-success">New</span></span>
<img src="product.jpg" alt="Product photo">
</div>
<div class="shop-card-body">
<p class="shop-card-meta">Category</p>
<h3 class="shop-card-title">Product name</h3>
<p><span class="shop-price">€24,00</span></p>
</div>
</a>
<div class="shop-card-footer">
<span class="text-subtle text-sm">Variant</span>
<button type="button" class="btn btn-sm btn-primary">Add</button>
</div>
</article>
<!-- repeat .shop-card -->
</div>
Compact grid with .shop-grid--minimal and
.shop-card--minimal: horizontal rows like a light table.
<div class="shop-grid shop-grid--minimal">
<article class="shop-card shop-card--minimal">
<a href="#" class="shop-card-hit" aria-label="Product — view">
<div class="shop-card-media">
<img src="product-thumb.jpg" alt="Product photo">
</div>
<div class="shop-card-body">
<p class="shop-card-meta">Category</p>
<h3 class="shop-card-title">Product name</h3>
<p><span class="shop-price">€32,00</span></p>
</div>
</a>
<div class="shop-card-footer">
<span class="text-subtle text-sm">Variant</span>
<button type="button" class="btn btn-sm btn-primary">Add</button>
</div>
</article>
<!-- repeat .shop-card.shop-card--minimal -->
</div>
Tableware · SKU DS-MUG-01
Glazed stoneware, comfortable grip, matte finish that resists fingerprints.
Free returns within 30 days. VAT included for EU.
<div class="product-detail">
<div class="product-gallery">
<img src="product-large.jpg" alt="Product detail">
</div>
<div class="product-info">
<p class="text-subtle text-sm">Category · SKU</p>
<h3 class="product-title">Product name</h3>
<p class="product-lead">Product description.</p>
<div class="product-price-row">
<span class="shop-price">€24,00</span>
<span class="text-subtle text-sm">In stock</span>
</div>
<div class="product-actions">
<label class="text-sm text-muted">Qty</label>
<input class="input shop-qty-input" type="number" value="1" min="1" max="99">
<button type="button" class="btn btn-primary">
<svg class="icon"><use href="downstage-icons.svg#shopping-cart" /></svg>
Add to cart
</button>
</div>
<p class="help">Free returns within 30 days.</p>
</div>
</div>
Mug Sand
Throw Fog
Order summary
<div class="grid">
<div class="col-8">
<div class="cart" role="group" aria-label="Shopping cart">
<div class="cart-row">
<div class="cart-thumb">
<img src="product-thumb.jpg" alt="Product">
</div>
<div class="cart-line-main">
<p class="cart-line-title">Product name</p>
<p class="cart-line-meta">Category · €24,00 each</p>
</div>
<div class="cart-line-end">
<div class="cart-line-qty">
<label class="sr-only">Quantity</label>
<input class="input shop-qty-input" type="number" value="2" min="1" max="99">
</div>
<div class="cart-line-price">€48,00</div>
</div>
</div>
<!-- repeat .cart-row -->
</div>
</div>
<div class="col-4">
<div class="cart-summary">
<p class="cart-summary-title">Order summary</p>
<div class="cart-summary-row">
<span>Subtotal</span><span>€137,00</span>
</div>
<div class="cart-summary-row">
<span>Shipping</span><span>€6,00</span>
</div>
<div class="cart-summary-row cart-summary-row--total">
<span>Total</span><span>€143,00</span>
</div>
<button type="button" class="btn btn-primary btn-block mt-4">Checkout</button>
</div>
</div>
</div>
<div class="checkout-layout">
<div class="payment-panel">
<h3 class="payment-panel-title">Payment</h3>
<form class="stack" action="#" method="post">
<div class="field">
<label class="label">Name on card</label>
<input class="input" type="text" autocomplete="cc-name">
</div>
<div class="field">
<label class="label">Card number</label>
<input class="input" type="text" inputmode="numeric" autocomplete="cc-number">
</div>
<div class="payment-card-row">
<div class="field">
<label class="label">Expiry</label>
<input class="input" type="text" autocomplete="cc-exp" placeholder="MM / YY">
</div>
<div class="field">
<label class="label">CVC</label>
<input class="input" type="text" autocomplete="cc-csc" placeholder="123">
</div>
</div>
<button type="submit" class="btn btn-primary btn-block">Pay</button>
</form>
</div>
<aside class="order-recap" aria-label="Order recap">
<p class="order-recap-title">Your order</p>
<div class="order-recap-item">
<span>Item × 2</span><span>€48,00</span>
</div>
<div class="order-recap-total">
<span>Total</span><span>€143,00</span>
</div>
</aside>
</div>
28 — Components
Account-area pattern: user fields, password, and security actions. Demo markup only — connect to real endpoints or your auth provider.
Email and display name. Use .input-minimal
for
consistency with the rest of the page.
Update your current password. In production, verify the current password on the server.
Revoke sessions on other devices after a password change or a suspicious sign-in.
<div class="profile-shell">
<div class="profile-block">
<h3 class="profile-block-title">Account</h3>
<p class="profile-block-lead">Email and display name.</p>
<form class="stack" action="#" method="post">
<div class="field">
<label class="label">Email</label>
<input class="input input-minimal" type="email" autocomplete="email">
</div>
<div class="field">
<label class="label">Display name</label>
<input class="input input-minimal" type="text" autocomplete="name">
</div>
<div class="cluster mt-2" style="justify-content: flex-end;">
<button type="button" class="btn btn-ghost">Discard</button>
<button type="submit" class="btn btn-primary">Save changes</button>
</div>
</form>
</div>
<div class="profile-block">
<h3 class="profile-block-title">Password</h3>
<p class="profile-block-lead">Update your current password.</p>
<form class="stack" action="#" method="post">
<div class="field">
<label class="label">Current password</label>
<input class="input input-minimal" type="password" autocomplete="current-password">
</div>
<div class="field">
<label class="label">New password</label>
<input class="input input-minimal" type="password" autocomplete="new-password">
</div>
<div class="field">
<label class="label">Confirm new password</label>
<input class="input input-minimal" type="password" autocomplete="new-password">
</div>
<div class="cluster mt-2" style="justify-content: flex-end;">
<button type="button" class="btn btn-secondary">Cancel</button>
<button type="submit" class="btn btn-primary">Update password</button>
</div>
</form>
</div>
<div class="profile-block">
<h3 class="profile-block-title">Sessions</h3>
<p class="profile-block-lead">Revoke sessions on other devices.</p>
<button type="button" class="btn btn-secondary btn-sm">Sign out everywhere</button>
</div>
</div>