Design Lounge
Install

Nº 489 of 520

Handwritten homepage

A first page written as a letter on warm paper: a short nav, a signed opening, and three notes for three pieces of work.

Preview

Open full size
1280 × 800 · 7.7 KB · 244 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 "Handwritten homepage" (piece handwritten-homepage) 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

256 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.

What it is

The first page of Slip room, a fictional pottery workshop, written as a letter. A cream sheet sits on a warmer desk. Across the top is a short nav. The opening is a date, a two-line title, a salutation, two short paragraphs, and a signature. Three notes for three pieces of work sit in the right margin, spaced down the height of the letter. One word is struck in red and rewritten. Gochi Hand is only the nameplate, the title, the note titles, and the signature. Patrick Hand is every line a person reads: nav, date, salutation, paragraphs, note bodies, footer.

Reference behaviour

  1. Initial state at 1280×800: the sheet is centred on the desk and the whole page fits without scrolling. Nav reads Letter (current), Work, Visit. The letter and the first note, “The quay mug”, are both fully visible. All three notes are visible. Each note’s extra line is hidden. No note has aria-pressed="true".
  2. The title “Come by on Thursday” wraps to two lines because its max-width is 8.2em. Body lines wrap inside 34ch. They are not stretched across the sheet.
  3. Hover a note: background becomes the sheet colour #FFFAF0, border becomes blue #1D4E89, over 160ms. Hover a nav link: colour becomes blue.
  4. Click a note. That note sets aria-pressed="true", border and background match the hover, and its hidden line appears. The other two notes close: aria-pressed="false" and their extra lines hide. Click the open note again to close it.
  5. Click Letter, Work, or Visit. That link gets aria-current="page" and the others lose it. The browser follows the hash. Letter starts as the current link. Work and Visit do not open a note, because their targets are not buttons. If a nav target is itself a note button, open that note with the same toggle as a click.
  6. Active (mouse down) on a note: it moves down 1px. The tilted note keeps its −1.5° while it moves.
  7. Nothing loops. The red correction is static. Reduced motion: transitions last 1ms.
  8. First-frame test at 1280×800, before any click: the h1 bottom is above 800, the first .note bottom is above 800, and the footer bottom is above 800. The extra lines report hidden === true and display: none. If those lines are visible, a display: block rule is overriding the hidden attribute.
  9. Sideways test at 800×800: documentElement.scrollWidth <= clientWidth. The page may be taller than 800. The letter and the first note should still both start inside the first viewport. The tilt is gone at this width.

Structure

1280 × 800, desk padding 28px 36px, sheet centred
┌──────────────────────────────────────────────────────────────────────────┐
│ Slip room (Gochi 34)              Letter   Work   Visit (Patrick 20)    │  head
│ ─ hairline ──────────────────────────────────────────────────────────── │
│ │ 4 October 2026 (blue)                  ┌ The quay mug ─────────────┐ │
│ │ Come by on                             │ one sentence               │ │
│ │ Thursday          h1, max 8.2em        └────────────────────────────┘ │
│ │ Dear friend,                                                              │
│ │ paragraph, 34ch                        ┌ Thursday hours  (−1.5°) ──┐ │
│ │ paragraph, 34ch                        │ one sentence               │ │
│ │ Tess                                   └────────────────────────────┘ │
│ │ at the slip room                       ┌ Twelve letters ───────────┐ │
│ ─ footer hairline ───────────────────────│ one sentence               │ │
│ Tess Pell, Cedar yard. Written by hand.  └────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────┘
blue margin rule at 26px from the sheet's left, from 78px down to 52px up
  • Desk is the page. Sheet is an article, width min(1120px, 100%), radius 2px.
  • Header is a flex row: nameplate (div.mark, not a paragraph) and nav labelled “Shop”.
  • The split is a grid: minmax(0, 520px) for the letter and 320px for the notes, justify-content: space-between, gap 32px, items stretch.
  • Notes are a ul with three li, each holding one button.note. The list is a column flex with justify-content: space-between and a 14px gap, so the three slips spread along the letter.
  • Footer is one line under a hairline, margin-top 22px. It is not pushed by a growing empty region: the sheet is as tall as its content, and the desk centres that sheet.
  • Semantic map: article > header (nameplate + nav) > letter div#letter + ul#work > footer#visit.

