--- version: alpha name: wagtail-design description: "A pale mint-white canvas (#f2f7f6) with deep green-charcoal ink (#1f2b28), a warm terracotta (#ab4d28) for the clinic's own mark and primary action, and a calm teal-green (#2f7361) for ready/confirmed states. Fredoka carries every heading at weight 600, rounded and friendly; Inter carries the surrounding prose. The system reads as an actual neighborhood vet clinic's site, warm but not cutesy, never a baby-talk pet-influencer page." --- ## Brand Positioning Wagtail Veterinary is for pet owners who want a clinic that feels warm without talking down to them or their animal. It exists because most vet-clinic sites either borrow cold medical-portal chrome or overcorrect into baby-talk and cartoon mascots, neither of which matches what a good visit actually feels like: a calm walk in, a specific person who knows your pet's name, a plain update afterward. Wagtail's bet: the one piece of warmth on the page should be literal, a trail of paw prints walking in, nothing else needs to perform friendliness. Every visual decision below serves that one bet. If a component doesn't help someone book a visit or understand their pet's status, or doesn't come from a real clinic interaction (appointment table, visit status, booking form), it doesn't belong in this system. colors: accent: "#ab4d28" accent-alt: "#2f7361" ink: "#1f2b28" ink-muted: "#5c6d68" canvas: "#f2f7f6" surface: "#ffffff" surface-raised: "#e4efec" border: "#d3e2dd" focus-ring: "#2f7361" ## Logo / Wordmark System The mark is a rounded-square card containing a single paw print, one large pad and four toes, literally a 1:1 miniature of the prints that walk across the homepage's trail. ```svg ``` - **Lockup**: mark, then a `0.5rem` gap, then the wordmark "Wagtail" in Fredoka/600, mark always left of the wordmark, never stacked or reversed. - **Minimum size**: mark not smaller than `16px` square, below that the toes merge into the pad. Wordmark not smaller than `0.85rem`. - **Clearspace**: empty margin equal to the mark's own height (22px at default size) on all four sides of the lockup. - **Don't**: recolor the mark for a dark background, it only ever renders on `--panel`/`--bg`. Don't add a cartoon face, eyes, or blush marks to the paw, it's a literal print, not a mascot. Don't animate the mark itself, the walking motion belongs to the homepage's trail, not the nav. Don't rotate the mark itself, individual trail prints rotate slightly but the static lockup mark stays upright. ## Color System ### Roles | Role | Token | Value | Used for | |---|---|---|---| | Canvas | `--bg` | `#f2f7f6` | Page background | | Surface | `--panel` | `#ffffff` | Panels, nav, service cards, table body | | Surface raised | `--surface-raised` | `#e4efec` | Table header, row hover, input focus bg | | Border | `--border` | `#d3e2dd` | Panel edges, dividers, input outlines, table rules | | Ink | `--ink` | `#1f2b28` | Primary text | | Ink muted | `--dim` | `#5c6d68` | Secondary text, helper text, waiting-room status | | Clinic / primary | `--accent` | `#ab4d28` | Paw prints, primary button fill, running-behind copy | | Ready / calm | `--accent-alt` | `#2f7361` | Ready-for-pickup status, confirmation badge, focus ring | There is deliberately no alarm red. A schedule running behind is normal clinic reality, not a crisis, so it's communicated in the same warm terracotta the paw prints use, in a plain sentence, never a flashing banner. ### Contrast (computed from the hex values above via WCAG relative luminance) | Pairing | Ratio | Passes | |---|---|---| | `--ink` text on `--bg` | ~13.5:1 | AAA | | `--dim` text on `--bg` | ~5.1:1 | AA (body text) | | `--accent` text on `--bg` (running-behind copy, links) | ~5.1:1 | AA (body text) | | `--accent-alt` text on `--bg` (ready status, badge) | ~5.2:1 | AA (body text) | | Light label on `--accent` fill (primary button) | ~5.1:1 | AA | | `--ink` on `--panel` | ~14.6:1 | AAA | | `--ink` on `--surface-raised` | ~12.5:1 | AAA | The rule this table exists to enforce: `--accent` started as a brighter coral that only cleared large-text contrast and was darkened specifically so the running-behind message itself, not just a badge, could carry the color directly at body size. typography: display: fontFamily: Fredoka fontWeight: 600 body: fontFamily: Inter fontWeight: 400 ## Type Scale | Token | Size | Weight | Family | Line-height | Letter-spacing | Used for | |---|---|---|---|---|---|---| | `--text-display` | `clamp(2.5rem, 6vw, 4.25rem)` | 600 | Fredoka | 1.1 | 0 | Hero H1 only | | `--text-h2` | `1.6rem` (homepage) / `1.4rem` (second page) | 600 | Fredoka | 1.2 | 0 | Section headings | | `--text-body` | `1rem` | 400 | Inter | 1.6 | 0 | Paragraph copy | | `--text-small` | `0.85rem` | 400 | Inter | 1.5 | 0.01em | Footer, nav utility links, helper text, table cells | Rule for Fredoka vs. Inter: Fredoka, rounded and warm, is reserved for the hero headline, section headings, and service names, the moments meant to feel approachable. Everything read as information, pet/owner names, table cells, form labels, status copy, is Inter, chosen because Fredoka at small sizes starts to look cartoonish in a way that undercuts the "doesn't need convincing" positioning. ## 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 One radius scale: `--radius: 16px` for panels, service cards, inputs, and table containers, rounder than most other systems in this gallery on purpose, it reads soft without needing cartoon illustration to feel warm. `--radius-pill: 999px` for buttons and the ready-for-pickup badge. ## Iconography No icon library. The only non-text glyphs are the logo mark, the paw-print trail, and one Unicode glyph, `✓` (ready for pickup), set at the same weight as the text beside it. Visit status is communicated with a plain-language phrase ("In the waiting room", "Ready for pickup") paired with color, never a status icon. If a future page needs more iconography, the fallback is Phosphor (line style, `1.5` stroke), that decision just hasn't been needed yet. ## Motion Principles Scroll reveals a trail of six paw prints stepping across the hero, each one fading and lifting into place a beat after the last, exactly once per view (`toggleActions: play none none reverse`, reversible by scrolling back up). This is the only scripted animation on either page, everything else (buttons, table rows, form inputs) uses only `:hover`/`:active`/`:focus-visible` CSS transitions. The whole system honors `prefers-reduced-motion` by showing every print in place immediately, no stagger, no lift. ### Never-list (written before the impeccable-pass rebuild) 1. No full-viewport centered hero holding the paw trail a forced screen-height away, the trail walks in directly beneath the headline in the same first fold. 2. No two-button CTA row floating free of the trail. ## Voice & Tone friendly, reassuring, plain, no baby-talk. In practice: - **Button label**: "Book a visit", not "Schedule Your Furry Friend's Appointment!" - **Error message**: "Running behind. An earlier surgery pushed the schedule back 20 minutes.", not "Oopsie, we're running late!" - **Empty state**: "No visits scheduled for today.", not "Nothing to see here, paw-some!" - **Success status**: "Biscuit is ready for pickup", not "Yay!! Your fur baby is all done!! 🐾" ## Accessibility Baseline - Focus ring: `2px solid var(--accent-alt)`, `2px` offset, applied via `:focus-visible` on every interactive element (links, buttons, inputs, textarea), never removed without a visible replacement. - Reduced motion: the paw-trail stagger checks `prefers-reduced-motion: reduce` and shows every print in place immediately, no animation. - Minimum tap target: `44px` in the smallest dimension for every button and form control on touch viewports. - Color is never the only signal: visit status pairs color with a specific phrase and, where relevant, a pet's name, the running-behind state pairs terracotta with a full sentence, not a bare icon. ## Components ### Navigation Single-line bar, `64px` tall, `--panel` background with a `--border` bottom hairline, sticky to the top. Left: a small "back to gallery" utility link. Center-left: the mark + wordmark lockup. Right: an Appointments link plus one primary button. Collapses to just the lockup and primary button under `480px`, no hamburger, there are only two destinations. ### Buttons Three variants, one radius (`--radius-pill`), one primary accent: - **Primary**: `--accent` fill, light label, used once per view for the single real action ("Book a visit", "Request a time"). - **Secondary**: transparent fill, `1px solid --border`, `--ink` label. "See new time" and similar secondary actions. - **Ghost**: text-only, `--dim` label, `--ink` on hover, bold weight matching the rest of the button set. Tertiary actions like "follow the trail." All variants define `:hover` (brightness/border shift), `:active` (`transform: scale(0.98)`), `:disabled` (`opacity: .4`, `pointer-events: none`), and `:focus-visible` (teal outline). ### Paw trail Six absolutely-positioned paw-print SVGs, each rotated a few degrees off-axis (never uniformly aligned, a real walk isn't perfectly straight), revealed with a stagger fade-and-lift the first time the section enters view. Purely illustrative, not interactive. ### Service cards A flat panel per service: a Fredoka name and one plain sentence of detail. No icon per card, no stock photography, the sentence does the work. ### Table Header row in `--surface-raised`/`--dim` bold labels, body rows in `--panel`, one `--border` rule between rows, row hover to `--surface-raised`. Status cells are bold text in `--accent-alt` (ready) or `--dim` (waiting/in progress), never a bare colored dot. ### Forms Label above input, `--text-small`/`--dim`. Input/textarea: `--panel` background, `1px solid --border`, `--radius`, `--ink` text, `--dim` placeholder. On `:focus`, border becomes `--accent-alt` and background lifts to `--surface-raised`. On error, border becomes `--accent` and helper text explains what's missing in plain, non-scolding language. ### Status / feedback states - **Loading**: a skeleton shaped like the real content (bars matching text line-heights), not a spinner. - **Empty**: a plain sentence in `--dim`, no illustration. - **Error**: an inline `--accent` message with a concrete next step, never a silent failure. - **Success / status badge**: `--radius-pill`, `1px solid --accent-alt`, `--accent-alt` text on transparent fill, not filled, filled would compete with the primary button's exclusive use of a solid `--accent` fill. ### Footer One row: clinic name/tagline on the left, real page links on the right (Appointments, back to gallery). No invented legal or licensure text. ## Do's and Don'ts ### Do - Let the paw trail be the only scroll-staggered illustrative element on the page. - Reserve `--accent` for the clinic's own primary meaning and `--accent-alt` for ready/calm meaning, keep that split consistent everywhere. - Use a light label on any `--accent`-filled surface. - Name pets and owners specifically in tables and status copy, never "Patient 1." - Keep Fredoka to headings and card names only, body copy stays in Inter for real legibility. ### Don't - Don't add a cartoon mascot, cutesy sound effects, or baby-talk copy ("furbaby", "paw-some"), warmth here comes from plain, specific language. - Don't introduce alarm red for scheduling delays, route those to `--accent` with a specific sentence instead. - Don't replay the paw-trail stagger on every scroll pass, reveal once per view. - Don't stack more than one primary button in the same view. - Don't fill a status badge solid, badges stay outlined so the primary button remains the only solid-`--accent`-fill element on screen. ## Known Constraints - Two routes now exist (home, appointments), still no real patient-record system or payment flow, no responsive breakpoint table beyond a single-column mobile collapse, no authenticated owner login (the "Book a visit" form is not wired to anything real, this is a concept demo).