Design Lounge
Install

Nº 268 of 520

Hero with a live browser card

A SaaS hero: marker-highlighted headline, hard-shadow buttons, and a browser mockup whose schedule card ticks up, adds a post and pops a toast every 4.2s.

Preview

Open full size
1280 × 800 · 15.6 KB · 212 lines

Use it

Free to use · credit appreciated

1 Once, in your project

npx skills add SusanAcharya/Design-Lounge

2 Then ask

Using the Design Lounge skill, build "Hero with a live browser card" (piece hero-live-browser-card) in my stack. Match its brief; restyle it onto my product's theme.

No skill? Paste the brief instead. It carries the numbers, tokens and behaviour.

Brief

207 lines

Build brief for a coding agent. Rebuild this piece in the reader’s stack. If they haven’t said which stack, ask once, then default to semantic HTML + CSS + a little vanilla JS. Match the numbers below; don’t “improve” them. When a kit is locked, map colours onto the kit tokens and keep the hard 0-blur shadows.

What it is

Studied from usearticle.com: the first screen, where the product is shown working inside a drawn browser window instead of as a static screenshot. This version is Ovenlight, a fictional service that publishes a recipe blog on a schedule. Left: a green live badge, a 64px headline with “cooking itself.” in cobalt on a yellow marker stripe, a lede, two big hard-shadow buttons and three feature chips. Right: a browser frame with an 8px ink shadow, a tilted yellow sticker on its corner, and a schedule card that is visibly running: every 4.2 seconds the post count goes up by one, the progress bar grows, a new title drops into Recent posts and a “New post live” toast pops over the window’s lower-left edge. The detail worth copying is that the mockup is alive but calm, with a real pause button, so the hero shows the product’s promise (“it runs while you sleep”) instead of claiming it.

Reference behaviour

  1. First frame: nav (logo, four links, cobalt “Start a kitchen” button), badge “Recipe autopublish · live” with a pulsing white dot, headline “Your recipe blog, cooking itself. Fresh every morning.”, lede, buttons “Start a 14-day kitchen” (cobalt) and “Watch a post get made” (surface), chips “Daily at 7:00”, “11 recipe formats”, “9 languages”, and mono fine print.
  2. The browser shows “app.ovenlight.co/schedules” in the URL pill. The card: Live pill, pause and Edit buttons, “Weeknight Suppers”, “weeknightsuppers.blog”, progress “18 / 40 posts” at 45%, three stats (6 formats, 14 pans linked, 1/d for 40 days). Recent posts lists four titles with green dots and “1d ago” to “4d ago”.
  3. 1.6s after load, then every 4.2s: count +1, bar width animates, percentage updates, a new title is prepended with “just now”, the older times shift (1d, 2d, 3d…), the list keeps four rows, and the toast shows for 2.2s.
  4. At 40 / 40 the next tick wraps back to 18. Titles cycle through a list of eight.
  5. Pause button: toggles aria-pressed, swaps the icon to a play triangle, the Live pill turns grey and reads “Paused”, ticking stops. Pressing again resumes.
  6. When the tab is hidden the interval is cleared; it restarts when visible unless paused.
  7. Buttons press into their shadow on hover and flat on active. The sticker straightens from 9° to -3° and scales 1.06 on hover.

Structure

1280 × 800, bg #EEF3EA with a 24px dot grid
nav  max 1180, padding 20/40   [logo Ovenlight] ............ links ×4 [Start a kitchen →]
hero max 1180, padding 28/40/48, grid minmax(0,1fr) | minmax(0,560px), gap 56, centred
┌ copy ──────────────────────────────┐   ┌ stage (padding 18 right/top) ─────────[sticker 9°]
│ [● RECIPE AUTOPUBLISH · LIVE]      │   │ ┌ window 2px ink, r14, shadow 8/8/0 ─────────────┐
│ Your recipe blog,           64/700 │   │ │ ● ● ●  [ app.ovenlight.co/schedules ]          │
│ cooking itself.  ← cobalt+marker   │   │ ├────────────────────────────────────────────────┤
│ Fresh every morning.               │   │ │ ┌ schedule card ───────────────────────────┐   │
│ lede 19px 46ch                     │   │ │ │ (● LIVE)                     [II] [Edit] │   │
│ [Start a 14-day kitchen][Watch…]56 │   │ │ │ Weeknight Suppers 22/700                 │   │
│ [◷ Daily at 7:00][≡ 11…][◍ 9…]     │   │ │ │ PROGRESS                    18 / 40 posts│   │
│ fine print mono 12                 │   │ │ │ [█████████░░░░░░░░░] 10px                │   │
└────────────────────────────────────┘   │ │ │ [6 formats][14 pans][1/d]                │   │
                                          │ │ └──────────────────────────────────────────┘   │
                                [toast]───┤ │ RECENT POSTS             ALL PUBLISHED         │
                                          │ │ ● title ………………………………… just now (4 rows × 30)│
                                          │ └────────────────────────────────────────────────┘
  • header.nav with an a.logo, a nav labelled “Main”, and a CTA link.
  • main.hero with the copy div and div.stage.
  • The window is role=region labelled “Product preview: a running recipe schedule”. The traffic lights and URL are aria-hidden.
  • Recent posts is an ol with aria-live="polite" and aria-relevant="additions".
  • The toast and sticker are aria-hidden decoration; the list announcement carries the news.

