Brand & UI System Β· v3 marketing + v8 live auction

Fizook Style Guide

The single source of truth for Fizook.com and the Reverse Auction web app β€” colors, gradients, type, components, motion, and voice. Synced with fzk-new.html (the live auction, v8) and the marketing / account suite β€” index.html, auction-details.html, fizook-demo.html, fizook-register.html, fizook-vendor.html, fizook-history.html, fizook-profile.html (all v3). The v3 marketing release added the hero banner, gradient mesh, glassmorphic surfaces, gradient text, scroll-progress bar and in-sheet hold-flash. The v8 live-auction release expanded the bidder pool to 19 restaurants (distributed 8 / 8 / 3 across a 3-auction series) and introduced the battle ticker and the Live Top 3 podium. The hold tray remains 8 slots.

1. Brand & Personality

Fizook flips the auction model on its head β€” vendors compete to lower their price for everyday meals. The product needs to feel alive, fast, and friendly: bidders are dropping prices in real time, and users should always feel they are catching a deal.

Personality pillars

  • Energetic β€” saturated brand blue with a green "save" accent; pulses, flashes, drifting blobs, and falling-coin confetti reinforce momentum.
  • Trustworthy β€” clean Inter sans-serif, generous whitespace, soft shadows. Money words (price, savings) are bold and unambiguous; tabular numerals lock digits in place so prices don't shimmy.
  • Plain-spoken β€” short sentences, sentence case for body, action verbs on buttons. Never jargon.
  • Mobile-first β€” every layout works at 360px wide and scales up; touch targets are at least 36 Γ— 36 px.
  • Ambient motion β€” gradient meshes drift, blobs float, sparkles shimmer. Motion is decorative and calm, never distracting. Always respects prefers-reduced-motion.

Voice in one line

"Watch your wallet win." β€” emotional, benefit-led, present-tense. Marketing pages lean into the win; the live auction chants "Live Β· restaurants are dropping prices."

2. Color Palette

Every color is defined as a CSS custom property on :root. Reference the token name (e.g. var(--primary)) β€” never hard-code the hex.

Brand & surface

PRIMARY
--primary
#2481bc Β· brand blue
PRIMARY DARK
--primary-dark
#1a6494 Β· gradient end
BG
--bg
#0b1220 Β· dark base
SURFACE
--surface
#ffffff Β· cards, sheets
SURFACE 2
--surface-2
#f8fafc Β· subtle fills
SURFACE 3
--surface-3
#eef2f7 Β· scoped β€” auction-details only
BORDER
--border
#e5e7eb Β· 1px dividers

⚠️ --surface-3 currently lives only in auction-details.html β€” it's a setup-flow extension for nested summary rows. Don't paint other pages with it unless the rest of the suite adopts the token.

Text

TEXT
--text
#0f172a Β· primary text
MUTED
--muted
#64748b Β· secondary text

Semantic

SUCCESS
--success
#16a34a Β· "save", live
SUCCESS LIGHT
--success-light
#dcfce7 Β· pill background
DANGER
--danger
#dc2626 Β· ended, alerts
WARN
--warn
#f59e0b Β· paused state
ACCENT
--accent
#7c3aed Β· purple highlight

Color usage rules

  • Primary blue = identity + active CTA gradient.
  • Success green = price drops, savings, "live" status, BEST DEAL.
  • Danger red = auction ended, destructive actions, the "Live" word flash.
  • Warn orange = paused state, mid-action toasts.
  • Accent purple = standout secondary stat (Biggest savings); also one stop in nearly every brand gradient.

Gradient-accent palette (no token, used in compositions)

These hexes only appear inside gradients (hero banner, gradient text, scroll bar, animated held ring). They are not tokens β€” never reach for them in flat fills.

CYAN 400
#22d3ee
cyan accent Β· gradient start
VIOLET 400
#a78bfa
gradient mid (text)
PINK 500
#ec4899
gradient end Β· floating blob
PINK 200
#fbcfe8
soft gradient text end
CYAN 200
#a5f3fc
brand text mid Β· live-peek price
EMERALD 200
#a7f3d0
flash-green for price drops
CYAN 700
#0e7490
final-CTA gradient end

2b. Brand Gradients

Gradients are first-class brand assets in v3. Six canonical recipes show up across every page; pick the one that fits the surface and don't invent new ones.

