---
version: alpha
name: pearl-and-pop-design
description: "A pale bubblegum-lavender canvas (#fbeef8) with deep plum ink (#3a1e35), vivid bubblegum pink (#ff4fa0) and turquoise (#0fb8a6) as the two brand accents, reserved for UI, never for the drinks themselves. Baloo 2 carries every headline at weight 700, round and bubbly on purpose; Inter carries anything meant to be read quickly. The homepage's whole first act is four cups actually filling, pearls first, tea second, straw last, gated by scroll."
---
## Brand Positioning
Pearl & Pop exists because most boba shop sites either go full pastel-Y2K noise (glitter GIFs, bounce-everything) or overcorrect into the same moody dark-glass template every other food-and-drink concept in this gallery already uses. Neither is honest about what the product actually is: four specific drinks, made a specific way, that happen to be genuinely fun to watch get made. So the homepage doesn't describe the drinks, it makes them, in front of you, on scroll: tapioca pearls settle into the bottom of a cup, the tea rises above them in the drink's real color, a straw drops in when it's ready. If a component performs "fun" with confetti or a mascot instead of showing an actual step of making a real drink, it doesn't belong here.
colors:
accent: "#ff4fa0"
accent-alt: "#0fb8a6"
ink: "#3a1e35"
ink-muted: "#6f4d68"
canvas: "#fbeef8"
## Logo / Wordmark System
The mark is a cup in profile: a trapezoid outline (wider at the rim, narrower at the base, the real shape of a boba cup), three small filled circles at the bottom for pearls, and a straw entering at an angle through the lid line. It is not a generic drink icon, it's a literal miniature of the homepage's own signature cup illustration, frozen at "ready to drink."
```svg
```
- **Lockup**: mark, then a `0.5rem` gap, then "Pearl & Pop" in Baloo 2 700, mark always left of the wordmark, never stacked, never reversed.
- **Minimum size**: mark not smaller than `20px` tall, below that the three pearl dots merge into a blob. Wordmark not smaller than `0.9rem`.
- **Clearspace**: empty margin equal to the mark's own height on all four sides.
- **Don't**: don't fill the cup body, it's an outline so it reads as glass, not a solid drop. Don't recolor the straw, it's always `--accent-alt`, the one cool note against an otherwise warm mark. Don't add a lid dome or a logo on the cup, this is the shape, not a product photo. Don't use the mark as a bullet or divider.
## Color System
### Roles
| Role | Token | Value | Used for |
|---|---|---|---|
| Canvas | `--bg` | `#fbeef8` | Page background |
| Surface | `--panel` | `#fff6fb` | Nav, menu cards, form fields |
| Surface raised | `--raised` | `#fde3f2` | Hover state, input focus fill |
| Border | `--border` | `#f3c9e6` | Card edges, dividers, input outlines |
| Ink | `--ink` | `#3a1e35` | Primary text, headlines, label on any accent fill |
| Ink muted | `--dim` | `#6f4d68` | Secondary text, meta lines, placeholders |
| Bubblegum | `--accent` | `#ff4fa0` | Primary button fill, focus ring, the mark's outline, "in stock" |
| Turquoise | `--accent-alt` | `#0fb8a6` | Secondary confirmations, the mark's straw, sugar/ice control accents |
| Bubblegum, text-safe | `--accent-text` | `#b8266a` | The only place bubblegum appears as small text (links, price emphasis) |
| Turquoise, text-safe | `--accent-alt-text` | `#0a7568` | The only place turquoise appears as small text |
**The four drinks in the hero are illustrative, not tokens.** Milk tea's tan, taro's lavender, mango green tea's amber, and strawberry matcha's pink-over-green are the real, specific colors of those real drinks, the same way Harborview's dawn-to-night sky gradient uses colors beyond its two brand accents to paint an actual sky. `--accent` and `--accent-alt` never appear inside a cup, they're reserved for the interface asking you to do something, not for a drink telling you what it is.
### Contrast (computed from the hex values above via WCAG relative luminance, this is a light pastel canvas, every pairing below is text-on-light)
| Pairing | Ratio | Passes |
|---|---|---|
| `--ink` on `--bg` | 13.19:1 | AAA |
| `--dim` on `--bg` | 6.36:1 | AA |
| `--ink` on `--panel` | 13.99:1 | AAA |
| `--dim` on `--panel` | 6.75:1 | AA |
| `--dim` on `--raised` | 5.94:1 | AA |
| `--accent-text` on `--bg` | 5.30:1 | AA |
| `--accent-alt-text` on `--bg` | 4.97:1 | AA |
| `--ink` label on `--accent` fill | 4.85:1 | AA |
| `--ink` label on `--accent-alt` fill | 5.95:1 | AA |
| `--bg` label on `--accent` fill | 2.72:1 | Fails, never done |
| `--accent` (raw) as small text on `--bg` | 2.72:1 | Fails, never done |
| `--accent-alt` (raw) as small text on `--bg` | 2.22:1 | Fails, never done |
This palette breaks a rule every dark-canvas system in this gallery takes for granted, and the table above is why. On a dark canvas, a light `--bg` label on a saturated fill clears AA easily. On this light canvas, the opposite pairing wins: **a button or badge filled with `--accent` or `--accent-alt` labels itself in `--ink`, never `--bg`**, because white-on-bubblegum measures 2.72:1. And the raw accent hues are too light-mid-toned to pass as small text on this canvas at all, `--accent-text`/`--accent-alt-text` are darker tints that exist specifically to carry that job, the same solution Salt & Iron uses for its own too-light rust.
typography:
display:
fontFamily: Baloo 2
fontWeight: 700
body:
fontFamily: Inter
fontWeight: 400
## Type Scale
| Token | Size | Weight | Family | Line-height | Letter-spacing | Used for |
|---|---|---|---|---|---|---|
| `--text-display` | `clamp(2.25rem, 5.5vw, 3.75rem)` | 700 | Baloo 2 | 1.1 | 0 | Homepage H1 only |
| `--text-h2` | `1.6rem` | 700 | Baloo 2 | 1.2 | 0 | Section headings |
| `--text-h3` | `1.2rem` | 700 | Baloo 2 | 1.25 | 0 | Cup/flavor names, menu item names |
| `--text-price` | `1.15rem` | 700 | Baloo 2 | 1 | 0 | Price figures |
| `--text-body` | `1rem` | 400 | Inter | 1.65 | 0 | Paragraph copy |
| `--text-small` | `0.85rem` | 400 | Inter | 1.5 | 0 | Nav, footer, helper text, meta lines |
| `--text-label` | `0.75rem` | 600 | Inter | 1 | 0.06em, uppercase | Kickers, form labels, control labels |
Rule for Baloo 2 versus Inter: Baloo 2's round terminals are the whole point of the "bubbly" bet, so it's reserved for moments that should feel round and full, the headline, section headings, every flavor name, every price. Inter carries anything meant to be scanned quickly: body copy, nav labels, button labels, form fields, footer. A rounded display face used for paragraph copy stops reading as bubbly and starts reading as hard to read, so body text never gets it.
## Spacing Scale
Base unit `8px`. Tokens in use: `--space-2: 0.5rem`, `--space-3: 1rem`, `--space-4: 1.5rem`, `--space-6: 2rem`, `--space-8: 3rem`, `--space-12: 4rem`.
## Shape
`--radius: 20px` on cards, panels, and inputs, big enough to read as genuinely round, not just "rounded corners." `--radius-pill: 999px` on buttons, badges, and the sugar/ice segmented controls. Nothing on this page is sharp-cornered, a cup, a pearl, and a straw are all round shapes, and the UI around them follows.
## Iconography
No icon library. The only non-text graphics are the logo mark and the four homepage cups themselves (a reusable trapezoid-cup path, pearls, a rising tea-color fill, and a straw, all hand-built). A menu-page toppings list uses text labels, not icons, "extra pearls," not a pearl glyph next to unrelated words.
## Motion Principles
Scroll fills four cups in sequence, each one's own local progress window: pearls (3 small circles) fade and settle into the base first, then the tea itself rises inside the cup from empty to its fill line in the drink's real color, then a straw drops in from above at an angle once the cup is full. The moment a cup finishes, the menu card for that flavor slides in below it, exactly the "mechanism reveals, never gates" rule this gallery holds to, every flavor is also written out in plain markup regardless of scroll or script state. This is a one-shot reveal (`toggleActions: play none none reverse`), nothing loops or auto-plays. The scroll trigger's start/end bounds are tuned so progress is verified `0` at scroll position `0`, this page doesn't claim "nothing pours until you scroll" in its own copy without checking it first, see Second Hand's own Known Constraints for why that check matters. `prefers-reduced-motion: reduce` renders every cup already full, pearls settled, straw in, every card already visible.
## Voice & Tone
Playful, specific, a little proud, never saccharine. In practice:
- **Button label**: "Order ahead", not "Treat yourself today!"
- **Flavor description**: "Brown sugar syrup, hand-shaken, pearls cooked fresh every four hours, not held in syrup all day.", not "An explosion of flavor in every sip!"
- **Empty state**: "Nothing customized yet, pick a base below.", not "Oops, empty cup!"
- **Sugar-level copy**: "0% still tastes like something, we don't just pull the syrup and call it done."
## Accessibility Baseline
- Focus ring: `2px solid var(--accent)`, `2px` offset, applied via `:focus-visible` on every interactive element.
- Reduced motion: every cup fill, pearl settle, and straw drop checks `prefers-reduced-motion: reduce` and renders the finished state immediately.
- Minimum tap target: `44px` in the smallest dimension for every button, segmented-control option, and input.
- Color is never the only signal: sugar/ice segmented controls pair the selected state with a filled background and a checkmark, not color alone; a sold-out flavor pairs its badge with the word "Sold out," not a dimmed color alone.
- Every flavor the cup animation can reveal is also written out in plain markup at all times, see Motion Principles.
## Components
### Navigation
Single-line bar, `64px` tall, `--panel` background with a `--border` bottom hairline, sticky to the top. Left: the mark + wordmark lockup. Right: a "Menu" link plus one primary button ("Order ahead"). No dropdown, a two-page shop has nothing to collapse into a menu.
### Buttons
Three variants, one radius (`--radius-pill`):
- **Primary**: `--accent` fill, `--ink` label (see Contrast above for why), used once per view for the real action ("Order ahead").
- **Secondary**: transparent fill, `1px solid --border`, `--ink` label. Same-page anchors.
- **Ghost**: text-only, `--dim` label, `--ink` on hover. Tertiary jumps.
All variants define `:hover` (brightness/border shift), `:active` (`transform: scale(0.97)`), `:disabled` (`opacity: .45`, `pointer-events: none`), and `:focus-visible`.
### The cup row (signature interaction)
Documented in full under Motion Principles. Structurally: four `.cup` SVGs in a row, each with a shared trapezoid outline, an internal `clipPath` the tea-fill `` animates height inside, three pearl circles, and a straw. A kicker line states the mechanism plainly: "Four drinks, actually being made. The pearls settle, the tea rises, then the straw goes in."
### Menu card
A flat `.panel`: `--panel` background, `1px solid --border`, `--radius`, no shadow. Holds the flavor name (Baloo 2), a one-line real description (syrup, prep method, not marketing adjectives), the price (Baloo 2, `--text-price`), and an availability badge. Revealed by its cup filling above, present in the DOM at all times.
### Availability badge
`--radius-pill`, `1px solid` the semantic color, `--accent-text`/`--accent-alt-text` label on a `--bg` fill (never the raw accent as text, see Contrast). "In stock" and "Sold out" are the only two states, sold-out pairs its outline with the literal word, never color alone.
### Sugar / ice segmented control (menu page)
A single hard-bordered `--border` frame holding real buttons in one row, no gaps, no pills between segments (the pill radius applies to the frame's own two ends only). Selected segment gets an `--accent` fill with an `--ink` label and a small checkmark, `aria-pressed="true"`. Matches Wavelen's own show-filter precedent: real buttons in a frame, not a fake dropdown.
### Order form (menu page)
Label above input, `--text-small`/`--dim`. Input: `--panel` background, `1px solid --border`, `--radius`, `--ink` text. On `:focus`, border becomes `--accent` and the focus ring applies. On error, the border becomes `--accent-text` and the helper explains what to fix, reusing the text-safe pink rather than inventing a third color for "invalid."
### Footer
One row: shop name/tagline on the left, real page links on the right (Menu, back to gallery). No invented legal text.
## Do's and Don'ts
### Do
- Let the cups decide the layout, they're the product, not a decoration next to one.
- Use each drink's own real color inside its cup, never `--accent`/`--accent-alt` for the liquid itself.
- Label any accent-filled surface in `--ink`, this palette's fill/label pairing is the opposite of every dark-canvas system in this gallery, see Contrast.
- Write every flavor the cup row can reveal into plain markup at all times.
- Keep radii genuinely round (`20px`+), a bubbly brand with an 8px "safe" corner isn't bubbly.
### Don't
- Don't use raw `--accent`/`--accent-alt` as small text on `--bg`, both fail AA outright, use the `-text` tints.
- Don't fill a drink's cup with the brand's own accent color, that's a UI color describing itself, not the drink.
- Don't add a mascot, confetti burst, or mid-scroll popup, the real drink-making steps carry the "fun," nothing else needs to perform it.
- Don't replay the cup-fill animation on every scroll pass, it plays once, like an order actually being made.
- Don't stack more than one different primary action in the same view (the nav's persistent primary echoing the hero's own is the gallery-wide exception, see Second Hand's own Deliberate Exceptions for why that specific pattern isn't this rule).
## Known Constraints
- Two routes exist (homepage, menu). There is no checkout and no authenticated state, "Order ahead" is not wired to anything real, this is a concept demo.
- The cup row holds exactly four drinks because that's the current homepage lineup. A fifth drink means a fifth cup on the shared row, not a separate list.
- No responsive breakpoint table beyond a single-column mobile collapse of the cup row and menu grid.
## Process
Built through the impeccable-audited anti-slop workflow: never-list written
before any HTML, page structure derived from the signature interaction
(four cups actually filling) rather than a template, mechanical detector
run clean, and the scroll trigger's start/end bounds checked to verify
`0` progress at scroll position `0` before this system was considered
done, applying the exact lesson Second Hand's own critique surfaced.