Tokens

:root {
  --bg: #eef3ea;         /* page, pale sage, with a #d3ddd0 1px dot every 24px */
  --surface: #fcfdf9;    /* window, cards, secondary button */
  --ink: #0f1e19;        /* text, borders, shadows */
  --ink-2: #44524c;      /* lede, nav links */
  --ink-3: #6b7871;      /* mono meta */
  --rule: #d7e0d4;       /* stat and list borders */
  --primary: #2443f0;    /* cobalt: headline accent, primary buttons, focus */
  --mark: #ffe14d;       /* marker stripe, sticker */
  --live: #15a05c;       /* badge, progress, dots, toast check */
  --live-soft: #d6f2e2;  /* live pill */
  --sans: "Familjen Grotesk", system-ui, sans-serif;
  --mono: "Fragment Mono", ui-monospace, monospace;
  --hard-sm: 3px 3px 0 var(--ink);
  --hard: 5px 5px 0 var(--ink);
  --hard-lg: 8px 8px 0 var(--ink);
  --r-btn: 10px; --r-cta: 12px; --r-win: 14px; --r-card: 12px;
  --micro: 150ms;
  --ease: cubic-bezier(.2,.7,.2,1);
  --expo: cubic-bezier(.16,1,.3,1);
  --tick: 4200ms; --toast-hold: 2200ms;
}

Typography

RoleFamilySizeWeightLine-heightTracking
LogoFamiljen Grotesk21px7001-0.02em
Nav linkFamiljen Grotesk15px5001.50
BadgeFragment Mono12px40010.06em, upper
H1Familjen Grotesk64px7000.98-0.035em
LedeFamiljen Grotesk19px400, bold run 6001.550
Hero buttonsFamiljen Grotesk17px70010
Feature chipFamiljen Grotesk14px60010
Card titleFamiljen Grotesk22px7001.2-0.02em
CountFamiljen Grotesk15px70010
Labels, URL, times, domainFragment Mono11–12px4001.40.06em when upper
List rowFamiljen Grotesk13.5px50030px rows0

Motion

ThingTriggerPropertyFrom → toDurationEasing
Badge and Live dotsalwaysopacity1 → 0.35 → 12s loopstandard
Progress filltickwidthn/40 → (n+1)/40500msexpo out
New list rowtickopacity, translateY0, -14px → 1, 0500msexpo out
Toasttickopacity, translateY, scale0, 10px, .96 → 1, 0, 1300ms / 400msstandard / expo
Toast hide2.2s after showsame, reversed300msstandard
Button hoverpointertransform, shadow5px shadow → translate(3px,3px), 2px shadow150msstandard
Button activepresstransform, shadow→ translate(5px,5px), none150msstandard
Sticker hoverpointertransformrotate(9deg) → rotate(-3deg) scale(1.06)300msexpo out

Reduced motion: all transitions and keyframes are removed. Ticking continues so the content stays current, but numbers and rows change without movement, and the toast appears and disappears without sliding. The pause button is always available.