HERO
linear-gradient(135deg, #0b1220, #1a6494 50%, #7c3aed 110%)
Marketing hero, live-auction banner, glass-card stage
GRADIENT TEXT
linear-gradient(135deg, #22d3ee, #a78bfa 50%, #fbcfe8)
Hero h1 highlight word Β· animated via fzGradShift
SCROLL BAR
linear-gradient(90deg, #22d3ee, #7c3aed, #16a34a)
3-px scroll-progress strip + held-ring border
PRIMARY CTA
linear-gradient(135deg, #2481bc, #1a6494)
btn-primary, active chip, vendor logos
SUCCESS CTA
linear-gradient(135deg, #16a34a, #15803d)
btn-success, BEST ribbon, sheet-hold-flash
FINAL CTA
linear-gradient(135deg, #16a34a, #15803d 50%, #0e7490)
Index final-cta block (green→teal)

Ambient mesh background

Page backgrounds use multi-layer radial gradients on body plus a slowly-drifting overlay on body::before (animated via fzMeshShift, 22 s loop). Replaces the old full-page background image β€” same depth, no asset weight.

/* body */
background:
  radial-gradient(900px 500px at 10% -10%, rgba(124,58,237,.10), transparent 60%),
  radial-gradient(900px 500px at 110% 0%, rgba(36,129,188,.12), transparent 60%),
  radial-gradient(700px 400px at 50% 110%, rgba(22,163,74,.06), transparent 70%),
  #f8fafc;
background-attachment: fixed;

Composite tints (for cards on the mesh)

  • Status / feed cards β€” overlay radial-gradient(160% 80% at 0% 0%, rgba(36,129,188,.04), transparent 60%) to blend onto the mesh without flattening.
  • Stat tiles β€” linear-gradient(180deg, rgba(36,129,188,.05), rgba(124,58,237,.05)) with a 14 % border tint.
  • Feed-row hover β€” linear-gradient(90deg, rgba(36,129,188,.06), rgba(124,58,237,.06)) swept in plus a 2 px translateX.

Scroll-progress bar

Fixed 3-px stripe at the top of every page (z-index: 90). JS scales width from 0 % to 100 % as the user scrolls. Same gradient as the held-tray ring so the two read as a family.

3. Typography

Fizook uses Inter as the single UI typeface β€” loaded via Google Fonts at five weights (400 / 500 / 600 / 700 / 800). Code samples use JetBrains Mono. Set the base via the html, body font-family.

Font stack

font-family: 'Inter', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;

Weight scale

Regular drop
400 Β· body, descriptions
Medium drop
500 Β· labels, sub copy
Semibold drop
600 Β· chips, status labels
Bold drop
700 Β· headings, buttons, prices
Heavy drop
800 Β· brand, hero, big numbers

Type scale

H1 / Hero2.1rem Β· 800
Catch the best deal.
H2 / Section1.4rem Β· 800
Section title
H3 / Sub1.05rem Β· 700
Sub-section heading
Body.95rem Β· 400
Body copy used for descriptions, modals, and helper text.
Status1rem Β· 700
Live Bidders are dropping Prices!
Big price1.45rem Β· 800
$8.49
Caption.78rem Β· 600
Caption / meta text
Eyebrow.72rem Β· 700 caps
Eyebrow label

Capitalization rules

  • Title Case for buttons, statuses, and CTA copy ("Hold Offer", "Pick the Best Deal!").
  • UPPERCASE + letter-spacing for tiny eyebrow labels (stat keys, ribbons, BEST DEAL).
  • Sentence case for descriptions and toasts ("Auction reset", "You can hold at most 6 offers").

4. Spacing & Radius

Spacing follows multiples of 4 px. Radius is tokenized so cards, buttons, and pills feel consistent.

Border-radius tokens

6px
--radius-button Β· all buttons & chips
10px
--radius-sm Β· stat tiles, inputs
14px
--radius Β· cards, feed, sidebar
20px
--radius-lg Β· status hero, sheet
pill
999px Β· badges, ribbons, progress

Spacing rhythm

TokenUseSample
4pxTight gaps inside compact components (chip icon→text)gap:4px
6–8pxStat tiles, button padding, dense gridspadding:8px
10–14pxCard padding, gaps between cardspadding:12px 14px
16–24pxSection padding, hero edgespadding:16px
24–48pxHero / page-top breathing roompadding:48px 24px

5. Shadows & Elevation

Three discrete elevation levels. Hover lifts elements by 1–4 px and bumps to the next shadow.

Resting
--shadow-sm Β· 0 1px 2px / .06
Lifted
--shadow Β· 0 4px 16px / .08
Modal
--shadow-lg Β· 0 16px 40px / .18

6. Buttons

All buttons use .btn as the base, then layer a variant. Border-radius is locked at 6 px. Padding is 10px 14px; icons live to the left with a 6 px gap.

Primary & success (CTAs)

Ghost (neutral actions)

Destructive

Disabled

Muted (series limit)

A muted button looks disabled (gray-on-gray) but stays clickable. It's used on the Start button after the user has run the 3-auction series limit β€” clicking it opens the series-limit popup instead of starting another auction.

Success with shimmer sweep (v3)

In v3 the dock's Start button (and every btn-success on the marketing pages) gets a white-gradient gloss that sweeps left-to-right on hover via a ::after pseudo-element. Hover this to see it.

Light-on-dark ghost (over hero gradient)

btn-ghost-light replaces btn-ghost when the surface is dark (hero, final CTA, live-peek). 16 % white fill, 30 % white border.

Sizing

  • Default β€” 10–11 px / 14–16 px padding, .88–.95 rem font.
  • .btn-lg β€” 13 px / 20 px padding, 1 rem font. Used for hero CTAs.
  • .btn-block β€” full-width inside its container; standard for the login form.

Social sign-in

Same base button, branded fill colors. Hover lifts 2 px and scales the icon 1.15.

Hover lifts buttons 1 px (translateY(-1px)). Disabled state drops opacity to 55% and removes lift. btn-success in v3 has a 0.6 s shimmer sweep on hover; btn-success on the dark hero uses a heavier 0 6px 18px shadow.

7. Chips & Filters

Chips drive filter / sort selection. The active chip switches to the primary gradient. Same 6 px radius as buttons for visual consistency.

8. Form Controls

Inputs are minimal: 1 px border, 8 px radius, 8–10 px padding, white surface. No focus ring is custom-styled β€” rely on the browser's default outline.

9. Badges, Pills & Status

Tiny pills communicate state in-line: feed kind, savings, trend direction, ribbons. They share the 999 px pill radius.

Feed badges

Info Drop

Trend & savings pills

35% off Β· save $3.50 Awaiting first drop 28% off

Ribbons

BEST DEAL

Live status indicator

The status text in the Fizook Auction card has four shapes β€” empty before first start, the running composition with a flashing red word + flashing red hand, paused, and the multi-part ended composition.

Live Bidders are dropping Prices!
Paused
Ended! Choose or Hold Any Deal!
The ended state is a three-piece composition β€” .ended-static (solid red "Ended!"), .ended-flash (solid green action phrase), and .hand-bounce (green hand icon bouncing Β±4 px). Every 7 s the action phrase swaps between "Choose or Hold Any Deal!" and "or, Run Another Fizook Auction!". The endedFlash keyframe is defined but currently unused β€” re-enable it by adding animation:endedFlash 1s ease-in-out infinite to .ended-flash.

Headline stat tiles

Bidders
6
Best price now
$5.49
Biggest savings
$4.20
Held offers
2 / 6

10. Cards

Cards are the primary container pattern. White surface, 14 px radius, 1 px border, soft shadow. Hover lifts and tightens the border.

Bidder card (default)

Bidder 1 Restaurant

5 offers Β· best showing
meal img

Crunchwrap Supreme

$6.49$8.49
24% off Β· save $2.00

Bidder card (best deal)

Bidder 3 Restaurant

5 offers Β· best showing
meal img

Whopper

$4.49$6.99
36% off Β· save $2.50

Held card

meal img

Quesadilla

Bidder 2 Restaurant
$5.99
Slot 2
empty
The bidder grid is repeat(4, 1fr) on tablet and up. The live auction draws from a pool of 19 restaurants split across a 3-auction series: auction 1 renders 8 cards (2 rows Γ— 4), auction 2 renders another 8 cards, and auction 3 renders the remaining 3 cards (a partial row). Each card always carries the same 14 px radius / soft-shadow chrome β€” the layout adapts, the chrome does not. On phone (≀ 559 px) cards collapse to a logo-only grid; the full detail (meal, prices, actions) lives in the bottom sheet that opens on tap.

10b. Marketing Patterns

v3 introduces a family of high-energy marketing surfaces β€” used on the live auction (a slim banner above the status card) and on the homepage (a full split hero, animated counters, a live peek demo, value-prop and audience cards, a green final CTA, and a dark footer). All share the same gradient + ambient-motion language.

Live-auction hero banner (fzk-new v8)

Gradient block with two floating colored blobs (cyan + pink, blurred 48 px), 5 falling-coin emoji and 3 drifting sparkles. The status card below it is lifted with a -40 px bottom margin so it floats over the banner edge β€” creates a single composition. The headline and sub copy are the v8 "battle" framing; the marketing homepage uses a different hero (see below).

Live Β· 19 restaurants fighting for your order

Watch them battle for you.

Nineteen bidders. Three rounds. They're undercutting each other in real time β€” sit back, watch the war, then snap up the winner.

Recipe: hero gradient bg + ::before/::after blurred blobs (animated fzFloatA 9 s / fzFloatB 11 s) + absolutely-positioned .fz-coin spans (fzCoinFall 8–13 s, staggered) + .fz-spark spans (fzSparkleDrift 7 s). Inner stack: pill tag β†’ h1 with .grad text β†’ max-560 px paragraph.

Marketing homepage hero (index.html)

The homepage uses a split hero β€” left pitch + right glass login card β€” and softer copy. The tag pill swaps to "Live Β· restaurants are bidding right now" and the headline reads "Restaurants compete for your business.". The lead paragraph below it is: "Fizook is a reverse auction for everyday meals. Tell us what you want, when you want it β€” hundreds of restaurants drop their prices in real time until your wallet wins." (The homepage demo widget renders 6 tiles as a sample; the marketing claim is the full marketplace, and the live auction itself runs the 19-bidder pool per series.)

Animated stat strip (homepage)

Four tiles with gradient-text counters that animate 0 β†’ target on scroll-into-view (IntersectionObserver). Color-coded: blue/purple (default), green, cyan, amber.

2.4M
Meals auctioned
142K
Active diners
$9,800
Avg lifetime savings
32%
Avg meal savings

Feature card (icon rotates on hover)

Used on the homepage "Why Fizook" grid. Hover lifts the card 4 px and rotates the gradient icon -8Β° + scale(1.08). A radial blue blob sits in the upper-left corner inside ::before.

Reverse auction

Vendors compete for your order β€” prices only go down.

Real-time drops

Watch the live activity feed as bidders undercut each other.

Hold up to 8

Stockpile favorites across 3 auctions, then pick the winner.

Audience-picker card

Three cards on the homepage segment users into Diner / Vendor / Returning user. Same hover lift as the feature card; arrow icon nudges right 4 px on hover.

Final CTA block

Closes every long-form marketing page. Green-to-teal gradient with a soft white halo radial in the upper-left.

One auction is all it takes.

See your wallet win β€” then come back for dinner tomorrow.

Dark footer with social orbs

Sits flush at the bottom of every marketing page. #0b1220 background, white headings, 86 % opacity links. Social icons are 34 px circles that lift 2 px and switch to a cyan-tinted background on hover.

10c. Glassmorphic Surfaces

Cards that sit on top of the gradient hero use frosted-glass styling β€” semi-transparent white background, backdrop blur, subtle white border, and a soft halo behind the panel. Two patterns: a light glass card for forms (homepage login) and a dark glass pill for inline stats on the hero.

Light glass card (login)

Welcome back

Sign in to start an auction.

Recipe: background: rgba(255,255,255,.94), backdrop-filter: saturate(1.4) blur(10px), border: 1px solid rgba(255,255,255,.6), --shadow-lg, plus a ::before at inset: -1px with the cyan→purple→pink halo blurred 14 px at 55 % opacity. Inputs: 10 px radius, 36 px left padding for an absolutely-positioned icon.

Dark glass pill (pitch stat)

$87 avg saved/year 32% off per meal 90s start to deal
10 % white background + 16 % white border + backdrop-filter: blur(8px). The strong uses one of the soft gradient-accent colors (#a7f3d0, #a5f3fc, #fbcfe8) so the number pops against the dark hero.

10d. Live Auction v8

The v8 live auction (fzk-new.html) doubled the bidder pool and added two new spectator-mode surfaces on top of the v3 chrome: a battle ticker that scrolls live commentary across the screen, and a Live Top 3 podium that surfaces the cheapest three bidders at any moment. The status hero also grew from 4 stats to 6.

Bidder-pool distribution

  • Pool size: 19 restaurants total.
  • Distribution: auction 1 renders 8 cards (2 rows of 4), auction 2 renders 8 more, auction 3 renders the remaining 3 (partial row).
  • Grid: repeat(4, 1fr) at β‰₯ 560 px; logo-only collapse at < 560 px (taps open the bottom sheet for detail).
  • Headline-card title: "Your Fizook Auction" (the live status text appends after it).
  • Round label (top-right of the status card): "Round 1 of 3" β€” drives off the same series counter as the Start-button mute.

Battle ticker

A sportscaster-style strip that sits between the hero banner and the status card. The left chip is a red "ON THE WIRE" label with a pulsing dot; the right belt is a CSS-driven horizontal scroll (.fz-ticker-belt with a 30 s linear-infinite translateX, duplicated content for seamless wrap). JS rewrites the belt with the latest 8–12 events every few seconds.

Item kinds: .drop (green bolt β€” a price cut), .lead (amber trophy β€” leaderboard swap), .war (cyan fire β€” multi-bidder skirmish), .event (purple bolt β€” lifecycle: start/pause/end). Vendor names use .ti-vendor (cyan-200 weight 700); prices use .ti-price (emerald-200 weight 800, tabular numerals). Hover (or prefers-reduced-motion) pauses the belt via .fz-ticker-belt.paused.

Live Top 3 podium

Three glassmorphic tiles sit on the gradient hero. Grid order is silver β€” gold β€” bronze so the tallest gold tile lives in the middle (classic podium). Each tile shows medal pill β†’ square logo β†’ vendor β†’ meal β†’ live price. When a rank changes hands the tile flips and the medal glows briefly.

Empty state (.fz-pod.empty) hides medal / vendor / price and dashes the border. Medal pills: gold = amber gradient, silver = slate gradient, bronze = darker amber gradient. Prices use cyan-200 (#a5f3fc) so they pop against the dark hero, matching the live-peek price treatment on the homepage.

6-stat headline strip

The status card's stat row carries six tiles (was four in v2). On phone they restack to 3-up, then 2-up at ≀ 419 px. After the auction ends, Best price now and Biggest savings become clickable shortcuts that open the offer sheet.

Offers available
37
Bidders
19
Best price now
$4.49
Biggest savings
$5.50
Auction rounds
1 of 3
Held offers
2 / 8
Order is fixed β€” don't reshuffle. Color accents: Bidders = blue (--primary), Best price now = green (--success), Biggest savings = purple (--accent). The other three tiles use the default text color so the eye lands on the money tiles first.

Controls dock β€” buttons

Five buttons in fixed order: Start (success), Pause (ghost, disabled at rest), Reset (ghost), Settings toggle (ghost, phone-only β€” opens the Rounds / Speed panel), Clear All (red ghost fa-undo). On phone the five spread to equal width with a 10 px gap. The settings panel is always visible on desktop and toggled on phone via the sliders icon.

10e. Setup & Account Patterns

The setup flow (auction-details.html), signup pages (fizook-register.html, fizook-vendor.html), and account suite (fizook-profile.html, fizook-history.html) share a family of form patterns that aren't used on the auction or marketing pages. They follow the same tokens and motion language; only the components are new.

Pill toggle group

Mutually-exclusive segmented control β€” Delivery vs. Pickup, Solo vs. Group, Daily vs. One-off. Each pill is a .toggle wrapping a hidden radio plus .toggle-bg and .toggle-label. Active pill swaps to the primary gradient. Six-pixel radius and small padding keep them compact.

Day-of-week row

Used by the vendor signup form for "what days are you bidding". Each button is a 46 px minimum-width 10 px-radius pill. Three labels per button: .day-abbr (Mon β€” default), .day-full (Monday β€” wider viewports), .day-off-mobile/-desktop (the offset state).

Hour grid

Auto-fill grid (minmax(64px, 1fr)) of 60-minute slots. Selected hours flip to the success gradient (green = "yes, bidding open").

10am
11am
12pm
1pm
2pm
3pm
5pm
6pm
7pm
8pm

Upload preview boxes

Square (14 px radius) for cover images, circle (.is-circle) for logos/avatars. Dashed 2 px border, surface-2 fill, hover lifts and turns the border brand-blue. Replaces native <input type="file"> chrome.

Cover image
1280 Γ— 720
Logo

Live preview card (vendor signup)

A right-rail card that mirrors a real bidder card in miniature so the vendor sees how their listing will appear. Updates as they edit menu / pricing fields.

meal img
Your Restaurant

Crunchwrap Combo

$5.99$8.99

Tips card

Dark gradient block with a soft cyan radial in the upper-right corner. Always carries an icon-titled h4 and a bulleted list. Used on auction-details and fizook-vendor to coach the user mid-form.

Tips for first-time bidders

  • Set a comfortable floor β€” your card opens the bidding, not your wallet.
  • Pick at least three days of the week so auctions actually find you.
  • Compelling photos win first-time diners. Daylight, no filters.

Connected accounts list (profile)

One row per OAuth provider β€” icon tile, name + sub-label, and a pill that shows the connection state. .conn-state.on uses the success-light pill; .off uses the muted-fill pill.

Google

lcraigwilson@gmail.com
Connected

Apple

Not connected
Off

Danger zone

Soft-red bordered block that holds destructive actions (delete account, leave vendor program). Heading + explanation + a single red button. Always last on the profile page so it's hard to hit by accident.

Danger zone

Deleting your account erases your auction history and any held offers. This can't be undone.

Sticky save bar

A floating bar that slides in from the bottom the moment the user edits any field (and out when they save or revert). Carries a one-line summary on the left and the action buttons on the right.

3 unsaved changes β€” display name, email, marketing emails.

Receipt tile (auction history)

Dark gradient card that summarizes a closed auction β€” eyebrow ("Auction #1842"), meal name, vendor, then a row stack of "Was / Now / Saved" with a totaled "You paid" at the bottom. Used inside the history detail sheet.

Auction #1842 Β· 2026-05-29
Crunchwrap Combo
Cravings
Was$8.99
Saved$3.50
You paid$5.49
Token note: auction-details.html defines an additional surface token --surface-3: #eef2f7 for tertiary fills inside the multi-step setup form (e.g. nested cards, summary rows). It is scoped to that page β€” don't propagate it elsewhere unless the rest of the suite adopts it.

11b. Activity Feed

A live, prepended list of price drops and system events sits inside a card titled "Live activity". Drop rows are clickable shortcuts into the offer sheet; info rows are read-only.

  • Drop Bidder 4 Restaurant is now offering Base Meal at $4.99just now
  • Drop Bidder 2 Restaurant is now offering Quesadilla at $5.492s
  • Info Auction started14s
  • Info Held Whopper from Bidder 3 Restaurant22s
  • Info Auction ended. Final prices locked.31s
Drop rows get the .feed-clickable class β€” hand-pointer cursor, soft hover background, and a one-line "Tap to view this deal" tooltip. A single delegated click handler reads the row's data-bi / data-id and calls openSheet(bi, id). Info rows (auction lifecycle messages, hold / accept confirmations) stay non-interactive.

v3 enhancements

  • Hover sweep β€” drop rows now fade in linear-gradient(90deg, rgba(36,129,188,.06), rgba(124,58,237,.06)) on hover and slide right 2 px. Makes the row read like a button without changing the markup.
  • Card halo β€” the feed card itself gains a soft purple radial in the upper-right corner so it doesn't read as a flat white tile against the gradient mesh.
  • Bolt shimmer β€” the section heading's fa-bolt icon pulses its drop-shadow from 4 px to 12 px every 2.4 s (fzBoltShimmer keyframe) so the "Live activity" header always reads as alive.

12. Motion

v2 motion communicates state (live, paused, ended, best). v3 layers on a second class of ambient motion β€” slow, calm, looping β€” that says "this product is alive" without demanding attention. State-motion is fast (≀ 1 s); ambient motion is slow (1.6 s – 22 s). Every long-running animation is gated by prefers-reduced-motion.

State motion (v2 β€” communicates a moment)

@keyframes pulse Β· 1.6s
Live status indicator
Live
@keyframes liveWordFlash Β· 1s
"Live" red flash (running)
Same liveWordFlash Β· 1s
Pointing-right hand (running)
@keyframes handBounce Β· 1s
Pointing-down hand (ended)
bestPulseRing + bestBgFlash Β· 1.1s
Best-deal card pulse
Choose or Hold Any Deal!
setInterval Β· 7s
Ended-phrase swap (JS, not CSS)

Ambient motion (v3 β€” sets the mood)

All v3 keyframes are namespaced with the fz prefix to avoid collisions with v2 animations. They drift, breathe, and shimmer; none of them snap or bounce.

@keyframes fzBoltShimmer Β· 2.4s
Live-activity bolt drop-shadow halo
3 / 8
@keyframes fzCounterPulse Β· 2.4s
Held-counter outward ring
@keyframes fzChipGlow Β· 2.6s
Active sort-chip outward ring
1
2
3
4
@keyframes fzHeldShift Β· 12s
Held-tray cyan→purple→pink ring
@keyframes fzMeshShift Β· 22s
Page mesh-background drift
your wallet wins
@keyframes fzGradShift Β· 8s
Hero gradient-text position drift
πŸ’°
@keyframes fzCoinFall Β· 8–13s
Falling coin confetti (5 staggered)
✨
@keyframes fzSparkleDrift Β· 7s
Hero-banner drifting sparkles (3)
@keyframes fzFloatA Β· 9s, fzFloatB Β· 11s
Hero-banner blurred blobs
@keyframes fzPulse Β· 1.6s
Banner tag pulse-dot (renamed pulse)
.fz-reveal β†’ .in
.fz-reveal Β· 0.55s ease
Scroll-into-view fade + 16 px rise
@keyframes logoSwap
@keyframes logoSwap Β· 0.45s
Phone logo-grid card swaps

Marketing-only (homepage)

  • @keyframes slideInL Β· 0.7s β€” hero pitch fades in from -24 px on the X axis.
  • @keyframes slideInR Β· 0.7s β€” login card mirrors the same motion from +24 px.
  • @keyframes cardIn Β· 0.6s β€” every section.block fades up 20 px on first paint.
  • @keyframes coinFall, floatA, floatB, gradShift, pulse β€” unprefixed twins of the auction-page fz-* versions, used inside the homepage hero.
  • Counter animation (JS) β€” data-count-to tiles tween 0 β†’ target on IntersectionObserver entry. No CSS.

Page-scoped (setup & account suite)

These keyframes live on a single page each and are intentionally not fz-prefixed β€” they're local flourishes, not part of the shared design language. Treat them as one-offs; promote a name into the fz namespace before reusing it on a second page.

  • auction-details.html β€” welcomeShift (gradient eyebrow drift), greetSwap (rotating greeting), wave (waving hand), beamDrift (light beam across stepper), sparkleDrift, startRipple / startWiggle (Start-button attention), bidderBounce (preview tiles), fadeIn.
  • fizook-demo.html β€” pricePop (number flash on price drop), hypeScroll (testimonial belt), perkIn (perk-card stagger), sparkBurst, beamDrift.
  • fizook-history.html / fizook-profile.html β€” avatarPulse (profile avatar halo), bounceX (page-tab indicator).

Defined but currently unused

  • @keyframes endedFlash β€” green ↔ light-green color/opacity loop. Defined in CSS; .ended-flash intentionally renders solid right now. Re-enable by adding animation:endedFlash 1s ease-in-out infinite to .ended-flash.

Hover micro-interactions

  • Buttons / chips β€” translateY(-1 to -2 px) on hover, transition 150 ms ease.
  • btn-success (v3) β€” white-gradient gloss sweeps left β†’ right via a ::after pseudo, 600 ms ease.
  • Bidder cards β€” non-best cards lift 4 px, gain a translucent purple 0 0 0 2px ring, and bump to a 0 16px 30px shadow.
  • Feature / audience cards β€” lift 4 px, swap to --shadow, and rotate the gradient icon -8Β° + scale(1.08); arrow icon nudges 4 px right.
  • Sheet open β€” slide from bottom (mobile) or scale-in (desktop), 300 ms ease.
  • Activity feed drop rows β€” gradient sweep + translateX(2 px), hand-pointer cursor.
  • Top-nav dropdowns β€” submenu fades in on hover; an invisible 6 px bridge keeps it open while the cursor crosses the gap.
  • Footer social orbs β€” lift 2 px and switch background to rgba(34,211,238,.25) on hover.

13. Iconography

Fizook uses Font Awesome 4.7 (the classic CSS-class API). Icons are sized via parent font-size and inherit color via currentColor.

fa-bolt
fa-money
fa-bookmark
fa-bookmark-o
fa-check
fa-times
fa-play
fa-pause
fa-refresh
fa-undo
fa-sliders
fa-arrow-down
fa-percent
fa-dollar
fa-tag
fa-th-large
fa-line-chart
fa-user
fa-user-plus
fa-sign-out
fa-bars
fa-hand-o-right
fa-hand-o-down
fa-clock-o
fa-trash-o
fa-rocket
fa-shield
fa-cutlery
fa-id-card-o
fa-cogs
fa-arrow-right
fa-envelope-o
fa-lock
fa-eye
fa-sign-in
fa-play-circle
fa-google
fa-facebook-f
fa-apple
fa-twitter
fa-instagram
fa-linkedin
fa-paint-brush
fa-snowflake-o

Decorative emoji (banners only)

Used only as drifting confetti/sparkle inside the marketing hero (and the v3 in-auction banner). Always wrapped in aria-hidden="true". Do not use emoji inside body copy, toasts, or buttons.

β†’ Browse alternatives in the Floating Emoji Picker β€” preview swaps live on a hero banner and copy the snippet.

14. Voice & Tone

Fizook talks like a calm but excited friend who just saw a great deal. Always present-tense, always plain English. Punctuation can be expressive but doesn't need to be loud.

Do

  • Lead with the verb: Hold, Accept, Release, Pick.
  • Use exclamations sparingly, only for in-the-moment energy.
  • Be specific with numbers: "save $3.50", "2 / 6 held".
  • Match red text only to red states (ended, danger).
  • Keep messages under 70 characters when possible.

Don't

  • Use jargon ("liquidity", "auction tick", "render pass").
  • Stack exclamations: "Hurry now!! Save big!!".
  • Apologize ("Sorry, you can only hold 6"). State the rule plainly.
  • Pile on emoji β€” one is plenty in a toast.
  • Use placeholder copy in production ("Sub Link 1").

Reference copy library β€” live auction (v8)

Hero banner tag: "Live Β· 19 restaurants fighting for your order"
Hero banner headline: "Watch them battle for you." — second half wears the cyan→violet→pink gradient text.
Hero banner sub: "Nineteen bidders. Three rounds. They're undercutting each other in real time β€” sit back, watch the war, then snap up the winner."
Status card title: "Your Fizook Auction" β€” the dynamic status text appends after it (see status states below).
Round counter: "Round 1 of 3" β€” top-right of the status card; tracks the current series position.
Live Top 3 podium title: "Live Leaderboard" with sub-label "Top 3 right now".
Battle-ticker label: "On the wire" (red pill, left of the scrolling belt).
Battle-ticker seed items (pre-start): "Press Start to ignite the bidding war" Β· "19 restaurants are warming up their offers" Β· "Up to 50% off β€” they want this order"
Toolbar helper: "Tap a card for details Β· Hold up to 8 offers"
Status (pre-start / reset): empty β€” the status text is blank until the user clicks Start.
Status (running): "Live Bidders are dropping Prices!" β€” only the word "Live" and the hand icon flash red.
Status (paused): "Paused"
Status (ended, phrase A): "Ended! Choose or Hold Any Deal! "
Status (ended, phrase B β€” swaps every 7 s): "Ended! or, Run Another Fizook Auction! "
Sheet hold flash (v3): "Deal N of 8 Held" β€” fades in for 3 s after the user clicks Hold from inside the sheet.
Held tray heading: "Offers you're holding N / 8"
Toast (success): "Offer held" Β· "Accepted Whopper for $4.49 πŸŽ‰"
Toast (warn): "You can hold at most 8 offers" Β· "Already in your held list"
Empty state: "Slot 2 empty"
Activity feed (drop): "Bidder 4 Restaurant is now offering Base Meal at $4.99" β€” clickable.
Activity feed (info): "Auction started" Β· "Auction paused" Β· "Auction reset" Β· "Auction ended. Final prices locked." Β· "Held Whopper from Bidder 3 Restaurant" Β· "βœ“ Accepted Whopper from Bidder 3 Restaurant at $4.49"
CTA labels: "Start", "Pause", "Reset", "Hold", "Accept", "Release", "Release all", "Yes", "Cancel"
Series-limit popup: Heading "Auction Series Complete" Β· Body "You've reached the limit of 3 auctions per series. From here you can either pick a deal from the offers you've held, or start a brand new auction series." Β· Sub-title "Start A New Auction Series?"

Reference copy library β€” marketing (index.html)

Topbar live ticker (β‰₯ 1100 px): "1,284 auctions running right now"
Hero tag: "Live Β· restaurants are bidding right now"
Hero headline: "Restaurants compete for your business."
Hero lead: "Fizook is a reverse auction for everyday meals. Tell us what you want, when you want it β€” hundreds of restaurants drop their prices in real time until your wallet wins."
Pitch stats: "$87 avg saved/year" Β· "32% off per meal" Β· "90s start to deal"
Login card: "Welcome back" / "Sign in to start an auction or check your held offers." / "Don't have an account yet? Become a Fizook user β†’"
Final CTA: "One auction is all it takes." with paired buttons "Run an auction" + "How it works"

14b. Auction Series Logic

A "series" is up to 3 sequential auction runs. Held deals carry across runs so the user can stockpile favorites before deciding. After three runs, the Start button mutes and a popup gates a fresh start. v8 widened the bidder pool to 19 restaurants split across the series β€” 8 / 8 / 3 β€” while keeping the hold tray at 8 slots.

  • Auction 1 β€” Start β†’ run β†’ end. Eight bidders compete. User can hold up to 8 deals.
  • Auction 2 β€” Start again β†’ run β†’ end. Eight new bidders compete; held deals from auction 1 remain in their slots; new ones can be added.
  • Auction 3 β€” Start again β†’ run β†’ end. The final three bidders compete (partial row in the grid). Same hold rules.
  • Series limit hit β€” Start button gets the .btn-muted style (gray-on-gray, no shadow) but stays clickable. Clicking it opens the series-limit popup.
  • Yes in the popup β€” wipes state.heldIds, resets state.auctionCount to 0, un-mutes Start, then immediately runs auction 1 of a fresh series.
  • Cancel / Γ— / backdrop β€” closes the popup; nothing changes.
  • Reset button β€” only resets the current auction's progress. auctionCount is preserved, so once you've burned 3 you can't restart by pressing Reset.
  • Clear All button (red fa-undo in the dock) β€” full wipe: feed, held deals, auction state, AND auctionCount. Returns the page to its just-loaded state.
  • In-sheet hold flash (v3) β€” every successful Hold from inside the sheet shows "Deal N of 8 Held" centered over the sheet body for 3 s; the sheet stays open so the user can hold another offer immediately.

15. Layout & Breakpoints

All pages center inside a max-width:1280px container with 16 px gutters. The grid uses display:grid with explicit column counts at each breakpoint. v8 holds the bidder grid at repeat(4, 1fr) on tablet+: auction 1 and 2 each render 8 cards (2 rows of 4) and auction 3 renders the remaining 3 (partial row) from the 19-restaurant pool. The held tray stays 8-up on tablet+.

Breakpoints

≀ 419.98pxTiny portrait phone β€” homepage hero h1 drops to 1.6 rem, pitch stats stack full-width, login card padding tightens to 18 / 16 px, 6-stat headline strip restacks to 2-up.
≀ 559.98pxPhone (portrait) β€” bidders 4-up logo grid (no body), held offers 4-up wrap to 2 rows, dock buttons full-width equal columns, sheet from bottom, hero banner padding tightens, drifting sparkles hidden, podium tiles stack to 1-up.
≀ 759.98pxTablet portrait floor β€” 6-stat headline strip restacks to 3-up.
orientation:landscape + ≀ 500 px tallPhone (landscape) β€” bidders 4 Γ— 2 with full meal/price/actions detail, held offers single row of 8 (compact thumbs and buttons), hero-banner coins + sparkles hidden, hero h1 clamps to 1.2–1.6 rem, battle ticker pauses scroll on hover.
β‰₯ 560pxTablet portrait β€” bidders 4-up at full detail, held offers 8-up, podium reaches its full 3-tile silver-gold-bronze layout.
β‰₯ 640pxStats grid expands to 4–6 columns.
β‰₯ 680pxDock packs Start/Pause/Reset to the left, settings inline (no overflow toggle).
β‰₯ 760px6-stat headline strip hits its full 6-up row.
β‰₯ 900pxTop nav switches to horizontal, dropdowns float on hover with an invisible 6 px bridge, sheet centers as a modal.
β‰₯ 960pxBidders 4-up at full detail, held grid 8-up, setup/vendor forms switch to a 2-column form + live-preview rail.
β‰₯ 980pxHomepage hero switches to a 2-column split (1.1fr pitch + 420 px login card).
β‰₯ 1100pxTopbar shows the live-status ticker ("1,284 auctions running right now").
β‰₯ 1280pxContainer hits its max-width; outer gutters grow with the viewport.

Container rules

  • Page-level wrappers: max-width:1280px; margin:0 auto; padding:0 16px;
  • Section vertical rhythm: 14–32 px gap between sections, 24 px inside cards.
  • .wrap on marketing pages uses margin:-40px auto 0 to lift the first section over the gradient hero edge β€” same depth trick as the v3 banner.
  • Smooth scroll: scroll-behavior:smooth on html,body for in-page anchor links.

Z-index stack

  • z-index: 50 β€” sticky topbar.
  • z-index: 60 β€” sticky bottom dock.
  • z-index: 90 β€” scroll-progress bar (sits above everything except modals).
  • z-index: 100+ β€” sheet backdrop and modal panels.
  • z-index: -1 β€” body::before animated mesh overlay (so it sits behind every painted element).

16. Accessibility

Ambient motion and gradient text are pretty, but they have to fail gracefully for users who can't or don't want them. v3 adopted these baselines on every new surface β€” apply them to anything new.

Reduced motion

Every long-running ambient animation is wrapped in a prefers-reduced-motion media query that sets animation:none. Users keep the colors and layouts; they lose the looping movement.

@media (prefers-reduced-motion: reduce) {
  body::before,
  .fz-hero-banner::before, .fz-hero-banner::after,
  .fz-coin, .fz-spark,
  .chip.active, .feed-head h3 i,
  .held .held-grid, .held-counter,
  .fz-hero-banner h1 .grad {
    animation: none !important;
  }
}
  • State-motion (live pulse, ended bounce, BEST ring) also opts out so an ended auction looks like a static red title.
  • Gradient text falls back to flat color when its position-shift is killed β€” verify contrast still passes WCAG AA.

ARIA & semantics

  • Sheet hold flash β€” wraps the badge in role="status" + aria-live="polite" so screen readers announce "Deal 3 of 8 held" without interrupting.
  • Decorative emoji + blobs β€” every coin, spark, and pulse-dot is aria-hidden="true". Same for the floating ::before/::after blobs (no markup needed).
  • Banner regions β€” every marketing section uses aria-label ("Welcome to Fizook", "Live auction welcome", "Sign in", etc.) so the page outline is meaningful.
  • Active nav β€” the current top-nav link uses aria-current="page" in addition to the visual .active class.
  • Forms β€” every input has a <label>; the password reveal toggle uses aria-label="Show password"; autocomplete is set on email + password.
  • Inputs gain a 3 px focus ring in the brand blue (0 0 0 3px rgba(36,129,188,.18)) β€” never override the browser's default outline without supplying one of your own.

Color contrast

  • Body text on white surface: #0f172a / #fff β€” 17:1, well above AA.
  • Muted text on white: #64748b / #fff β€” 4.7:1, AA-passing for body but not for headlines. Keep --muted at β‰₯ 14 px.
  • White text on the hero gradient: paint the darkest stop (#0b1220) where the headline sits β€” never let h1 land on the brightest violet stop.
  • Don't rely on red-vs-green to communicate state alone β€” pair every color cue with text or an icon (already done for live / paused / ended).

Touch targets

  • Buttons, chips, sheet-close, password toggle β€” all β‰₯ 36 Γ— 36 px.
  • Activity-feed drop rows β€” full-width row is the hit area; the inline link inside isn't relied on.
  • Footer social orbs β€” 34 Γ— 34 px circles inside an inline-flex hit area.