Tokens

:root {
  --desk: #efe6d2;     /* page, the table under the sheet */
  --sheet: #fffaf0;    /* letter paper */
  --slip: #f6f1e4;     /* note paper, a step darker than the sheet */
  --ink: #1c2430;      /* text */
  --ink-2: #3d4a5c;    /* footer, place line, hidden note line */
  --line: #e2d5bc;     /* hairlines, note borders */
  --blue: #1d4e89;     /* the one blue ink: date, current link, focus, pressed border */
  --red: #b42323;      /* the one red: the crossed word and its replacement */
  --title: "Gochi Hand", cursive;
  --hand: "Patrick Hand", cursive;
  --ease: cubic-bezier(.2, .7, .2, 1);
  --fast: 160ms;
  --radius: 2px;
  --shadow: 0 10px 24px -16px rgba(28, 36, 48, .2);
}

Load only those two families, weight 400, from one Google Fonts stylesheet. Do not request a bold weight. Set font-synthesis: none so the browser does not fake one.

Spacing on an 8px grid, with 4px and 2px only where a hairline needs them:

TokenValueUse
22pxplace-line margin above the signature
44pxgap under a note title
66pxgap above a revealed note line
88pxdate margin-bottom
1010pxsalutation margin-bottom, header padding-bottom
1212pxparagraph margin-bottom, footer padding-top, narrow desk padding
1414pxtitle margin-bottom, note-list gap
1616pxsignature margin-top, note padding inline
2222pxheader margin-bottom, footer margin-top, nav column gap
2626pxsheet padding-top
2828pxdesk padding-top, header column gap
3232pxsplit gap
3636pxdesk padding inline
4040pxsheet padding-right
4848pxsheet padding-left, so text clears the margin rule

The margin rule is 1px wide, rgba(29, 78, 137, .4), left: 26px, top: 78px, bottom: 52px. It starts under the header and stops above the footer. It is not a border on the text column.

Exact strings for this demo, in order:

  • Nameplate: Slip room
  • Nav: Letter, Work, Visit
  • Date: 4 October 2026
  • Title: Come by on Thursday
  • Salutation: Dear friend,
  • Paragraph: The kiln is on from noon ten. Bring the mug you want glazed, and a name for the bottom. (“noon” is the struck word, “ten” is the replacement.)
  • Paragraph: I keep tea on until the last cup comes out. Push the door if it sticks.
  • Signature: Tess
  • Place: at the slip room
  • Note 1 title / body / more: The quay mug / A white cup with one blue line, promised for the 18th. / The line is cobalt, laid on after the bisque.
  • Note 2 title / body / more: Thursday hours / Ten until four. The door is the blue one on Cedar yard. / If you are late, leave the mug on the stone sill.
  • Note 3 title / body / more: Twelve letters / A folded note for each seat at a winter supper. / The name goes on the outside, in blue ink.
  • Footer: Tess Pell, Cedar yard. Written by hand.

Typography

RoleFamilySizeWeightLine-heightTrackingCase
Nameplate “Slip room”Gochi Hand34px40010sentence
Page titleGochi Hand52px4001.150sentence, max-width 8.2em
Note titleGochi Hand28px4001.150sentence
Signature “Tess”Gochi Hand46px40010name, a div, not a p
Nav linkPatrick Hand20px40010sentence
DatePatrick Hand20px400inherit0blue
SalutationPatrick Hand24px4001.450sentence
Body paragraphPatrick Hand22px4001.450sentence, max-width 34ch
Note bodyPatrick Hand20px4001.350one sentence
Place line and footerPatrick Hand20px4001.450ink-2

Letter-spacing on every one of these is 0. Do not add tracking to either hand. Do not set text-transform: uppercase on either hand. A paragraph, a link, a button label, and a footer line are Patrick Hand. Gochi Hand is a title, a nameplate, or a signature.

Motion

ElementTriggerPropertyFrom → toDurationEasing
Notehover, pressedbackground, border-colorslip / line → sheet / blue160mscubic-bezier(.2,.7,.2,1)
Noteactivetransform0 → translateY(1px)160mssame
Tilted noteactivetransformrotate(−1.5deg) → that plus translateY(1px)160mssame
Nav linkhover, currentcolorink → bluenone (instant colour)n/a

