Nº 115 of 520
Giant email, click to copy
A 200px Anton address fills the contact page; click copies it, flashes the page black, and scrambles the type to COPIED TO CLIPBOARD.
Preview
Use it
Free to use · credit appreciated1 Once, in your project
npx skills add SusanAcharya/Design-Lounge 2 Then ask
Using the Design Lounge skill, build "Giant email, click to copy" (piece contact-giant-email-copy) 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.
<!-- Design Lounge Nº 115 · "Giant email, click to copy" · designlounge.vercel.app -->
# Giant email, click to copy
> **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.
## What it is
A full-viewport contact section for a sound-and-spatial studio ("Ferro Works"). The email **HI@FERRO.WORK** is the page: 200px condensed Anton, one line, flush left. Clicking it copies `hi@ferro.work`, inverts the whole page to black-on-cream for 1.6s, and runs a glyph scramble that resolves to **COPIED TO CLIPBOARD** then back to the address. A pill that says "Copy ↗" replaces the cursor over the address. The feeling is loud, physical, poster-like: 2px rules, four-column meta, a 52px inverted ticker of services. The detail worth copying is the fit-to-width resize — the display size is computed from a hidden probe so "COPIED TO CLIPBOARD" never overflows, even though it is longer than the email.
## Reference behaviour
1. Initial state: orange field `#FF4F1A`. Top strip of four cells (studio, cities + live Lisbon clock, booking, response time). Giant address. Four contact cells. Black ticker rolling services.
2. Hovering the address: custom cursor hidden; a black pill "Copy ↗" tracks 14px down-right of the pointer; a 14px black underline wipes left → right in 420ms (`scaleX` 0 → 1, origin left).
3. Clicking the address copies `hi@ferro.work` (lowercase) via `navigator.clipboard.writeText`, with a `textarea` + `execCommand('copy')` fallback. `aria-live="assertive"` announces "Copied hi@ferro.work to clipboard" (or the failure string with the address spoken).
4. On success: `body` gets `.flash` (background `--ink`, colour `--paper`); the address gets `.copied` (type and underline become `--paper`); chip text becomes "Copied"; glyphs scramble to `COPIED TO CLIPBOARD` over 720ms.
5. After 1600ms hold, flash and `.copied` drop; chip returns to "Copy ↗"; glyphs scramble back to `HI@FERRO.WORK` over 640ms. Further clicks during the hold restart the timeout.
6. Clicking a `data-copy` link in the grid (phone, press, jobs) copies that string, swaps the link text to "Copied" for 1400ms, and announces via the same live region. Studio address is not copyable.
7. Lisbon clock (`#clock`) formats `Europe/Lisbon` as `Lisbon HH:MM` with `en-GB`, 2-digit hour and minute, and refreshes every 30s.
8. Display size: `font-size = min(260px, 200px * mail.clientWidth / probeWidth)` so the current string always fits. Recalculate on font load and resize.
9. Ticker: duplicated phrase list scrolls `translateX(-50%)` over 38s linear infinite.
10. Reduced motion: scramble snaps to the target string; ticker animation is `none`; transitions 1ms. Pointer-coarse (`hover:none`): native pointer on the address, chip hidden.
## Structure
```
1280 × 800 body grid: auto / 1fr / auto / auto overflow hidden
│ pad-x 40px, 2px rules
┌────────────┬────────────┬────────────┬────────────┐ top, border-bottom 2px
│ FERRO WORKS│ LISBON / │ NOW BOOKING│ RESPONSE │ 18/14 pad, uppercase
│ Sound + │ ROTTERDAM │ Projects │ Under 24 h │ 13px Space Mono
│ spatial… │ Lisbon HH:MM│ from Feb 2027│ Mon–Fri │
├────────────┴────────────┴────────────┴────────────┤
│ CONTACT — THE FASTEST WAY IN CLICK TO COPY kick uppercase │
│ HI@FERRO.WORK ~200px Anton / .86 │
│ (underline 14px at bottom 6px, scaleX 0 until hover) │
├────────────┬────────────┬────────────┬────────────┤ grid, border-top
│ NEW BUSINESS│ PRESS │ CAREERS │ STUDIO │ h4 12/700 +0.06em
│ Inês Prado │ Tom van │ Two open │ Rua do │
│ +351 21… │ Dijk │ roles │ Açúcar 88 │
… 161 more lines. Copy or download for the full brief. Loading the source…Brief
201 linesBuild 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.
What it is
A full-viewport contact section for a sound-and-spatial studio (“Ferro Works”). The email HI@FERRO.WORK is the page: 200px condensed Anton, one line, flush left. Clicking it copies hi@ferro.work, inverts the whole page to black-on-cream for 1.6s, and runs a glyph scramble that resolves to COPIED TO CLIPBOARD then back to the address. A pill that says “Copy ↗” replaces the cursor over the address. The feeling is loud, physical, poster-like: 2px rules, four-column meta, a 52px inverted ticker of services. The detail worth copying is the fit-to-width resize — the display size is computed from a hidden probe so “COPIED TO CLIPBOARD” never overflows, even though it is longer than the email.
Reference behaviour
- Initial state: orange field
#FF4F1A. Top strip of four cells (studio, cities + live Lisbon clock, booking, response time). Giant address. Four contact cells. Black ticker rolling services. - Hovering the address: custom cursor hidden; a black pill “Copy ↗” tracks 14px down-right of the pointer; a 14px black underline wipes left → right in 420ms (
scaleX0 → 1, origin left). - Clicking the address copies
hi@ferro.work(lowercase) vianavigator.clipboard.writeText, with atextarea+execCommand('copy')fallback.aria-live="assertive"announces “Copied hi@ferro.work to clipboard” (or the failure string with the address spoken). - On success:
bodygets.flash(background--ink, colour--paper); the address gets.copied(type and underline become--paper); chip text becomes “Copied”; glyphs scramble toCOPIED TO CLIPBOARDover 720ms. - After 1600ms hold, flash and
.copieddrop; chip returns to “Copy ↗”; glyphs scramble back toHI@FERRO.WORKover 640ms. Further clicks during the hold restart the timeout. - Clicking a
data-copylink in the grid (phone, press, jobs) copies that string, swaps the link text to “Copied” for 1400ms, and announces via the same live region. Studio address is not copyable. - Lisbon clock (
#clock) formatsEurope/LisbonasLisbon HH:MMwithen-GB, 2-digit hour and minute, and refreshes every 30s. - Display size:
font-size = min(260px, 200px * mail.clientWidth / probeWidth)so the current string always fits. Recalculate on font load and resize. - Ticker: duplicated phrase list scrolls
translateX(-50%)over 38s linear infinite. - Reduced motion: scramble snaps to the target string; ticker animation is
none; transitions 1ms. Pointer-coarse (hover:none): native pointer on the address, chip hidden.
Structure
1280 × 800 body grid: auto / 1fr / auto / auto overflow hidden
│ pad-x 40px, 2px rules
┌────────────┬────────────┬────────────┬────────────┐ top, border-bottom 2px
│ FERRO WORKS│ LISBON / │ NOW BOOKING│ RESPONSE │ 18/14 pad, uppercase
│ Sound + │ ROTTERDAM │ Projects │ Under 24 h │ 13px Space Mono
│ spatial… │ Lisbon HH:MM│ from Feb 2027│ Mon–Fri │
├────────────┴────────────┴────────────┴────────────┤
│ CONTACT — THE FASTEST WAY IN CLICK TO COPY kick uppercase │
│ HI@FERRO.WORK ~200px Anton / .86 │
│ (underline 14px at bottom 6px, scaleX 0 until hover) │
├────────────┬────────────┬────────────┬────────────┤ grid, border-top
│ NEW BUSINESS│ PRESS │ CAREERS │ STUDIO │ h4 12/700 +0.06em
│ Inês Prado │ Tom van │ Two open │ Rua do │
│ +351 21… │ Dijk │ roles │ Açúcar 88 │
├────────────┴────────────┴────────────┴────────────┤
│ WRITE TO US ◆ INSTALLATIONS ◆ SONIC BRANDING ◆ … ticker 52px, inverted │
└────────────────────────────────────────────────────┘
chip: position fixed, follows pointer, z-index 5
.top— 4-column grid,aria-label="Studio details". First line of each cell is<b>.<main class="stage">— flex column, vertically centred..kickthen<button class="mail">..mail—all:unset; contains visible.t(aria-hidden) and.sr“Copy email address hi@ferro.work”.aria-describedby="hint".#hintsr: “Copies the address to your clipboard”.#livesraria-live="assertive".<section class="grid" aria-label="Other contacts">— four cells. Copyable items are<a href="#" data-copy="…">..tick—aria-hidden, inner flex row duplicated so the 38s loop is gapless. Each item has a 14px diamond::after(rotated 45° square)..chip—aria-hidden, not in the tab order.
Tokens
:root {
/* colour — safety-orange field, near-black ink, cream flash */
--bg: #ff4f1a; /* page */
--ink: #0d0d0d; /* type, rules, ticker, chip */
--paper: #f2efe6; /* flash type, copied address */
--line: rgba(13, 13, 13, .9); /* 2px rules */
--ink-2: #3a1a0e; /* declared; body colour is --ink */
/* type */
--display: "Anton", Impact, sans-serif;
--mono: "Space Mono", ui-monospace, monospace;
/* layout */
--pad: 40px;
--rule: 2px;
--mail-fs: 200px; /* base; JS may raise to 260px cap */
--tick-h: 52px;
/* motion */
--t-micro: 140ms;
--t-wipe: 420ms;
--t-scramble-out: 720ms;
--t-hold: 1600ms;
--t-scramble-in: 640ms;
--ease: cubic-bezier(.2, .7, .2, 1);
--ease-out: cubic-bezier(.16, 1, .3, 1);
--roll: 38s;
}
Typography
| Role | Family | Size | Weight | Line-height | Tracking | Case |
|---|---|---|---|---|---|---|
| Address / copied | Anton | 200px (fit) | 400 | 0.86 | −0.01em | UPPERCASE |
| Ticker | Anton | 28px | 400 | 1 | +0.02em | UPPERCASE |
| Body / meta | Space Mono | 13px | 400 | 1.5 | 0 | sentence |
| Top labels | Space Mono | 13px | 400/700 | 1.5 | +0.04em | UPPERCASE |
| Kick | Space Mono | 13px | 700/400 | 1.5 | +0.04em | UPPERCASE |
| Grid headings | Space Mono | 12px | 700 | 1 | +0.06em | UPPERCASE |
| Chip | Space Mono | 12px | 700 | 1 | +0.06em | UPPERCASE |
| Grid links | Space Mono | 13px | 400 | 1.5 | 0 | as written |
Kick right label is weight 400; left is 700. Top cells: <b> 700, second line 400.
Motion
| Element | Trigger | Property | From → To | Duration | Easing | Notes |
|---|---|---|---|---|---|---|
| Address underline | hover / focus | transform scaleX | 0 → 1 | 420ms | --ease-out | origin left; 14px tall at bottom 6px |
| Chip | pointermove | opacity, transform | 0, scale .6 → 1, translate(14,14) | 140ms / 200ms | --ease / --ease-out | left/top = clientX/Y |
| Body flash | copy success | background, color | orange/ink ↔ ink/paper | 140ms | --ease | also invert rule colours |
| Glyph scramble | copy / revert | textContent per char | random glyphs → target | 720ms / 640ms | — | refresh ≥48ms; see notes |
| Link hover | hover | background, color | inherit → ink on --bg | instant | — | flash invert: paper on ink |
| Ticker | load, loop | translateX | 0 → −50% | 38s | linear | infinite; content duplicated |
| Link label | data-copy click | textContent | original → Copied → original | 1400ms | — |
Scramble: for target string of length n and duration dur, char i locks at at[i] = (i/n)*dur*0.7 + random()*dur*0.3. Before at[i]*0.4 show the previous character if it exists; otherwise pick from #%&*+=/\\<>[]{}?!0123456789ABCDEFGHJKLMNPQRSTUVWXYZ. Spaces lock immediately. Reduced motion: set textContent to the target and skip the loop.
States
- Default: orange page, black type, chip opacity 0, underline
scaleX(0). - Address hover: chip
.on, underline full,cursor: none. - Address focus-visible: 3px ink outline, 6px offset; underline also wipes in.
- Copied / flash: page black, type cream, rules cream, ticker orange with black diamonds. Chip: background
--paper, colour--ink. Address colour--paper. - Busy: a second click during the 1600ms hold clears the timeout and runs copy again;
busystays true until the return scramble finishes. - Copy failed: live region “Copy failed. The address is hi@ferro.work”; scramble target stays
HI@FERRO.WORK(do not show COPIED TO CLIPBOARD). - Grid link copied: text “Copied” or “Copy failed” for 1400ms.
- Grid link hover: background
--ink, colour--bg; 2px underline isborder-bottom: 2px solid currentColor. - No hover (touch):
.mail { cursor: pointer }, chipdisplay: none.
Accessibility
- Address is a real
<button type="button">. Visible Anton span isaria-hidden; an.srchild names the action.aria-describedbypoints at the hint. - Live region is
aria-live="assertive"and visually clipped (1×1). - Grid copy controls are links with
href="#";preventDefaulton click. Studio block has no copy action. - Keyboard: Tab hits the address button then the three copy links. Enter/Space activates copy (native button). Focus ring 3px on the address, 2px on grid links.
- Chip is pointer-only decoration (
aria-hidden,pointer-events: none). - Contrast: black on
#FF4F1Ais well above 4.5:1 for 13px mono; cream on black during flash likewise. Anton at 200px is display type. - Hit target: the address button includes 14px + 26px vertical padding; grid links are inline but sit in padded cells.
Responsive rules
- ≥ 1280: as specified. Address fits via the probe; do not wrap.
- 1024–1279: keep four columns; the probe will drop the Anton size below 200px as needed (floor is whatever
min(260, 200 * width / probe)yields). - 768–1023: top and grid become 2×2; ticker still 52px. Address
white-space: nowrapremains — shrink the font, never wrap. - < 640: single column meta;
--pad: 20px. Hide the ticker or let it clip. Chip already hidden on coarse pointers. - Reduced motion as above. Do not disable copy.
Acceptance checklist
- Display string is
HI@FERRO.WORKin Anton, one line, fitted so it never overflows the content width. - Click copies
hi@ferro.work(lowercase) and announces success or the spoken fallback address. - Successful copy flashes the page to black/cream and scrambles to
COPIED TO CLIPBOARDin 720ms, holds 1600ms, scrambles back in 640ms. - Hovering the address hides the system cursor and shows a “Copy ↗” pill that tracks the pointer.
- A 14px underline wipes in over 420ms with
cubic-bezier(.16,1,.3,1). - Phone, press@ and jobs@ each copy their
data-copyvalue and briefly read “Copied”. - Lisbon clock uses
Europe/Lisbonand updates at least every 30s. - Ticker loops in 38s; content is duplicated so the join is invisible.
- Reduced motion skips scramble frames and the ticker animation; copy still works.
- Focus-visible rings are present on the address and every copy link.
- On touch (
hover: none) the address usescursor: pointerand the chip is not shown. - Rules are 2px and invert with the flash.
Implementation notes
Fit the string with a hidden probe cloned from .t, 200px, off-canvas. Measure after fonts.ready and on resize:
function sizeFor(str) {
probe.textContent = str;
const w = probe.getBoundingClientRect().width || 1;
return Math.min(260, 200 * (mail.clientWidth / w));
}
t.style.fontSize = sizeFor(str).toFixed(1) + 'px';
Clipboard with fallback (the iframe sandbox may lack clipboard permission):
async function copyText(s) {
try { await navigator.clipboard.writeText(s); return true; }
catch {
const a = document.createElement('textarea');
a.value = s; a.style.cssText = 'position:fixed;opacity:0';
document.body.appendChild(a); a.select();
const ok = document.execCommand('copy'); a.remove(); return ok;
}
}
Scramble lock times — later characters stay noisy longer; cap glyph refresh at 48ms so it does not look like a flicker storm:
const at = [...to].map((_, i) => (i / n) * dur * .7 + Math.random() * dur * .3);
// each frame: (e >= at[i] || c === ' ') ? c : (e < at[i]*.4 && from[i] ? from[i] : GLYPHS[rnd])
Common mistakes: copying the display string HI@FERRO.WORK instead of lowercase; wrapping the Anton line; using cursor: none on body (only the address); driving the ticker with JS instead of a 38s CSS loop; forgetting all:unset on the button so a native border shows; putting the live region in a polite status that is skipped during the scramble.
Details
- Palette
- Type
- Anton · Space Mono
- Motion
- Rich motion
- Build
- One session
- Tags
Studied
Don't Board MeA service with a next step. The headline can shout. The booking stays plain.
All sourcesOn the shelves