05 · Game Night, 7 pm — "A run of show you can shop"
Thesis
The homepage is the evening's schedule. Timestamps mark each section as an event, a 2px navy rail runs the whole page with a dot at every event, and the photography is only what a game night actually looks like: hands at the floral table, a spritz beside a fanned hand, racks on the navy table, the kitchen-table host, the green tablecloth. The sweater is what you put on first, so it is the first product on the page and the first thing that moves.
Run of show as built:
| Time | Event | Section |
|---|---|---|
| 6:30 pm | Dress for the table. (H1) | Hero: lede and both CTAs under the H1, then the sweater flat |
| — | What to bring | Four category tiles |
| 6:45 pm | Pick your color | Colorway wall, seven deep links, Hot Pink/Blush leads |
| 7:00 pm | Set the table | Three-price strip (mobile), then the ladder, Complete Set default |
| 7:15 pm | Pick a deck | Five editions, Beach first, thumb scroll with peek, whole tile links to the PDP |
| 7:30 pm | Cards, not tiles | Comparison table, three benefits, two Learn to play links |
| 9:45 pm | Table talk | Six placeholder reviews interleaved with six game-night photos |
| Next Tuesday | Join the table | Email capture with the fall-drop incentive, trust strip |
Art direction decisions
- Type. Big Shoulders Display 700/800 (Google Fonts, loaded non-blocking) for timestamps, headings and product names; Work Sans 400/500/600 for everything else. Exactly two families. Sentence case throughout; no
text-transformanywhere. On desktop the timestamps are the largest type on the page (104px; "Next Tuesday" at 84px so "Tuesday" fits the 360px column), larger than the 76px H1. At 375 every timestamp is a 24px label beside the rail dot and the headings carry the size (H1 45px, H2 37px), so the brand statement, not the time, is the biggest thing in the first viewport. - Color. Background
#FBF8F3. Text navy#17264A; secondary text warm charcoal#4B4A5A(8:1 on the background). Rules#D9D1C3. Accent purple#6B4FBBwith white text (6.1:1), used only on primary buttons and the focus ring the brief specifies. Secondary buttons and text links are navy. The lavender chip's second stripe is#9578D1, deliberately not the accent. - Layout language. At 375 the rail is a 2px navy line at x=12 with content from x=28 (a 327px measure). At 1024+ each event is a three-column grid: a 360px time-and-heading column, the 2px rail, content. The rail is a real grid cell per event so consecutive sections join into one continuous line. Dots sit at each timestamp; the untimed "What to bring" gets a smaller dot. No cards with shadows, no rounded photo corners: rules, the rail and clean rectangles do the structuring. Buttons have a 4px radius.
- Flats on the page, not in boxes. Every product-on-white image (hero, swatches, Beach box, open trays, guide thumbnails) carries
mix-blend-mode: multiply, so the white photo background becomes the warm-white page and the garment sits directly on it. Photographs with real backgrounds are not blended. - Hero composition. Mobile order: time label, H1, lede, primary button and text link, then the Green/Blush flat as a 327px square with its caption. Measured at 375x812: H1 181–264px, primary button 372–420px, text link 428–472px, image 492–819px, so the button and all but the last 7px of the sweater sit in the first viewport, and the MAHJ letters are visible on a 375x667 screen too. Desktop: 104px time, H1, lede and buttons in the left column; the flat at 640px in the content column.
- The colorway wall is where the boldness goes. Seven flats as paint chips: image, a two-tone stripe in the sweater's body and letter colors, the name. Hot Pink/Blush leads (full width on mobile, a 2x2 cell on desktop) so the hero's Green/Blush file is not repeated at full width; Green/Blush appears as a standard tile in the second row. The eighth cell is the only human in the section: the two-women booth shot captioned "Green/Blush and White/Blue, worn at a trade show", the product paragraph, price, sizes and the section's single CTA.
- Bundle ladder. On mobile a three-cell price strip (Cards only $62.95 · Complete Set $85 to $100 · Table Set $165, each cell an anchor to its tier) sits above the stacked tiers so all three prices are visible before the first tier card; it is hidden on desktop where the three columns show the prices at once. Complete Set carries a 2px navy outline, the "Most tables" tag and the only accent button in the section; the other two tiers use navy ghost buttons. What's-in-the-box lists are plain disc bullets. Table Set shows $165 with
$199.90struck through (visually hidden "Compare at"). Add-on prices for Racks, Rack bag and First Lines follow as text links. - Editions. Five open-tray shots, Beach first with its Etsy line, 72vw items on mobile so the next deck peeks, 268px items on desktop bleeding to the right edge so Texas peeks. No arrows; scroll-snap only. Each whole tile is a link to the edition PDP, where the Complete Set is the default variant. There is no bare-deck add to cart on the homepage; the lede says every edition comes as a Complete Set.
- Cards, not tiles. A real
<table>with a visually hidden caption and row headers. The three original benefits survive as H3 microcopy beside the table. Learn to play is two rows with a thumbnail, title, one line and the read time in bold. - Table talk. Mobile: a two-column grid where photos pair up and every quote spans the full 327px width (about 40 characters per line). Desktop: three-column CSS masonry. Photos and reviews alternate in DOM order; the storefront on-model shot sits above Dana R.'s sweater review with the caption "The White/Blue, worn to a stockist's table." Each review is a
<figure>withdata-placeholder="review", arole="img"star rating, blockquote and figcaption. Header shows "4.9 from 212 reviews" withdata-placeholder="aggregate". - Join the table. Labelled email input, one accent button ("Save my seat"), trust strip as a dotted list. Footer groups: Shop, Help, Elsewhere (Wholesale, Instagram), a smaller labelled signup; payment methods listed once as text; no raw URLs.
The single motion moment
On load the hero figure slides in from the left once, as if pulled from a closet: @keyframes closet { from { transform: translateX(-14%); opacity: 0 } }, 600ms, cubic-bezier(.22,.61,.36,1), 50ms delay, fill-mode both. Pure CSS, so it works without JS. Disabled entirely under prefers-reduced-motion: reduce. Nothing else animates: no scroll reveals, no IntersectionObserver, no rail progress fill. Button hovers are 120ms color changes.
Interactions and accessibility
- Skip link to
#main;header, two labellednavs (Primary, Mobile) plus three footer navs,main,footer; every image has meaningful alt oralt=""for the decorative drawer thumbnail. - Mobile drawer:
role="dialog" aria-modal="true", opens with focus on the close button, Tab and Shift+Tab wrap inside, Escape closes and returns focus to the menu button, body scroll locks while open, auto-closes if the viewport grows past 1024px. Six items at 56px tap height, "Shop the sweater" tile on top. - The only Shopify-bound actions on the page are the two signup forms; each
console.logs a descriptive line and shows a 2-second toast in arole="status" aria-live="polite"region, then resets. Nothing navigates away; collection and product links remain real hrefs. The cart icon shows a static count of 0. - Focus ring: 3px accent outline with 3px offset on
:focus-visible. Tap targets are at least 44px (icon buttons 44, buttons 48, drawer items 56, footer and add-on links 44, price-strip cells 44, whole-tile links on decks and categories). - Headings read as a table of contents: one H1, eleven H2 (six timed events plus What to bring in the schedule, four in the footer), H3 for products and benefits, H4 only for the two Learn to play articles under the "Learn to play tonight" H3.
Assumptions
- A 6:45 pm event was added. The task grouped hero and colorway wall under 6:30, but the fixed section order puts the category tiles between them, so the wall gets 6:45 and the tiles are an untimed list.
- H1 is "Dress for the table." One of the brief's candidates; it doubles as the 6:30 event name. "Game night, anywhere." closes the lede. Kept per the critic's assignment.
- Green/Blush is the hero colorway (and the drawer tile); Hot Pink/Blush leads the wall so the hero file is not shown twice at full width. No sales-by-colorway data was available.
- "Cards only" links to the Beach Edition PDP (the brief says "the edition PDP"; Beach is the lead edition). The Complete Set links to
/collections/bundles-gifts, the Table Set to/products/table-setmarkeddata-placeholder="sku". - The header logo is the arched wordmark (its 400px twin, 64px rendered); the drawer uses the brand name in the display face as its title.
- The announcement bar is two static lines on mobile (about 44px) and one line on desktop. Announcement plus header total about 104px at 375px; only the header is sticky.
- Search and cart icons are links to
/searchand/cart. - The 24px time label applies to every timestamp at 375, not only the hero's, so the schedule stays consistent on mobile; the critic's instruction named the hero, and a 24px hero time beside 76px section times would have read as a mistake.
Honesty notes on photography
- No sweater at a table exists. The hero uses the flat. Human presence comes from the booth pair (wall info block) and the storefront shot (reviews), each captioned for what it is: a trade show and a stockist's display table, not a game.
- No exploded Table Set or all-components shot. The Table Set tier uses
racks-with-cards-overhead(racks, cards and a First Lines card) with the caption "Shown: racks, cards and First Lines. Ships gift-wrapped with the rack bag." The Complete Set usesracks-in-play-green-tablecloth, a Complete Set genuinely in play. - No Summit lifestyle shot. Summit appears only in the edition row (open tray).
- First Lines photos are CDN product shots, used only inside the Table Set tier image.
- Instagram-framed originals.
lifestyle-hands-floral-tablecloth-overheadandlifestyle-cards-cocktailscarry a thin baked-in frame; they sit in an overflow-hidden figure withtransform: scale(1.07)so the frame is cropped away. The kraft gift-box shot was not used because its blue frame is too wide to crop honestly. - Green/Blush and White/Blue flats exist only at 1024px and the lavender at 1206px. Every
srcsetdescriptor states the file's real pixel width, including the portrait-400twins (300w or 320w) and-800twins (600w or 640w), verified by script against the files.
Performance
- Fonts: the Google Fonts stylesheet is loaded with
<link rel="preload" as="style" onload="this.rel='stylesheet'">plus a<noscript>fallback,display=swap, so it no longer blocks first paint. The hero image has a<link rel="preload" as="image">whoseimagesrcset/imagesizesmatch the<img>exactly, plusfetchpriority="high"and no lazy attribute. - Images: 31
<img>, all with realsizes,width,height; 29 lazy (all but logo and hero). Anything rendered at 200px or less (logo, category tiles, learn thumbnails, drawer thumbnail, wall info photo) uses the-400twin as its only source. Swatches, review photos and tier images carry400wand800wcandidates with exactsizes(tiles are 151.5px at 375, so a 2.6x phone selects the 400 twin and a 3x phone the 800). Hero and edition trays carry 400/800/full. At 375 and 1x the browser selects a-400twin for every image except the hero (verified viacurrentSrc); the 28 distinct-400files referenced total about 590KB. - Verified by rendering in headless Chrome at 375 and 1440 (via a 375px iframe wrapper, since Chrome enforces a minimum window width) and by a scripted in-page check: one H1,
scrollWidthequals viewport at both sizes (no horizontal overflow), page height 10567px at 375 and 7570px at 1440, hero animation and multiply blend applied, drawer trap and Escape behave, the signup form logs, toasts and resets.
Revision (after the critic's pass)
Changed, in the order given:
- Hero at 375: timestamp reduced to a 24px label beside the rail dot; lede and both CTAs moved directly under the H1, above the image. Primary button now tops at 372px (was about 815px). Desktop keeps the 104px times.
- Removed the five edition-row "Add to cart" buttons and their JS; the whole deck tile links to the PDP. Lede now says every edition comes as a Complete Set.
- Replaced the empty checkbox pseudo-elements on category tiles and in-the-box lists with plain disc bullets (lists) and nothing (tile headings).
- Rail moved from x=18 to x=12, content from x=48 to x=28 (measure 309px to 327px). Review quotes are 1-up at 375 (photos still pair 2-up).
- Footer group renamed "Stockists" to "Elsewhere".
- Wall reordered: Hot Pink/Blush leads the full-width slot; Green/Blush is a standard tile. All seven present.
- Review section: booth photo swapped for the storefront on-model shot, captioned; the booth shot moved to the wall's info block with its own caption, so no file appears twice.
- Three-price strip added above the mobile ladder; hidden at 1024+.
- H1 kept.
- Fonts non-blocking with a
<noscript>fallback; hero image preloaded;-400twins added to every srcset and used as the only source under 200px; the drawer and wall-info thumbnails, learn thumbnails and logo also dropped their 800/1600 candidates. mix-blend-mode: multiplyon every product-on-white image.
Deliberately not taken as written:
- 400-only for swatches and review photos. The critic asked for the 400 twin as the sole source for anything under about 300px. Wall swatches and review photos render at 261px on desktop, which is 522 device pixels on a 2x screen; a 400px-only source would be upscaled 1.3x on the product that is 66 percent of revenue. They keep
400wand800wwith exactsizes, so a 2.6x phone still downloads the 400 twin (the byte saving the critic wanted) while retina desktops get the 800. - 24px time on every section at 375, not only the hero. See assumption 8.
Lighthouse (mobile, simulated throttling, served from a local Python http.server, run on the final file)
Performance 100 · Accessibility 100 · Best practices 100 · SEO 100. FCP 1.0 s, LCP 1.8 s (the hero image, preloaded), Speed Index 1.0 s, TBT 0 ms, CLS 0.035 (the font swap). No render-blocking resources, no console errors. "Properly size images" waste fell from 959KB to 73KB. Remaining flags are the test server's missing compression and cache headers. Before this revision the same audit read 94 / 100 / 96 / 100 with LCP 2.9 s. Run with npx lighthouse@12; report at the session scratchpad lh3.json.