No entrance animation. No looping animation. Reduced motion: every transition and animation duration is 1ms. The tilt is a resting position, not an animation, and it is removed below 900px.

States

  • Nav rest: ink #1C2430, no underline. Current and hover: blue #1D4E89. Initial current link is Letter.
  • Note rest: slip fill #F6F1E4, 1px line border, radius 2px, extra sentence hidden. Hover and pressed: sheet fill, blue border. Pressed also shows the extra sentence in ink-2. Active: 1px down.
  • Second note only: rotate(-1.5deg) at widths above 900px. The first and third notes are square to the page.
  • Correction: the word “noon” is a del in red with a 2px strike. The word “ten” is an ins in red with no underline. Both stay Patrick Hand at the body size.
  • Focus-visible: 2px solid blue, offset 3px, on links and note buttons. Remove the default outline only when :focus-visible replaces it.
  • Selection: background blue, text sheet.

Accessibility

  • One h1: “Come by on Thursday”. The nameplate is a div, not a second heading and not a paragraph in the script.
  • Nav has aria-label="Shop". Current page uses aria-current="page" on exactly one link.
  • Each note is a button type="button" with aria-pressed. The extra line is a span with the hidden attribute while closed, so it leaves the accessibility tree.
  • The struck word has aria-hidden="true" so the sentence is heard as “from ten”, which is the corrected reading. The replacement remains an ins.
  • Date is a time with datetime="2026-10-04".
  • Contrast, measured on the sheet #FFFAF0 unless noted:
PairRatioWhere
#1C2430 on #FFFAF015.0:1body, titles, notes
#1C2430 on #F6F1E413.9:1note text on slip paper
#1D4E89 on #FFFAF08.1:1date, current nav
#1D4E89 on #F6F1E47.4:1blue on a slip, if a border is not enough
#B42323 on #FFFAF06.3:1the correction at 22px
#3D4A5C on #FFFAF0above 7:1footer and the place line
  • Do not grey the footer down to #6A6256 thinking it looks softer. #3D4A5C is the secondary ink that still clears 4.5:1 at 20px.
  • Hit targets: nav links min-height 44px. Note buttons are the full slip, well above 44px.
  • Focus order: Letter, Work, Visit, then the three notes. Enter or Space activates a note.

Responsive rules

  • ≥ 1280: as drawn. The sheet is centred. The first viewport shows the letter, all three notes, and the footer line.
  • 1024 to 1279: same two columns. The letter column may shrink (minmax(0, 520px)). Title stays 52px until the 900px break. Paragraphs stay 34ch.
  • 901 to 1023: still two columns if both fit. If the 320px note column plus the letter crowd the padding, allow the sheet to be width: 100%. Do not drop the tilt until 900px.
  • ≤ 900: the desk is block layout, padding 12px. The split stacks. Notes follow the letter with margin-top 22px and gap 12px, top-aligned, not spaced apart. Remove the −1.5° tilt so a full-width slip cannot poke past the viewport. Title drops to 44px. The page may grow taller than 800px. It must not scroll sideways.
  • < 640: same stack. Nav may wrap. The margin rule stays 12px from the sheet edge. Paragraph max-width remains 34ch so a wide phone in landscape does not grow a long line.
  • Horizontal overflow is a failure at every width, including 800px. Test documentElement.scrollWidth <= clientWidth.

Acceptance checklist

Always

  • The page is a letter: date, salutation, a few short paragraphs, a sign-off, three notes, a one-line footer, and a short nav.
  • Titles, the nameplate, note titles, and the signature use Gochi Hand at weight 400. Paragraphs, nav, buttons, and the footer use Patrick Hand at weight 400.
  • No paragraph is set in Gochi Hand, Caveat, or another signature script.
  • Letter-spacing is 0 on both families. Nothing uses uppercase styling.
  • At most one element is tilted, and by no more than 2 degrees. Below 900px that tilt is removed.
  • One blue ink and one red. Red appears only on the correction.
  • Body measure stays near 34ch. Lines do not run the full viewport.
  • Note buttons toggle aria-pressed and reveal one extra sentence. Opening one closes the others.
  • Focus-visible is a 2px blue ring, offset 3px. Nav targets are at least 44px tall.
  • Reduced motion shortens transitions to 1ms. There is no looping motion.
  • At 800px wide, nothing overflows horizontally.

