--- version: alpha name: splashdeck-design description: "A saturated turquoise canvas (#00c2cb), the whole page background, not a neutral canvas with bright accents. Deep-teal-black ink (#062326) carries all text. Coral (#ff5a36) and sunny yellow (#ffe14d) are fills only, reserved for buttons, lane markers, and badges, never used as text color since neither passes contrast directly against the turquoise. Poppins carries every headline, Inter carries anything meant to be read quickly. The homepage's hero is one pool cross-section, water actually rising as you scroll, four skill levels lighting up in sequence as the waterline passes them." --- ## Brand Positioning SplashDeck runs group swim lessons, and it exists because most swim-school sites either go clinical (a stock photo of a chlorine-blue pool and a liability paragraph) or go full inflatable-flamingo kids-party and undersell that this is actual safety instruction. SplashDeck's bet: be genuinely loud, a real saturated pool-water color as the canvas itself, not a muted accent wearing a pool theme, and stay completely plain about the thing that matters, what level your kid is at, what they'll learn next, and when. If a component performs "fun in the sun" without being tied to a real skill level, a real class time, or the water itself, it doesn't belong here. colors: accent: "#ff5a36" accent-text: "#c73512" accent-alt: "#ffe14d" accent-alt-text: "#8a6d00" ink: "#062326" ink-muted: "#0a3a3d" canvas: "#00c2cb" ## Logo / Wordmark System The mark is a single wave crest over a droplet, the wave always mid-break (curling over, never flat), the shape a swimmer actually sees at the surface, not a generic water-drop icon. ```svg ``` - **Lockup**: mark, then a `0.5rem` gap, then "SplashDeck" in Poppins, mark always left of the wordmark. - **Minimum size**: mark not smaller than `18px` wide, below that the wave curl and the droplet both blur into noise. - **Clearspace**: empty margin equal to the mark's own width on all four sides. - **Don't**: don't flatten the wave into a straight line, it's always mid-break. Don't recolor the droplet, it's always `--accent`, never `--accent-alt` or ink. Don't place the mark directly on the turquoise canvas without at least a white or panel-colored backing, the coral droplet loses definition against pure `--bg`. ## Color System ### Roles | Role | Token | Value | Used for | |---|---|---|---| | Canvas | `--bg` | `#00c2cb` | Page background, the whole page, not a band or hero-only treatment | | Surface | `--panel` | `#ffffff` | Nav, class cards, form fields, anywhere body copy needs to sit on a neutral surface | | Surface raised | `--raised` | `#f2fdfd` | Hover state, input focus fill | | Border | `--border` | `#d9f3f3` | Card edges, dividers, input outlines | | Ink | `--ink` | `#062326` | All text on both the canvas and the panel, headlines | | Ink muted | `--dim` | `#0a3a3d` | Secondary text, meta lines, placeholders, on canvas or panel | | Coral | `--accent` | `#ff5a36` | Primary button fill (ink label), the mark's droplet, deep-end lane marker | | Coral text | `--accent-text` | `#c73512` | Links and small accent text, panel surfaces only, see constraint below | | Yellow | `--accent-alt` | `#ffe14d` | Secondary button fill (ink label), shallow-end lane marker, "open" status | | Yellow text | `--accent-alt-text` | `#8a6d00` | Secondary links, small accent text, panel surfaces only | **Constraint specific to this palette**: `--accent` and `--accent-text` (and their yellow equivalents) are never used as text color directly on `--bg`. Both measure below 2:1 against the turquoise canvas, close enough in perceived lightness that colored text on canvas is functionally invisible. Every piece of real copy on this site sits on `--ink` over either `--bg` or `--panel`; the coral and yellow tones only ever appear as solid fills (buttons, lane markers, badge dots) or, on a white panel specifically, as small link text. This is the opposite problem from Pearl & Pop, Sunsplit, and High Score's bright-fill/dark-text-tier answer, those palettes had accents too light for white text; this palette's canvas itself is mid-brightness, so its accents collide with the canvas instead of with white. ### Contrast (computed from the hex values above via WCAG relative luminance) | Pairing | Ratio | Passes | |---|---|---| | `--ink` on `--bg` | 7.51:1 | AAA | | `--dim` on `--bg` | 5.68:1 | AA | | `--ink` on `--panel` | 16.46:1 | AAA | | `--accent-text` on `--panel` (links) | 5.32:1 | AA | | `--accent-alt-text` on `--panel` (links) | 4.92:1 | AA | | `--ink` label on `--accent` fill | 5.3:1 | AA | | `--ink` label on `--accent-alt` fill | 12.64:1 | AAA | | `--accent` on `--bg` (why it's fill-only) | 1.42:1 | Fails | | `--accent-alt` on `--bg` (why it's fill-only) | 1.68:1 | Fails | The last two rows are recorded deliberately: they're the computed proof for why this palette's accents are fill-only, not an assumption carried over from another system. typography: display: fontFamily: Poppins fontWeight: 600 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.6rem)` | 700 | Poppins | 1.1 | 0 | Homepage H1 only | | `--text-h2` | `1.5rem` | 600 | Poppins | 1.2 | 0 | Section headings | | `--text-h3` | `1.1rem` | 600 | Poppins | 1.25 | 0 | Class level 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 | Poppins' round geometry reads as confident and friendly without tipping into a kids'-menu typeface, reserved for the headline, section headings, and class level names. Inter carries anything read as a sentence or clicked as a control, including every class time and price, which need to be scanned accurately. ## 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. `--radius-pill: 999px` on buttons and badges. The pool cross-section itself uses a single continuous rounded-rect basin, deliberately the one large shape on the page that isn't a card, because a pool is a basin, not a stack of panels. ## Iconography No icon library. The only non-text graphics are the logo mark and the hero's own pool cross-section (hand-built SVG). Class times and skill levels are plain text, not a stopwatch or star icon next to unrelated words. ## Motion Principles Scroll rises the water level in one continuous pool cross-section, not four separate parallel elements, closer to Tumble Town's single-path answer than the four-parallel-object pattern most of this batch uses. Four skill-level threshold lines sit at fixed depths; the moment the rising waterline crosses one, that level's class card slides in below. One-shot reveal, nothing loops, every class is written out in plain markup at all times regardless of scroll or script state. Scroll trigger uses a fixed pixel-distance range ("top top" / "+=…"), not a viewport-percentage range, after Sunsplit's pre-elapsed-trigger bug proved percentage triggers are unsafe for hero elements sitting close to the viewport top at load; verified at exactly `0` progress at scroll position `0`. `prefers-reduced-motion: reduce` renders the pool already full and every card already visible. ## Voice & Tone Energetic, encouraging, plainspoken about safety, no baby-talk. In practice: - **Button label**: "Find a class time", not "Dive into the fun!" - **Class description**: "Puts a face in the water without panic, kicks with a board, no swim vest by the end.", not "Splashtastic water play!" - **Safety note**: "Every class keeps a 4-to-1 kid-to-instructor ratio, we count heads out loud at the start and end.", not silence about ratios - **Empty state**: "That time's full for this session, the next one opens in three weeks.", not "Oops, no spots!" ## Accessibility Baseline - Focus ring: `2px solid var(--accent-alt-text)`, `2px` offset, applied via `:focus-visible` on every interactive element. - Reduced motion: the water-rise 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: a class's badge pairs "Open" or "Full" with the word, never color alone. - Every class level the water can reveal is also written out in plain markup at all times, see Motion Principles. - No colored text ever sits directly on `--bg`, see the Color System constraint above, this keeps every on-canvas string at AA or better by construction. ## 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 "Classes" link plus one primary button ("Find a class time"). ### Buttons Three variants, one radius (`--radius-pill`): - **Primary**: `--accent` fill, `--ink` label, used once per view for the real action. - **Secondary**: `--panel` fill, `1px solid --border`, `--ink` label, used on the turquoise canvas so it reads as a raised surface rather than colored text-on-canvas. - **Ghost**: text-only, `--ink` label at reduced opacity, full `--ink` on hover, never `--dim` alone on canvas since it needs to stay legible at a glance. All variants define `:hover`, `:active` (`transform: scale(0.97)`), `:disabled` (`opacity: .45`), and `:focus-visible`. ### The pool (signature interaction) Documented in full under Motion Principles. Structurally: one basin path, a single water rect rising continuously from `height: 0` to full over the whole scroll range, four fixed threshold lines with labels, real lane-marker colors (coral for the deep end, yellow for the shallow end). ### Class card A flat `.panel`: `--panel` background, `1px solid --border`, `--radius`, no shadow. Holds the level name (Poppins), a real skill description, the class time, and an open/full badge. Revealed by the waterline crossing its threshold above, present in the DOM at all times. ### Badge `--radius-pill`, `1px solid` the semantic color, semantic-color text on transparent fill (panel surfaces only): `--accent-text` for "Open," `--dim` for "Full." Never filled solid, never placed directly on `--bg`. ### Footer One row: school name/tagline on the left, real page links on the right (Classes, back to gallery). ## Do's and Don'ts ### Do - Keep the canvas itself loud, a real saturated pool-water turquoise, not a pale tint standing in for one. - Use `--ink` for every string of text on the canvas, never a colored accent as text-on-canvas. - Let the pool fill continuously, one basin, not four parallel elements. - Write every class level the water can reveal into plain markup at all times. - State the real instructor ratio and safety practice, don't just imply safety with tone. ### Don't - Don't use a stock pool photo, a lifeguard-whistle icon, or a beach-ball graphic anywhere. - Don't perform "splashtastic" or "dive into the fun" copy, name the actual skill and class time instead. - Don't put coral or yellow text directly on the turquoise canvas, verify against the contrast table first. - Don't replay the water rise on every scroll pass, it plays once, like a real pool filling. ## Known Constraints - Two routes exist (homepage, classes). There is no checkout and no authenticated state, "Find a class time" and the enrollment form are not wired to anything real, this is a concept demo. - The pool holds exactly four skill-level thresholds because that's the current curriculum. A fifth level adds a fifth threshold line, not a second pool. - No responsive breakpoint table beyond a single-column mobile collapse of the pool stage and class cards. - This palette cannot safely add a fifth accent without recomputing its contrast against `--bg` directly, the canvas itself is mid-brightness and collides easily with new mid-brightness colors. ## Process Built through the impeccable-audited anti-slop workflow: never-list written before any HTML, page structure derived from the signature interaction (one real pool, 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, using a fixed-pixel-distance trigger from the outset given the pre-elapsed-trigger lesson from Sunsplit earlier in this batch.