States

  • Primary button: cobalt fill, white text, 2px ink border, hard shadow. Secondary: surface fill, ink text.
  • Hover: presses partway into the shadow. Active: flat, no shadow. Focus-visible: 2px cobalt outline, 3px offset.
  • Live: green pill, pulsing dot. Paused: grey pill (#eef0ec, --rule border), static grey dot, text “Paused”, play icon in the button.
  • Toast: hidden (opacity 0) by default, shown for 2.2s per tick.
  • Complete: at 40 / 40 the next tick wraps to 18; there is no separate done state in the hero.

Accessibility

  • Pause control is a button with aria-pressed and a label that flips between “Pause the live preview” and “Resume the live preview”. This is the WCAG 2.2.2 control for auto-updating content.
  • Recent posts ol is aria-live="polite" with aria-relevant="additions", so only the new title is read.
  • Progress is role=progressbar with min 0, max 40, aria-valuenow.
  • The nav CTA keeps an aria-label because its text hides below 420px.
  • Decorative pieces (traffic lights, URL, sticker, toast) are aria-hidden.
  • Contrast: #44524c on #eef3ea ≈ 7:1; white on #2443f0 ≈ 6.9:1; #6b7871 on #fcfdf9 ≈ 4.7:1.
  • Hero buttons are 56px tall; nav button and card controls at least 34–44px.

Responsive rules

  • ≥1280: as drawn.
  • 1100 and below: one column; the browser stage sits under the copy, max 560px wide.
  • ≤720: nav links hide; padding 16px 20px; h1 44px; lede 17px; toast moves inside the window edge (left 8px); sticker sits flush right.
  • ≤420: the nav CTA becomes an arrow-only button; hero buttons go full width.
  • Never let the toast or sticker cause horizontal scroll; body { overflow-x: hidden } is a guard, not the fix. Keep their offsets inside the stage padding.

Acceptance checklist

Always

  • Two columns at desktop, copy left, live product mockup right.
  • One accent word in the headline with a marker stripe behind it.
  • All elevated items use 0-blur ink shadows; buttons press into them.
  • The mockup changes on a timer that is no faster than every 4s.
  • A visible pause button stops all ticking, with aria-pressed.
  • Ticking stops while the tab is hidden.
  • New list items are announced politely; the list never grows past four rows.
  • Reduced motion keeps the content but removes movement.
  • No horizontal scroll at 375px.

This demo

  • First frame shows “18 / 40 posts” at 45%; first tick at 1.6s makes it “19 / 40” and adds “Crispy rice salad with herbs and lime”.
  • Headline accent “cooking itself.” is #2443f0 on a #ffe14d stripe.
  • Window shadow 8px 8px 0 #0f1e19; sticker rotated 9°.
  • Toast reads “New post live / Email sent · just now”.

Implementation notes

The tick. Keep it one function so pause and visibility only start and stop the interval:

let n = 18, timer;
function tick() {
  n = n >= 40 ? 18 : n + 1;
  setProgress(n);
  list.querySelectorAll('time').forEach((t, i) => t.textContent = `${i + 1}d ago`);
  const li = document.createElement('li');
  li.className = 'in';
  li.innerHTML = `<span>${titles[qi++ % titles.length]}</span><time>just now</time>`;
  list.prepend(li);
  while (list.children.length > 4) list.lastElementChild.remove();
  showToast(2200);
}
const start = () => { timer = setInterval(tick, 4200); };

Update the old times before prepending, so the new row is the only “just now”.

The marker highlight is a background gradient, not a pseudo element, so it wraps with the text:

h1 .hl { color: var(--primary);
  background: linear-gradient(transparent 62%, var(--mark) 62% 90%, transparent 90%); }

The list must have a fixed height (4 × 30px = 120px, overflow: hidden) or the window grows by a row for 500ms on each tick and the whole hero jumps.

Common mistakes:

  • A static screenshot in the frame. The point is that it moves.
  • Ticking every second. It reads as a slot machine; 4.2s reads as “running”.
  • Soft drop shadows on the window. Use the 8px hard offset.
  • Drawing a fake cursor clicking around. One loop: count, row, toast.
  • No pause button. Auto-updating content needs one.
  • Putting aria-live on the whole card, so the count, percent and title are all read every 4 seconds.

Rebuild order:

  1. Nav and two-column grid.
  2. Headline, lede, buttons, chips.
  3. Browser frame, sticker, schedule card, list (static).
  4. Tick function and interval.
  5. Toast.
  6. Pause and visibility handling.
  7. Reduced motion and the narrow layout.

Details

Palette
Type
Familjen Grotesk · Fragment Mono
Motion
Subtle motion
Build
One session
Designed bySusan AcharyaKathmandu

Studied

UseArticle

Let the visitor press the controls and watch the card change. Thick black edges and hard shadows keep it friendly.

All sources