This demo

  • Nameplate “Slip room”. Title “Come by on Thursday”. Salutation “Dear friend,”.
  • The correction reads noon struck and ten in red #B42323, inside the sentence about the kiln.
  • Notes: “The quay mug”, “Thursday hours” (the tilted one), “Twelve letters”.
  • Footer: “Tess Pell, Cedar yard. Written by hand.”
  • Date text “4 October 2026”, colour #1D4E89.
  • Desk #EFE6D2, sheet #FFFAF0, slip #F6F1E4, ink #1C2430.
  • At 1280×800 the first frame shows the letter and the first note without scrolling, and the footer is on that same screen.

Implementation notes

The demo is one HTML file. First line:

<!-- Design Lounge piece: handwritten-homepage · platform: web · 1280x800 -->

html, body { height: 100%; margin: 0 }. Viewport meta is width=device-width. The only external request is the Google Fonts stylesheet for Gochi+Hand and Patrick+Hand. No <script src>, no images, no fetches. Inline the open-note script at the end of body. Do not touch localStorage. Do not call alert or console.log.

Hover colour on the nav can be instant. The 160ms transition is for the note fill and border only. Keep the easing cubic-bezier(.2, .7, .2, 1), not ease and not linear.

Sheet radius is 2px. Shadow is 0 10px 24px -16px rgba(28, 36, 48, .2) and it belongs on the sheet only, not on each note. Notes separate themselves with the slip colour #F6F1E4 and a 1px #E2D5BC border. A drop shadow on every slip starts to look like a card grid. One tilt, on Thursday hours, is enough to keep the three from reading as equal feature tiles.

The desk centres the sheet with align-items: safe center. At 1280×800 the sheet is shorter than the viewport, so a margin of desk shows around it and the footer is still on the first screen. Under 900px the desk switches to block layout so a stacked page starts at the top and can grow past 800px. Do not force min-height: 100vh on the sheet at that breakpoint. An empty cream band under a short letter is the failure that rule prevents.

Gochi Hand and Patrick Hand ship at weight 400 only. Do not set font-weight: 700 on a note title to make it win. font-synthesis: none is there so the browser will not invent a bold. If a note title needs more presence, raise the size (28px is the note title) rather than the weight.

Selection colour is blue fill with sheet text: background: #1D4E89; color: #FFFAF0. It matches the ink already in the date, so a selected phrase does not introduce a new hue.

The focus ring is that same blue: 2px, offset 3px. This page has no filled blue button, so the ring does not need a second colour.

Hidden lines must stay hidden. A class that sets display: block overrides the user-agent rule for the hidden attribute. Close it again:

.more { display: block; margin-top: 6px; color: var(--ink-2); }
.more[hidden] { display: none !important; }

One open note. Do not leave every slip expanded on load. The first frame is the short form.

function openNote(btn) {
  var on = btn.getAttribute("aria-pressed") === "true";
  notes.forEach(function (b) {
    b.setAttribute("aria-pressed", "false");
    b.querySelector(".more").hidden = true;
  });
  if (!on) {
    btn.setAttribute("aria-pressed", "true");
    btn.querySelector(".more").hidden = false;
  }
}

Hands. Put Gochi Hand on h1, .mark, .sign, and .nt only. The signature is a div, not a p. If a stylesheet sets p { font-family: Gochi Hand }, the piece is wrong. Common mistakes: a hero headline in a script with a pill button under it; letter-spacing: 0.08em on the nav; small-caps or uppercase labels; tilting all three notes; a purple gradient on the desk; loading Caveat or Homemade Apple for the paragraphs; faking bold on a family that only has weight 400.

Details

Palette
Type
Gochi Hand · Patrick Hand
Motion
Subtle motion
Build
One session
Designed bySusan AcharyaKathmandu

Studied

Linear

Show the product doing the work. Fade it at the edges and keep one colour for what matters.

All sources