--- version: alpha name: tumble-town-design description: "A warm off-white canvas (#fefcf9) with navy ink (#16213e), a true primary red (#d4291f) and a true primary blue (#0d55c4) as the two brand accents. Bungee-adjacent chunk comes from Baloo 2 at weight 700 for every headline, Inter carries anything meant to be read quickly. The homepage's hero is one ball, actually bouncing zone to zone down the real course, not four static icons." --- ## Brand Positioning Tumble Town exists for the parent booking the visit, not just the kid attending it, because that's who actually reads a website. Most indoor-playground sites perform "fun" at the parent (confetti, a bouncing mascot, exclamation points) while burying the two things a parent actually needs: what's really in the building, and what it costs. So the homepage's hero is one ball, bouncing down the real course, landing on each real zone in the order a kid actually hits them, and the copy talks to the parent like an adult ("Wear them out, properly," not "Get ready for MEGA fun!!"). If a component performs excitement without naming a real zone, a real price, or a real rule, it doesn't belong here. colors: accent: "#d4291f" accent-alt: "#0d55c4" ink: "#16213e" ink-muted: "#5c6b85" canvas: "#fefcf9" ## Logo / Wordmark System The mark is a ball mid-bounce: a filled circle with a short motion-arc trailing behind it and a small flattened "impact" ellipse beneath, the literal shape of the homepage's own signature ball caught at the moment it lands. ```svg ``` - **Lockup**: mark, then a `0.5rem` gap, then "Tumble Town" in Baloo 2 700, mark always left of the wordmark. - **Minimum size**: mark not smaller than `20px` wide, below that the motion-arc dashes merge into a blur. Wordmark not smaller than `0.9rem`. - **Clearspace**: empty margin equal to the mark's own width on all four sides. - **Don't**: don't drop the impact ellipse, without it the ball reads as floating, not landing. Don't recolor the ball, it's always `--accent`, the trail is always `--accent-alt`. Don't add a face or eyes to the ball, it's a ball, not a mascot. Don't use it as a bullet or divider. ## Color System ### Roles | Role | Token | Value | Used for | |---|---|---|---| | Canvas | `--bg` | `#fefcf9` | Page background | | Surface | `--panel` | `#ffffff` | Nav, zone cards, form fields | | Surface raised | `--raised` | `#fff2ee` | Hover state, input focus fill | | Border | `--border` | `#f2e2d4` | Card edges, dividers, input outlines | | Ink | `--ink` | `#16213e` | Primary text, headlines | | Ink muted | `--dim` | `#5c6b85` | Secondary text, meta lines, placeholders | | Red | `--accent` | `#d4291f` | Primary button fill, focus ring, the ball, "open" status | | Blue | `--accent-alt` | `#0d55c4` | Secondary confirmations, the motion trail, "members" status | Both accents are deliberately true, saturated primaries, not a pastel-softened or jewel-toned version of red and blue, the same way the equipment in the building is actually red and blue, not a tasteful editorial version of them. Unlike Pearl & Pop's light-canvas palette, these particular reds and blues were tuned dark enough to clear AA as both text-on-canvas and white-label-on-fill without needing separate text-safe tints, see Contrast. ### Contrast (computed from the hex values above via WCAG relative luminance) | Pairing | Ratio | Passes | |---|---|---| | `--ink` on `--bg` | 15.52:1 | AAA | | `--dim` on `--bg` | 5.26:1 | AA | | `--ink` on `--panel` | 15.89:1 | AAA | | `--dim` on `--panel` | 5.39:1 | AA | | `--dim` on `--raised` | 4.92:1 | AA | | `--accent` on `--bg` (links, status) | 4.96:1 | AA | | `--accent-alt` on `--bg` (links, status) | 6.59:1 | AA | | white label on `--accent` fill | 5.08:1 | AA | | white label on `--accent-alt` fill | 6.74:1 | AA | | `--ink` label on `--accent` fill | 3.13:1 | Fails, never done | | `--ink` label on `--accent-alt` fill | 2.36:1 | Fails, never done | The rule: a filled accent surface labels itself in white (`#ffffff`, matching `--panel` here since panel is pure white), never `--ink`, both accents fail navy-on-fill outright. This is the opposite lesson from Pearl & Pop (whose lighter pinks needed dark labels) and a reminder that "light canvas" doesn't imply one fixed fill/label rule, each palette's own computed numbers decide it. 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.5rem` | 700 | Baloo 2 | 1.2 | 0 | Section headings | | `--text-h3` | `1.15rem` | 700 | Baloo 2 | 1.25 | 0 | Zone names | | `--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, badges, form labels | Same split as every other display/body pairing in this gallery: Baloo 2 for the handful of moments meant to be felt (headline, zone names), Inter for anything read as a sentence or clicked as a control, including every price and every rule, those need to be scanned accurately, not felt. ## 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: 16px` on cards, panels, and inputs, round enough to read as padded/safe (this is a kids' venue) without going full pill. `--radius-pill: 999px` on buttons, badges, and the platform shapes in the hero. One scale, applied consistently. ## Iconography No icon library. The only non-text graphics are the logo mark and the hero's own ball-and-platform course (hand-built). Zone rules use plain text, not warning-triangle glyphs, "socks required," not an icon next to unrelated words. ## Motion Principles One ball drops from above the course and bounces zone to zone as you scroll, a single continuous path, not four independent elements animating in parallel. Each hop is a short parabolic arc between the previous platform and the next, landing exactly on the platform, at which point that zone's card slides in below. This is the one departure from this gallery's usual "four elements gated by overlapping windows" pattern (see Second Hand, Pearl & Pop, Rink & Roll), because a ball can only be in one place, four independent balls bouncing at once wouldn't read as one course. One-shot reveal (`toggleActions: play none none reverse`), nothing loops, every zone is written out in plain markup at all times regardless of scroll or script state. Scroll trigger bounds checked to verify `0` progress at scroll position `0`. `prefers-reduced-motion: reduce` renders the ball already resting on the final platform and every card already visible. ## Voice & Tone Dry, plainspoken, talks to the parent booking the visit, not just the kid attending. In practice: - **Button label**: "Book a visit", not "Let's get bouncing!!" - **Zone description**: "Foam pit, six feet deep, socks required, no exceptions.", not "The ULTIMATE foam pit experience!" - **Rule**: "One adult per four kids under 6, we do check.", not a vague "adult supervision recommended" - **Empty state**: "No open slots this weekend, weekdays have more room.", not "Oh no, we're all booked up!" ## Accessibility Baseline - Focus ring: `2px solid var(--accent-alt)`, `2px` offset, applied via `:focus-visible` on every interactive element. - Reduced motion: the ball's hop sequence and every card reveal check `prefers-reduced-motion: reduce` and render the finished state immediately. - Minimum tap target: `44px` in the smallest dimension for every button and input. - Color is never the only signal: zone badges pair "Open" or "Members" with the word, never color alone. - Every zone the ball course 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 "Zones" link plus one primary button ("Book a visit"). ### Buttons Three variants, one radius (`--radius-pill`): - **Primary**: `--accent` fill, white label, used once per view for the real action ("Book a visit"). - **Secondary**: transparent fill, `1px solid --border`, `--ink` label. - **Ghost**: text-only, `--dim` label, `--ink` on hover. All variants define `:hover`, `:active` (`transform: scale(0.97)`), `:disabled` (`opacity: .45`), and `:focus-visible`. ### The course (signature interaction) Documented in full under Motion Principles. Structurally: a dashed static path connecting a start point to four platform shapes (`--radius-pill` bars), and one ball (`circle`, `--accent` fill) whose `cx`/`cy` are set directly per animation frame based on overall scroll progress, not four parallel elements. ### Zone card A flat `.panel`: `--panel` background, `1px solid --border`, `--radius`, no shadow. Holds the zone name (Baloo 2), a one-line honest rule or description, an age/height note, and an availability badge. Revealed by the ball landing on it above, present in the DOM at all times. ### Badge `--radius-pill`, `1px solid` the semantic color, semantic-color text on transparent fill: `--accent` for "Open," `--accent-alt` for "Members." Never filled solid. ### Footer One row: venue name/tagline on the left, real page links on the right (Zones, back to gallery). ## Do's and Don'ts ### Do - Let one ball bounce through the whole course, not four parallel elements, a real course only has one ball on it at a time. - Talk to the parent booking the visit, plain and dry, not the kid. - Label any accent-filled surface in white, both accents fail navy-on-fill, see Contrast. - Write every zone the course can reveal into plain markup at all times. - Keep both accents true, saturated primaries, not a softened or pastel version. ### Don't - Don't add a mascot, a face on the ball, or a confetti burst. - Don't stack exclamation points or write in the kid's voice, the parent is the reader. - Don't animate four balls in parallel, one ball, one course. - Don't replay the bounce sequence on every scroll pass, it plays once. - Don't invent a third accent for a zone that needs a color, reuse red/blue by role (open/members), same as every other status in this system. ## Known Constraints - Two routes exist (homepage, zones). There is no checkout and no authenticated state, "Book a visit" is not wired to anything real, this is a concept demo. - The course holds exactly four platforms because that's the current zone lineup. A fifth zone means a fifth platform on the shared course, not a separate list. - No responsive breakpoint table beyond a single-column mobile collapse of the course and zone cards. ## Process Built through the impeccable-audited anti-slop workflow: never-list written before any HTML, page structure derived from the signature interaction (one real ball on one real course) 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.