2 cases built from this template
Same prompt, different [VARIABLES]. Click one to preview it above.About this template
A two-page website for a dance studio that needs to fill classes without hiding the practical details. The home page pairs a wide, stage-lit dance photograph with a direct free-class invitation, then introduces three dance programs, three instructor profiles, the next recital, class passes and a trial-booking form. A second page presents 24 weekly classes with combined style, age and level filters, clear availability, and a detail drawer that leads back to the trial form.
The default content follows an invented neighborhood studio teaching hip-hop, contemporary and jazz to children, teens and adults. Class names, times, capacities, prices, instructor biographies and first-visit answers are specific enough to feel like an operating business, but every person and detail is fictional. The three instructor portraits are generated placeholders for an invented team, ready to be replaced with a real studio's photography.
Visually, the template uses deep aubergine, warm paper, coral and soft lilac, with oversized uppercase headlines and a rhythmic moving program rail. Photographs share one editorial treatment: dark studio floors, coral rim light and gentle lilac fill. Large images anchor the hero and recital sections rather than leaving the first screen to typography alone.
Useful interactions do the selling. Filters combine with AND logic and sync to the URL, the recital timer counts down to a configurable local date, pass cards feed the booking form, and valid trial reservations produce a printable confirmation saved only in the browser. Everything works as static files with local assets and reduced-motion support.
To adapt it, change the studio name, city, dance styles, audience and recital date. All schedule entries, prices, biographies and copy live in one content file, so a builder can rewrite them for the new studio while preserving the layout, motion and booking flow.
The template prompt
The live demo was built from exactly this text — nothing added. The other cases only change the values of the [VARIABLES].
# Dance Studio Website
Build this website exactly as described below. Replace the [VARIABLES] with your own values; keep everything else.
## Brief
Build a two-page website for [BRAND], a dance studio in [CITY] teaching [STYLES] to [AUDIENCE]. The home page sells the experience with a wide class photograph, three program cards, three instructor profiles, a live recital countdown to [RECITAL_DATE], three pricing passes and a validated free-trial booking flow. classes.html is the complete weekly timetable with style, age and level filters, class details and direct trial links. The visual language is electric editorial: deep aubergine, warm paper, coral and lilac, oversized grotesque headlines, asymmetric grids and rhythmic but readable motion. Everything is static and client-side.
- Audience: Parents comparing a first activity for a child, teens looking for a level-appropriate class, and adults in [CITY] who want to start or return to dance. Visitors need to quickly answer: is there a class for my age and experience, who teaches it, what does it cost, and can I try before committing?
- Goal: Turn a first-time visitor into a free-trial reservation. Every major section offers a route to a suitable class or the booking form. The timetable serves existing dancers too, making the next class, instructor and available places easy to scan on a phone.
- Tone: Energetic, encouraging and precise. Short declarative sentences, concrete times, ages, durations and prices. Celebrate effort rather than body image or competition. No dance clichés, no promises of fame, no exclamation marks, no pressure to buy.
## Stack
- Framework: Vite 5 + React 18 + TypeScript
- Styling: Tailwind CSS 3.4
- Libraries: react (MIT), react-dom (MIT), motion (motion.dev, import from 'motion/react') (MIT), lucide-react (ISC), tailwindcss (MIT), postcss (MIT), autoprefixer (MIT), vite (MIT), @vitejs/plugin-react (MIT), typescript (Apache-2.0), @fontsource/archivo-black (OFL-1.1), @fontsource-variable/manrope (OFL-1.1), @fontsource/ibm-plex-mono (OFL-1.1)
- Build: `npm run build` → static files in `dist/`. No backend, no server code, no external APIs.
- Setup:
- Scaffold with npm create vite@latest using the react-ts template. Create two real HTML entry files at the project root: index.html with src/main-home.tsx and classes.html with src/main-classes.tsx. Do not add a router.
- vite.config.ts: base './', plugins [react()], build { outDir 'dist', sourcemap false, assetsInlineLimit 0, rollupOptions { input { index: resolve(__dirname, 'index.html'), classes: resolve(__dirname, 'classes.html') } } }. Do not copy src/ into dist/.
- Tailwind 3.4 through PostCSS with content ['./index.html', './classes.html', './src/**/*.{ts,tsx}']. Add Design colors as ink, plum, raised, paper, white, coral, coral-deep, lilac, muted and rule; fontFamily display ['Archivo Black', 'Arial Black', 'sans-serif'], sans ['Manrope Variable', 'system-ui', 'sans-serif'], mono ['IBM Plex Mono', 'ui-monospace', 'monospace']. Configure a 1240px container and the easing tokens below.
- src/fonts.ts imports '@fontsource/archivo-black/400.css', '@fontsource-variable/manrope', '@fontsource/ibm-plex-mono/400.css' and '@fontsource/ibm-plex-mono/500.css'. Both entry files import src/fonts.ts and src/index.css.
- src/index.css holds Tailwind layers, focus styles, the image grade and grain, clipped headline masks, the program-rail keyframes, countdown tabular numerals, print rules for the trial pass, and all prefers-reduced-motion overrides.
- src/content.ts contains every string, number, price, image path, alt text, program, instructor, session, pass, FAQ and address for both pages, typed. Parse [STYLES] as exactly three comma-separated names and derive lowercase style slugs from them. src/lib/brand.ts derives brandSlug from [BRAND], emailDomain from brandSlug without hyphens + '.com', and a two-letter reservation prefix from the first two brand words.
- src/lib/schedule.ts owns class filtering, end times, spots labels and query parsing. src/lib/countdown.ts parses [RECITAL_DATE] once, calculates remaining whole days/hours/minutes/seconds, and clamps expired values to zero. src/lib/storage.ts provides safe try/catch localStorage helpers using keys prefixed with brandSlug + ':'. src/lib/validation.ts owns all trial-form rules.
- Components in src/components/: Header.tsx, MobileMenu.tsx, Reveal.tsx, MaskedHeading.tsx, ProgramRail.tsx, ProgramCards.tsx, Instructors.tsx, RecitalCountdown.tsx, Pricing.tsx, TrialForm.tsx, TrialPass.tsx, Faq.tsx, Visit.tsx, Footer.tsx, and classes/FilterBar.tsx, WeekList.tsx, DayGroup.tsx, ClassRow.tsx, ClassDrawer.tsx. src/pages/Home.tsx and Classes.tsx compose them; both pages use the same Header and Footer.
- Before the first build, download the six images listed under Assets into public/images/ using the exact file names. The build itself never fetches assets or calls an API.
- Create public/favicon.svg as described under Assets. Both HTML files use lang en, <meta name='theme-color' content='#17111C'> and a relative ./favicon.svg link. Titles: index.html '<title>[BRAND] — Dance classes in [CITY]</title>' and classes.html '<title>Class timetable — [BRAND]</title>'.
- Write ASSETS.md at the project root with every image, font and icon package and the exact credit and license details under Assets.
- dist/ must contain index.html, classes.html, hashed JS/CSS, self-hosted woff2 fonts, favicon.svg and the six local images. Target under 12 MB and never exceed 20 MB.
## Variables
- [BRAND] — Studio name (default: "Offbeat Dance Assembly"). An invented 2–4 word studio name used in the wordmark, titles, contact email, reservation references and localStorage keys. Never use a real studio or franchise.
- [CITY] — Studio city (default: "Austin, Texas"). Used in the hero, visit section, footer and page titles. Adapt phone formatting, time zone and the invented neighborhood details to fit.
- [STYLES] — Three dance styles (default: "Hip-Hop, Contemporary, Jazz"). Exactly three comma-separated style names. Rewrite the three program cards, all 24 session names and descriptions, instructor specialties, filters and FAQs for these styles while retaining the schedule structure.
- [AUDIENCE] — Who the studio teaches (default: "dancers ages 7 and up, from complete beginners to experienced movers"). A natural lowercase phrase used in the hero and program introduction. Preserve the three timetable age bands 7–12, 13–17 and 18+.
- [RECITAL_DATE] — Next recital date and time (default: "2027-06-12T19:00:00-05:00"). An ISO 8601 local datetime with offset. Drives the countdown and the human-readable event line; use the supplied offset rather than the visitor's time zone for event formatting.
- [CREDIT] — keep a small "Template by VibeFather" link to https://vibefather.ai/t/dance-studio-website in the footer (default: yes; delete this line to remove it)
The copy under Pages & Sections is written for the default values. If your values differ, rewrite every headline, paragraph, label and image for them — same length, tone and structure. Layout, colors, type and motion stay as described.
Keep all copy, image paths and links in one content file (for example `src/content.ts`), keyed by section, so the content can be swapped later without touching components.
## Design
### Colors
- Ink `#17111C` — Primary page background, dark text on Paper and Coral, footer and dialog backdrop.
- Plum `#281A32` — Hero gradient, alternate dark sections, program cards and mobile menu.
- Raised `#382443` — Class rows, form fields, drawer and elevated dark surfaces.
- Paper `#F4EEE5` — Light sections, trial form panel, pricing background and primary text on dark.
- White `#FFFCF7` — Bright headlines, portrait-card text and selected highlights.
- Coral `#FF7452` — Primary action fill, active filters, countdown accents, focus ring and small editorial marks; always pair with Ink text.
- Coral Deep `#E95C3B` — Hover and pressed state for Coral buttons and filters.
- Lilac `#C7B9FF` — Secondary accent for level pills, recital details, outlined type and links on dark; pair with Ink when used as a fill.
- Muted `#B9AFBF` — Secondary text, metadata and captions on Ink or Plum; on Paper use Ink at 68% instead.
- Rule `#4B3954` — Dark-section borders and separators; light-section rules use Ink at 16%.
### Typography
- Display: wordmark, H1, H2, large prices, program names and countdown numerals; uppercase with tight line spacing: Archivo Black (OFL), weights 400
- Text and UI: body, navigation, buttons, class rows, biographies, form labels and FAQ: Manrope (OFL), weights 400/500/600/700/800
- Mono: eyebrows, section indices, schedule times, age and level metadata, spots, reservation reference and small print: IBM Plex Mono (OFL), weights 400/500
### Layout & motion
- Spacing: 8px base unit. Container max-width 1240px, centered, side padding 40px desktop, 28px tablet and 20px under 640px. Twelve-column grid with 24px gaps. Section padding 112px desktop, 80px tablet and 64px mobile. Eyebrow: IBM Plex Mono 500 12px uppercase, letter-spacing 0.14em, with a 24px Coral line. H1: Archivo Black clamp(58px, 8.6vw, 124px), line-height 0.9, letter-spacing -0.035em. H2: Archivo Black clamp(42px, 5.8vw, 78px), line-height 0.94, letter-spacing -0.025em. H3: Manrope 800 24px / 1.2. Lead: Manrope 500 19px / 1.6, max-width 56ch. Body: Manrope 400 16px / 1.7, max-width 66ch. Buttons: minimum 48px high, pill shaped, padding 0 24px, Manrope 800 13px uppercase with 0.06em tracking. Primary is Coral with Ink text; secondary is 1px currentColor with transparent fill. Inputs are 52px high with 16px text. Every interactive element gets a 2px Coral focus outline with 3px offset.
- Radius: 24px on large photographic and content panels, 16px on class rows and small cards, 12px on inputs, and 999px only for buttons, chips, pills and status dots. Avoid nesting rounded cards inside identical rounded cards.
- Motion: Use --ease-out cubic-bezier(0.22, 1, 0.36, 1) for photographic and content reveals and --ease-beat cubic-bezier(0.76, 0, 0.24, 1) for masks, rail transitions and drawer movement.
- Motion: MaskedHeading wraps each supplied line in overflow-hidden and raises its inner span from translateY(110%) to 0 over 720ms --ease-beat, with 80ms between lines. Trigger H2s once at 25% visibility.
- Motion: Reveal moves section content from opacity 0 and translateY(22px) to rest over 650ms --ease-out when 15% visible; grids stagger children by 70ms. Never hide content permanently if IntersectionObserver is unavailable.
- Motion: The hero photograph scales from 1.07 to 1 over 1600ms on load and translates no more than 5% vertically as the hero leaves the viewport. The headline and actions enter after 120ms.
- Motion: ProgramRail translates two identical tracks linearly by -50% over 32s. Pause on hover and focus-within; expose one visually hidden static list to screen readers.
- Motion: Filter updates use Motion AnimatePresence with opacity and 10px vertical movement over 180ms; preserve layout stability and announce the result count with aria-live polite.
- Motion: Recital digits crossfade and move 8px on value changes only; seconds do not cause layout shift. Buttons translate -2px on hover and return on press. Portraits scale to 1.035 inside their crop on hover.
- Motion: The class drawer enters from the right over 360ms --ease-beat while its backdrop fades in over 180ms. Trial confirmation replaces the form with a 12px rise and 250ms fade; errors reveal without pushing the submit button off-screen.
- Motion: prefers-reduced-motion: render all content at rest, stop the rail, remove parallax, scaling, stagger and digit movement, disable smooth scrolling, and use only a 100ms opacity change for menus and dialogs. Countdown values still update accessibly without animation.
- Imagery: Use only the six generated editorial dance photographs listed under Assets. They form one shoot: documentary movement photography, deep aubergine shadows, warm coral rim light, soft lilac fill, unbranded dark rehearsal clothes, subtle film grain and clean studio architecture. The hero is a wide ensemble scene with generous negative space, never a close-up face. The class and recital photographs show full-body movement with faces turned away, obscured by pose or naturally motion-softened. The three instructor images are professional portraits of explicitly fictional adults, not resembling any real individual, with varied age and ethnicity and consistent chest-up framing. Do not substitute real dancers, celebrities, stock portraits, initials-only instructor cards or unrelated gym photos. Apply object-fit cover and the listed object-position; retain natural skin texture. All other graphics are code-drawn: the wordmark is text, the favicon uses two offset beat bars, the program rail and pills are CSS, availability tracks are divs, and the trial-pass perforation is CSS. Icons come only from lucide-react at 1.75px stroke width. No readable signage, clothing logos or brand marks in any image.
## Pages & Sections
### Home (`index.html`)
1. **Content file and studio data** — All copy below uses the defaults: [BRAND] Offbeat Dance Assembly, [CITY] Austin, Texas, [STYLES] Hip-Hop, Contemporary, Jazz, [AUDIENCE] dancers ages 7 and up, from complete beginners to experienced movers, and [RECITAL_DATE] 2027-06-12T19:00:00-05:00. Put all content in src/content.ts and rewrite every headline, program, session, instructor specialty, event detail, price explanation and FAQ when variables change, keeping the same counts and approximate lengths: 3 programs, 3 instructors, 24 weekly sessions, 3 passes and 6 FAQs. All identities and business details are invented. Address: 18 Cadence Alley, [CITY]. Phone: (512) 555-0148. Email: hello@ + emailDomain. Hours: Mon–Fri 15:00–21:30, Sat 09:00–17:00, Sun 12:00–17:00. Event time zone for the default: America/Chicago. The recital is 'In Full Motion', held in the converted main studio at 19:00 on [RECITAL_DATE]; doors 18:15, three age-band showcases, 120 seats, free for participating families. Default prices: single class $24; eight-class pass $152, valid three months, $19 per class; monthly unlimited $168, month to month, equivalent to $5.25 per class at eight visits per week. Free trial: one First class or Beginner session, no card. Youth capacity 14, all others 16. Cancellation: cancel or move a reservation up to six hours before class at the desk or by phone; no online cancellation is faked. Instructor roster: maya — Maya Rivera, Hip-Hop lead, 11 years teaching, 'We learn the groove before the trick. Count it out, then make it yours.'; jules — Jules Bennett, Jazz and performance coach, 9 years teaching, 'Clean lines are useful. A little personality is required.'; elena — Elena Park, Contemporary and foundations coach, 14 years teaching, 'Technique should give you more choices, not make you afraid to move.' Their photographs are fictional placeholders, not real instructors. Link each instructor's 'View classes' button to classes.html?style=<their style slug>.
Layout: No visual output. Export typed studio, programs, instructors, sessions, passes, faqs, visit and images objects. Keep dates as ISO strings in content, never scattered through components.
Motion: n/a
2. **Header and mobile menu (shared)** — Left: [BRAND] in Archivo Black 18px uppercase on two maximum lines, preceded by two offset vertical bars (one Coral, one Lilac) drawn in CSS; link to ./index.html. Desktop nav: 'Programs' → ./index.html#programs, 'Timetable' → ./classes.html, 'Instructors' → ./index.html#instructors, 'Passes' → ./index.html#passes. Right: primary 'Free trial' → ./index.html#trial. Current page gets a Coral underline. Under 860px show a 48px Menu button and a small Coral 'Trial' button. The full-screen Plum mobile menu lists the four links in Archivo Black 38px, then address, phone and a Free trial button; Escape and link selection close it, body scroll locks and focus returns to the trigger.
Layout: Fixed top, height 76px desktop and 68px mobile, z-index 40. Transparent over the home hero, then Ink at 94% with backdrop blur and a Rule bottom border after 32px. Always solid on classes.html. Container-aligned flex row.
Motion: Header background and border transition 200ms. Mobile menu wipes down with clip-path over 320ms --ease-beat and links rise with 45ms stagger; reduced motion uses opacity only.
3. **Hero (#top)** — Full-width background hero-dance.webp, positioned 64% 50%, with a left-to-right Ink gradient (94% at left, 52% mid, 18% right) and a bottom Ink fade. Eyebrow: '[CITY] · CLASSES FOR AGES 7+'. H1 in three lines: 'FIND YOUR' / 'BEAT.' / 'OWN THE ROOM.' with 'BEAT.' in Coral and the final line no wider than nine columns. Lead: '[BRAND] teaches [STYLES] to [AUDIENCE]. Small classes, clear levels and a first session that costs nothing but an hour.' Buttons: primary 'Book a free class' → #trial; secondary on-photo 'Explore the timetable' → ./classes.html. Bottom ledger: '24' / 'weekly classes'; '3' / 'dance styles'; '16' / 'dancers max'; '$0' / 'your first class'. A small Lilac-outlined note above the ledger reads 'Next recital · In Full Motion' and links to #recital.
Layout: min-height 100svh, minimum 720px desktop and 740px mobile. Content sits in the container with top padding 156px and bottom ledger anchored at bottom. Text spans columns 1–9 on desktop; H1 max-width 1080px. Ledger is a four-column row with 1px White/20% top border and 24px vertical padding. Under 700px, use a stronger full-width Ink/55% overlay, H1 56px, stacked full-width buttons and a 2×2 ledger; keep the image visible on the right and upper half.
Motion: Photo scale and headline masks as described in Design. Ledger items fade up after the actions with 60ms stagger; no perpetual bouncing or cursor follower.
4. **Program rail** — A Coral band carrying the sequence 'HIP-HOP · CONTEMPORARY · JAZZ · FIRST CLASS FREE · AGES 7+ · ALL BODIES WELCOME ·' derived from [STYLES]. Set items in Archivo Black 30px uppercase Ink, with small Ink four-point stars drawn in CSS between them. Provide a static accessible list of the same facts outside the animated aria-hidden tracks.
Layout: Full bleed, 68px high, rotate the entire band -1.2deg and scale x 1.02 so it reaches both edges; add 24px of negative margin into adjacent dark sections. Overflow hidden with two identical tracks.
Motion: 32s linear infinite translation, paused on hover/focus and replaced by a wrapped static row under reduced motion.
5. **Programs (#programs)** — Eyebrow '01 · FIND YOUR CLASS'. H2 'THREE WAYS IN.' Lead: 'Start with the style that makes you turn the music up. Every program has a first-class session, and every instructor shows the steps before asking for polish.' Three asymmetric program cards derived from [STYLES]: 1) Hip-Hop — index 01, 'GROOVE / FOUNDATIONS / FREESTYLE' metadata, description 'Footwork, bounce, isolations and short combinations taught one eight-count at a time. Youth groups learn the same foundations without the late finish.' — '7–12 · 13–17 · 18+' and 'First class through Advanced'. 2) Contemporary — index 02, 'FLOORWORK / BREATH / PHRASES', description 'A clear technical warm-up moves into traveling phrases and floorwork. Beginners get smaller ranges and a slower count; experienced dancers get more complexity, not more speed for its own sake.' — same age bands, levels. 3) Jazz — index 03, 'RHYTHM / LINES / PERFORMANCE', description 'Sharp accents, turns and expansive combinations with room for character. Recital choreography stays optional and every class works as a standalone session.' — same age bands, levels. Each card has a large outlined index, three horizontal rhythm bars whose widths are 42/68/52%, 58/36/72% and 76/46/60%, and a 'See [style] classes' link to ./classes.html?style=<slug>. Use class-contemporary.webp only as the wide image beneath the Contemporary description, cropped 4:3 on desktop; the other two cards use their code-drawn rhythm bars, not substitute photos.
Layout: Ink background. Header is 7 columns for H2 and 4 for lead, offset 1. Cards form a 12-column grid: card one columns 1–5, card two columns 6–12, card three columns 3–9, producing deliberate asymmetry. Cards have 1px Rule borders, Plum fill, 28px padding and 24px radius. Under 800px, stack in order with no offsets and keep the Contemporary photograph at 16:10.
Motion: Cards reveal in order. On hover, the border turns Lilac, the index fills Coral from transparent, and rhythm bars grow from scaleX 0.65 to 1 with transform-origin left over 260ms.
6. **Instructors (#instructors)** — Eyebrow '02 · THE PEOPLE IN THE ROOM'. H2 'CLEAR CUES. GOOD MUSIC.' Lead: 'Three teachers, three different routes into dance. They correct the step, explain the why and learn every dancer's name.' Three profile cards: teacher-maya.webp — Maya Rivera — 'HIP-HOP LEAD · 11 YEARS TEACHING' — bio 'Maya builds combinations from the groove outward. Her beginner classes are music-first, low-pressure and famous for ending with one more run than planned.' — quote 'We learn the groove before the trick. Count it out, then make it yours.' — 'Teaches Hip-Hop · Mon–Sat'; teacher-jules.webp — Jules Bennett — 'JAZZ & PERFORMANCE · 9 YEARS' — bio 'Jules mixes clean technique with theater instincts. He breaks turns into foot, spot and landing, then helps each dancer add a little character.' — quote 'Clean lines are useful. A little personality is required.' — 'Teaches Jazz · Mon–Sat'; teacher-elena.webp — Elena Park — 'CONTEMPORARY & FOUNDATIONS · 14 YEARS' — bio 'Elena teaches floorwork without the mystery and progressions without the rush. Her first-class sessions include a full explanation of the room, the warm-up and what to wear.' — quote 'Technique should give you more choices, not make you afraid to move.' — 'Teaches Contemporary · Mon–Sat'. Alt text identifies each as a fictional instructor portrait. Button per card: 'View [style] classes' → ./classes.html?style=<style slug>.
Layout: Paper background with Ink text. Header spans 7 columns, lead 4. Three equal cards with 24px gaps. Portrait 3:4 at the top, 24px radius, name Manrope 800 26px, mono specialty in Ink/65%, bio and a Lilac-filled quote block with Ink text. On dark-to-light image edges use no text overlay. Under 900px use one column with a 38% portrait column beside text where width permits; below 600px return to stacked cards.
Motion: Reveal cards with 80ms stagger. Portrait scales to 1.035 on hover; the instructor link arrow moves 4px right.
7. **Recital countdown (#recital)** — Use recital-stage.webp as a large visual panel with a small mono label 'NEXT RECITAL · MAIN STUDIO'. Beside it: eyebrow '03 · SAVE A SEAT', H2 'IN FULL MOTION.' Body: 'Three age bands. Twenty-four short pieces. One night where the practice room becomes a stage. Participating is optional; cheering is strongly encouraged.' Event line formats [RECITAL_DATE] in the supplied event offset as 'Saturday, June 12 · 7:00 PM CDT' for the defaults, followed by 'Doors 6:15 PM · 18 Cadence Alley · 120 seats'. Four countdown cells: DAYS, HOURS, MINUTES, SECONDS, calculated every second from Date.parse([RECITAL_DATE]) with tabular numerals and fixed widths. The event date and its time zone abbreviation come from explicit event-offset formatting, not the visitor's zone. After the target passes, show 00 values and replace the button with 'Ask about the next recital' → mailto:hello@emailDomain; never show negative values. Primary 'Try a class before curtain' → #trial; secondary 'See class times' → ./classes.html. Small print: 'Recital participation is optional and included in regular classes. Tickets are free for participating families; no online ticket sale.'
Layout: Plum background. Twelve-column grid: photo columns 1–7 with 16:10 crop and 24px radius; text columns 8–12. Countdown is a four-column grid below the event line, each cell separated by Rule vertical borders, numerals Archivo Black clamp(34px, 4vw, 56px) Coral and labels mono 10px Muted. Under 900px stack photo then text; at 390px use a 2×2 countdown grid to prevent tiny numbers.
Motion: Photo reveals with a clip-path inset from bottom over 700ms. Digits crossfade on changes; no rolling-animation backlog on the seconds cell. Reduced motion removes both.
8. **Pricing passes (#passes)** — Eyebrow '04 · PASSES'. H2 'START SMALL. KEEP MOVING.' Lead: 'Try one class first. If the room feels right, choose the pass that matches your actual week.' Three cards: 'Single class' — $24 — 'One 45–75 minute session, any style or level that fits.' — features ['One class reservation', 'All props and practice space included', 'No enrollment fee'] — math '$24 / CLASS'; 'Eight-class pass' — $152 — tag 'BEST FOR 1–2 CLASSES A WEEK' — 'Eight classes to use within three months, across any style.' — features ['$19 per class', 'Share with one family member', 'Unused classes expire after 3 months'] — math '$19 / CLASS · SAVE $40'; 'Monthly unlimited' — $168 — 'Every regular class, every week, with month-to-month billing handled at the studio.' — features ['Unlimited regular classes', 'Two guest passes each month', 'Pause once per year for up to 30 days'] — math '$5.25 / CLASS AT 8 VISITS A WEEK'. Buttons all read 'Start with a free class' and link to ./index.html?plan=single|eight|unlimited#trial. The trial form shows 'Pass you are considering: …' from this query without charging. Footnote: 'Passes are purchased at the studio after your trial. Monthly plans need 30 days notice to cancel. Recital participation carries no costume fee.'
Layout: Paper background, Ink text. Three cards, equal height, 24px gaps. Ink text with 1px Ink/16% border and White fill; middle card has a 2px Coral border and translates up 12px on desktop. Price Archivo Black 58px, math IBM Plex Mono 12px in a Coral pill with Ink text, features Manrope 15px with Check icons. Buttons at the bottom. Under 900px stack, remove lift and show the middle card first only if DOM order remains logical; preferred order remains Single, Eight, Monthly at every size.
Motion: Cards reveal with 70ms stagger. Hover raises non-featured cards 4px; the math pill changes to Lilac, never animates prices.
9. **Free-trial booking (#trial)** — Two-column section. Left: eyebrow '05 · YOUR FIRST CLASS', H2 'COME AS YOU ARE.' Lead: 'Choose a First class or Beginner session. We will have a place marked, a teacher expecting you, and no card reader waiting by the door.' Checklist: 'One free trial per dancer', 'Comfortable clothes and water are enough', 'Arrive 15 minutes early; under-18s bring a parent or guardian on the first visit'. Right: a Paper form panel titled 'RESERVE A FREE CLASS'. Fields: dancer first name (required, 2–40 characters); parent or guardian name (shown and required only when the selected session age is 7–12 or 13–17); email (required, standard email pattern); session select grouped by day, including only non-full First class and Beginner sessions, labels such as 'Wed 6:45 PM · Adult Hip-Hop · 7 spots'; experience radio group 'Brand new', 'A few classes', 'Returning after a break' (required); optional notes textarea max 240 characters with live count; required checkbox 'I understand this reservation is saved on this device and I should show the confirmation at the front desk.' Validate on blur after touch and on submit, set aria-invalid and describedby, show concise errors and focus the first invalid field. ?class=<session id> preselects a valid eligible session; an unknown or ineligible id leaves the first eligible session selected without an error. ?plan=single|eight|unlimited displays the matching consideration line. Valid submit uses preventDefault, waits 500ms only for visual feedback, saves { reservation id, session id, dancer first name, created from RECITAL-independent current timestamp } to localStorage key brandSlug + ':trial', and replaces the form with TrialPass. TrialPass: Coral label 'FREE CLASS RESERVED', 'SEE YOU ON THE FLOOR, {FIRST NAME}.', class name, day and start–end time, instructor, address, and reservation reference '<two-letter brand prefix>-' + four digits derived from a stable hash of session id + lowercase email. Caption: 'Saved on this device. Screenshot or print this pass and bring it to the desk. No payment has been taken and no email has been sent.' Buttons: 'Print pass' calls window.print using a stylesheet that prints only the pass; 'Choose another class' resets state and removes the saved reservation after confirmation. An existing saved reservation loads the pass on revisit. Nothing is transmitted.
Layout: Ink background. Twelve-column grid: left columns 1–5 sticky at top 112px on desktop, form columns 7–12. Panel has 24px radius and 36px padding (24px mobile). Two-column name/email rows only above 520px; labels 13px Manrope 700, fields White fill with Ink text and Ink/20% border. Error text is #9E321F on Paper with AlertCircle icons. Confirmation has a dashed divider, CSS side notches and a mono reference. Mobile keeps the explanatory content before the form and no sticky positioning.
Motion: Errors use a 160ms height/opacity reveal. Submit spinner is a simple LoaderCircle for 500ms. TrialPass rises exactly 12px over 250ms. Print and reset have no motion.
10. **First-visit FAQ (#faq)** — Eyebrow '06 · BEFORE YOU ARRIVE'. H2 'GOOD QUESTIONS. STRAIGHT ANSWERS.' Six accordions: 1) 'I have never danced. Which class should I pick?' — 'Choose any session marked First class. The warm-up, basic vocabulary and combination are taught from zero. Beginner is also suitable if you are comfortable learning with people who have taken a few classes.' 2) 'What should I wear?' — 'Clothes that let you bend and stretch, clean sneakers for Hip-Hop and Jazz, and socks or bare feet for Contemporary. Bring water. You do not need special dance shoes for a trial.' 3) 'How do age groups work?' — 'Youth is 7–12, Teen is 13–17 and Adult is 18+. Use the age filter on the timetable; dancers stay with their age band even when the choreography is shared.' 4) 'Does my child have to join the recital?' — 'No. Recital choreography is taught in regular classes, but performing is optional. Dancers who prefer not to perform still learn the complete combination.' 5) 'What if a class is full?' — 'Full sessions are marked on the timetable. Call the desk to join the waitlist; the site does not pretend to hold a place that is unavailable.' 6) 'Can I cancel or move my trial?' — 'Yes, up to six hours before class. Call (512) 555-0148 and the desk will move it. If you simply need a different session on this device, choose another class on the confirmation pass.' First item open by default; only one open at a time with aria-expanded and aria-controls.
Layout: Paper background, Ink text. Left H2 columns 1–5 sticky on desktop; right accordion columns 7–12. Questions are full-width buttons with 24px vertical padding, Manrope 800 18px and a Plus icon. Answers max-width 62ch, Ink/72%. Under 800px stack with no sticky.
Motion: Accordion height and opacity animate 220ms --ease-out; Plus rotates 45 degrees. Reduced motion opens instantly.
11. **Visit and footer (shared)** — Visit band on Plum: 'FIND THE ROOM' — '18 Cadence Alley', '[CITY]', 'Second floor; stairs and a lift open onto the same landing.'; 'STUDIO HOURS' — the four hour lines from content; 'CALL OR WRITE' — '(512) 555-0148' tel link and 'hello@' + emailDomain mailto. Beside the text, a code-drawn SVG neighborhood diagram: three thin Lilac street lines labeled 'CADENCE ALLEY', 'WILLOW WALK' and 'EIGHTH ST', a Coral square for the studio and a simple walking route; no map tiles or external map service. Footer on Ink: large [BRAND] in Archivo Black clamp(42px, 7vw, 96px), then four columns: Programs (three filtered timetable links), Visit (address and phone), Classes (Timetable, Free trial, Passes), First visit (FAQ, Recital). Bottom line: '© [BRAND] · Practice counts.' left and optional [CREDIT] link right. No current year and no social-media logos.
Layout: Visit padding 80px, grid with three information columns occupying 1–7 and map 8–12, aspect 4:3, 1px Rule border and 24px radius. Footer padding 72px 0 32px, large wordmark above a Rule, then a four-column grid. At 760px all grids stack and the map follows the address details.
Motion: Map route draws using stroke-dashoffset once on entry over 700ms; static under reduced motion.
### Class timetable (`classes.html`)
1. **Timetable data and behavior** — Render exactly 24 sessions from src/content.ts, shared with the home form. Each record: id, day, 24-hour start time, style slug, title, ageBand (youth 7–12, teen 13–17, adult 18+), level (first-class, beginner, intermediate, advanced), duration, instructor id, booked, capacity. Monday: mon-1630 16:30 hip-hop 'Youth Hip-Hop Foundations' youth first-class 45m maya 8/14; mon-1730 17:30 jazz 'Teen Jazz Basics' teen beginner 60m jules 11/16; mon-1845 18:45 contemporary 'Adult Contemporary Foundations' adult beginner 75m elena 12/16; mon-2015 20:15 hip-hop 'Adult Hip-Hop Combinations' adult intermediate 60m maya 14/16. Tuesday: tue-1630 16:30 contemporary 'Youth Contemporary Start' youth first-class 45m elena 9/14; tue-1730 17:30 hip-hop 'Teen Hip-Hop Combinations' teen intermediate 60m maya 13/16; tue-1845 18:45 jazz 'Adult Jazz Basics' adult beginner 60m jules 10/16; tue-2000 20:00 contemporary 'Adult Contemporary Repertoire' adult advanced 75m elena 16/16. Wednesday: wed-1630 16:30 jazz 'Youth Jazz Basics' youth beginner 45m jules 8/14; wed-1730 17:30 contemporary 'Teen Contemporary Foundations' teen beginner 60m elena 12/16; wed-1845 18:45 hip-hop 'Adult First Hip-Hop' adult first-class 60m maya 9/16; wed-2000 20:00 jazz 'Adult Jazz Combinations' adult intermediate 60m jules 15/16. Thursday: thu-1630 16:30 hip-hop 'Youth Hip-Hop Basics' youth beginner 45m maya 10/14; thu-1730 17:30 contemporary 'Teen Contemporary Phrases' teen intermediate 60m elena 14/16; thu-1845 18:45 jazz 'Adult First Jazz' adult first-class 60m jules 7/16; thu-2000 20:00 hip-hop 'Adult Hip-Hop Repertoire' adult advanced 60m maya 16/16. Friday: fri-1630 16:30 contemporary 'Youth Contemporary Basics' youth beginner 45m elena 11/14; fri-1730 17:30 jazz 'Teen Jazz Combinations' teen intermediate 60m jules 12/16; fri-1845 18:45 hip-hop 'Adult Hip-Hop Basics' adult beginner 60m maya 13/16; fri-2000 20:00 contemporary 'Adult Contemporary Combinations' adult intermediate 75m elena 9/16. Saturday: sat-0930 09:30 hip-hop 'Youth First Hip-Hop' youth first-class 45m maya 6/14; sat-1030 10:30 jazz 'Teen Jazz Basics' teen beginner 60m jules 9/16; sat-1145 11:45 contemporary 'Adult First Contemporary' adult first-class 75m elena 8/16; sat-1315 13:15 jazz 'Adult Jazz Repertoire' adult advanced 60m jules 14/16. Sunday has no regular sessions and shows 'Sunday · Rest and reset' with the studio's 12:00–17:00 front-desk hours. Compute end time from start + duration and spots from capacity − booked. Spots label: 0 = 'Full', 1–3 = 'Only N spots', otherwise 'N spots'. First-class and beginner sessions that are not full show a Coral 'Trial eligible' pill. If variables change, rename sessions and rewrite descriptions for the three new styles while preserving days, times, age bands, levels, counts and capacities.
Layout: No visual output of its own. src/lib/schedule.ts exports filteredSessions(filters), groupedByDay(sessions), spotsLabel(session), isTrialEligible(session), and safe query parsing. Filters combine style AND age AND level. Unknown query values are ignored and replaced with canonical values; no blank page or exception.
Motion: n/a
2. **Timetable masthead** — Shared solid Header. Eyebrow 'THE WEEK · 24 CLASSES · AGES 7+'. H1 'PICK A TIME. FIND YOUR PEOPLE.' Lead: 'Filter by style, age and level. Open a class for the full picture, or reserve a free trial where you see the Coral pill.' Right-side summary panel: 'FIRST TIME HERE?' with 'Start with any First class or Beginner session. Your first one is free.' and primary 'Book a free trial' → ./index.html#trial. Below, a wide crop of class-contemporary.webp at 16:5 desktop and 16:8 mobile with a small caption 'Contemporary foundations · Main room'.
Layout: Ink background, padding-top 156px including fixed header. Masthead grid: text columns 1–8, summary columns 10–12 on Raised with 24px padding and radius. H1 uses clamp(54px, 7.4vw, 104px) and max-width 1000px. Image band margin-top 56px, full container width, 24px radius. Under 800px stack summary below lead.
Motion: H1 masked lines on load. Summary and image fade up once; no autoplay video.
3. **Filters** — Three labeled single-select chip groups: STYLE = 'All styles' plus the three names parsed from [STYLES]; AGE = 'All ages', '7–12', '13–17', '18+'; LEVEL = 'Any level', 'First class', 'Beginner', 'Intermediate', 'Advanced'. Selected chips are Coral with Ink text and aria-pressed true. Live result count 'SHOWING 24 OF 24 CLASSES' and a Clear button appear after the groups; Clear shows only when a filter is active. Sync state to ?style=hip-hop&age=adult&level=first-class using history.replaceState, and read it on load so program and instructor links work. Preserve all three filters when opening and closing a class drawer. With no results, render 'No classes match all three filters.' and buttons 'Clear filters' and 'Ask the desk' (tel link), not an empty grid.
Layout: Sticky below header at top 76px desktop and 68px mobile, z-index 30, Ink 96% with backdrop blur and Rule bottom border. Container rows with labels in mono 11px Muted and 36px-high chips. Under 800px each group is its own horizontal overflow row with no body-level horizontal scrolling; result count sits below the groups.
Motion: Chips change fill over 140ms. Result count crossfades. The filter panel itself never shifts height when Clear appears; reserve its space.
4. **Week list** — Seven day groups Monday through Sunday. Day heading contains full day name in Archivo Black 30px and a mono class count reflecting filters. Each matching session is a button row: start–end time in IBM Plex Mono 13px; title in Manrope 800 18px with style name in small Muted text below; age and level pills; instructor name; spots label plus a 72px availability track (Coral fill for booked/capacity, Rule background); ChevronRight. Add 'Trial eligible' beside the title when appropriate. Full rows remain clickable so the drawer can explain the waitlist. Nonmatching rows are removed, and days with no matches are omitted except Sunday when no filters are active. The current weekday gets a small Lilac 'TODAY' label based on the visitor clock, but no current date is displayed.
Layout: Container max-width 1240px, padding 56px 0 96px. Day group has 1px Rule top border, heading padding 24px 0 12px. Class row uses CSS grid columns 110px minmax(240px, 2fr) minmax(160px, 1fr) 150px 150px 24px, gap 20px, align center, Raised background, 16px radius, 18px padding, margin-bottom 8px. Under 1080px hide the separate instructor column and place instructor below title; grid becomes 88px 2fr 1fr 120px 20px. Under 700px each row becomes a two-column card: time and title first, age/level chips next, spots and ChevronRight aligned at bottom. No table-like horizontal scrolling.
Motion: Rows reveal with 20ms stagger on first view, then filter changes use 180ms opacity/y transitions without animating layout height. Hover/focus border turns Coral and ChevronRight moves 3px.
5. **Class detail drawer** — Clicking a row opens a right drawer with the selected class and mirrors ?class=<session id> in the URL while retaining filters; a valid class query opens it on load. Header: style slug label, day and start–end time, close button. Title, then pills for age, level, duration and capacity. Description is composed from the program and level: foundations describe terminology and warm-up, combinations describe learning a short phrase, repertoire describes a four-week optional recital phrase with no requirement to perform. 'WHAT TO EXPECT' lists '15-minute guided warm-up', 'Steps demonstrated at two speeds', 'A short combination with options', 'Water breaks whenever you need one'. 'WHAT TO BRING' varies by style: Hip-Hop and Jazz = clean sneakers, comfortable clothes and water; Contemporary = socks or bare feet, layers for floorwork and water. Instructor block uses the matching portrait cropped to 64px square, full name and specialty; this small portrait is decorative with empty alt because the name is adjacent. Availability track with exact 'N of 16 booked · N spots left'. Footer for eligible non-full classes: primary 'Reserve this as my free trial' → ./index.html?class=<id>#trial; other non-full classes: primary 'Ask about this class' → tel link and caption 'Free trials are available in First class and Beginner sessions.' Full classes: primary 'Join the waitlist by phone' → tel link and no fake online waitlist. Secondary 'Close'.
Layout: Fixed right panel width 460px, full height, Ink background, Rule left border, independent scroll, sticky header and footer; 100vw under 560px. Backdrop Ink at 72%. role dialog, aria-modal, labelled by title. Focus moves to close on open, traps Tab, Escape and backdrop close, focus returns to the originating row and body scroll locks.
Motion: Drawer slides 100% → 0 over 360ms --ease-beat, backdrop fades 180ms. Content enters after the panel with 40ms stagger; reduced motion uses only a 100ms fade.
6. **Schedule help and shared footer** — Three plain help blocks above the footer: Clock icon 'ARRIVE 15 MINUTES EARLY' — 'The teacher will show you the room and where to put your things.'; Users icon 'SIXTEEN MAX, FOURTEEN FOR YOUTH' — 'Capacity is fixed so everyone can see the instructor and cross the floor safely.'; CalendarCheck icon 'NEED A DIFFERENT DAY?' — 'Call (512) 555-0148 up to six hours before class and we will move your reservation.' Then the same Visit and Footer component as index.html.
Layout: Plum background, three columns with 24px gaps, each separated by a Rule top line rather than floating cards. Under 760px stack with 32px gaps.
Motion: Simple Reveal, no looping effects.
## Assets
- image: Six template images generated for this design. Download each exact URL into the listed local path with curl -L -o before building: https://media.vibefather.ai/assets/f6760505-d224-4c8b-94b0-79a9a41365ad/hero-dance.webp → public/images/hero-dance.webp (home hero; object-position 64% 50%; alt 'A fictional adult dance ensemble moving across a dark studio under coral and lilac light'); https://media.vibefather.ai/assets/f6760505-d224-4c8b-94b0-79a9a41365ad/class-contemporary.webp → public/images/class-contemporary.webp (Contemporary program card and timetable masthead; object-position 50% 45%; alt 'Two fictional contemporary dancers practicing a wide floorwork phrase'); https://media.vibefather.ai/assets/f6760505-d224-4c8b-94b0-79a9a41365ad/recital-stage.webp → public/images/recital-stage.webp (recital panel; object-position 50% 50%; alt 'Fictional dancers seen from behind during a recital rehearsal'); https://media.vibefather.ai/assets/f6760505-d224-4c8b-94b0-79a9a41365ad/teacher-maya.webp → public/images/teacher-maya.webp (Maya profile and drawer portrait; alt 'Maya Rivera, a fictional hip-hop instructor, in the studio'); https://media.vibefather.ai/assets/f6760505-d224-4c8b-94b0-79a9a41365ad/teacher-jules.webp → public/images/teacher-jules.webp (Jules profile and drawer portrait; alt 'Jules Bennett, a fictional jazz instructor, in the studio'); https://media.vibefather.ai/assets/f6760505-d224-4c8b-94b0-79a9a41365ad/teacher-elena.webp → public/images/teacher-elena.webp (Elena profile and drawer portrait; alt 'Elena Park, a fictional contemporary instructor, in the studio'). Credit every one as 'Generated by VibeFather with qwen-image-3.0-pro, redistributable with this template'.
- image: Create ASSETS.md at the project root with a table of path, source URL, author and license. Give each of the six images its exact media.vibefather.ai URL and the exact credit 'Generated by VibeFather with qwen-image-3.0-pro, redistributable with this template'. Also list @fontsource/archivo-black, @fontsource-variable/manrope and @fontsource/ibm-plex-mono as OFL-1.1 and lucide-react as ISC. No other photographs or image services.
- icon: Use lucide-react only for Menu, X, ArrowRight, ChevronRight, Plus, Check, Clock, Users, CalendarCheck, AlertCircle, LoaderCircle, MapPin, Phone, Mail and Printer; stroke width 1.75, inherit color. public/favicon.svg is hand-written with viewBox 0 0 32 32: a 32×32 rounded-square Ink background and two 6×18 beat bars at x 8/y 8 Coral and x 18/y 6 Lilac, with no letters. The site wordmark remains plain text plus two CSS bars; no studio logo asset.
- font: Self-host Archivo Black, Manrope Variable and IBM Plex Mono through the three Fontsource packages named in Setup. Import only the listed weights so Vite bundles woff2 files locally; never request a font CDN.
- image: Draw in code: header bars, favicon, program rhythm bars, availability tracks, countdown cells, CSS ticket notches and the SVG neighborhood diagram. These are original simple geometry, not copied illustrations or branded iconography.
## Don'ts
- No backend, server code, API routes, databases, authentication, payment service, email service, analytics or third-party API. Filters, countdown, reservation confirmation and persistence are entirely client-side; never claim an email was sent or payment was taken.
- Use the fixed Vite 5 + React 18 + TypeScript + Tailwind CSS 3.4 + Motion stack and two HTML entries. No router, UI kit, calendar library, countdown package or form library unless the user explicitly changes the stack.
- All internal navigation uses relative file links such as ./index.html, ./classes.html, ./index.html#trial, ./classes.html?style=hip-hop and ./index.html?class=wed-1845#trial. Never use bare directories or leading-slash routes. Invalid query values fall back safely without console errors.
- Self-host every script, style, font, icon and image. No CDN scripts or links, Google Fonts, Adobe Fonts, remote map tiles, analytics, hotlinked photos or placeholder-image services. Download the six listed images into public/images/ before the build.
- No Unsplash, Pexels, Pixabay, Google Images, CC BY-NC or CC BY-SA assets. Do not substitute real studio, dancer or instructor photography. All six generated photos and all three instructor identities are fictional placeholders and must not resemble real individuals.
- No real studio names, logos, slogans, schedules, prices or contact details; no recognizable dancers or celebrities; no real performance, venue, franchise or class-program branding; no branded clothing, readable signage or copied imagery.
- No reference site's code, copy, illustrations, mascots, custom fonts or unique icons. Use only the original layouts and simple code-drawn geometry described here. Dependencies must retain the listed permissive licenses; no Aceternity UI, Tailwind Plus, purchased template or unlicensed source.
- Only Archivo Black, Manrope and IBM Plex Mono through Fontsource (OFL). No commercial fonts and no font-hosting CDN.
- Production build is npm run build to dist/ with Vite base './', minification, sourcemap false and no src/ copied into dist/. Keep dist/ under 20 MB, target under 12 MB.
- Do not add SEO work: no meta descriptions, Open Graph tags, JSON-LD, sitemap or keyword-stuffed copy. Only the specified plain title, theme color and favicon are required.
- No body-shaming, transformation promises, elite-dancer gatekeeping or medical claims. Recital participation stays optional. All people, biographies, prices, availability and reviews, if any are later added, are invented sample content.
- Respect prefers-reduced-motion exactly as specified. Stop the rail, remove masks, parallax, scales and staggers, and keep all information visible. The countdown must never produce negative numbers and must use tabular fixed-width values.
- The site must work at 1440×900 and 390×844 with zero console errors and no page-level horizontal overflow. Timetable chips may scroll within their own rows; class rows and the countdown must reflow on mobile.
- All controls are keyboard reachable with visible focus. Chips expose aria-pressed, accordions aria-expanded, filter results aria-live, the drawer and mobile menu trap and restore focus, and form errors use role alert and associated descriptions.
- Keep every string, price, time, image path and sample record in src/content.ts. No lorem ipsum, filler or contradictory hard-coded brand details in components. Rewrite all default-specific content when variables change.
- Do not display the current calendar date or a copyright year. The repeating timetable may mark TODAY by weekday, and only the configured fictional recital event displays its event date.
---
— Prompt by VibeFather · https://vibefather.ai/t/dance-studio-website · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown
Free for personal projects under CC BY-NC 4.0. Commercial use comes with Pro.
DESIGN.md
The design system on its own — colors, type, spacing and motion. Apply this look to a project you already have.
---
name: "Dance Studio Website"
colors:
ink: "#17111C"
plum: "#281A32"
raised: "#382443"
paper: "#F4EEE5"
white: "#FFFCF7"
coral: "#FF7452"
coral_deep: "#E95C3B"
lilac: "#C7B9FF"
muted: "#B9AFBF"
rule: "#4B3954"
typography:
display_wordmark_h1_h2_large_prices_program_names_and_countdown_numerals_uppercase_with_tight_line_spacing: { family: "Archivo Black", weights: [400] }
text_and_ui_body_navigation_buttons_class_rows_biographies_form_labels_and_faq: { family: "Manrope", weights: [400, 500, 600, 700, 800] }
mono_eyebrows_section_indices_schedule_times_age_and_level_metadata_spots_reservation_reference_and_small_print: { family: "IBM Plex Mono", weights: [400, 500] }
spacing: "8px base unit. Container max-width 1240px, centered, side padding 40px desktop, 28px tablet and 20px under 640px. Twelve-column grid with 24px gaps. Section padding 112px desktop, 80px tablet and 64px mobile. Eyebrow: IBM Plex Mono 500 12px uppercase, letter-spacing 0.14em, with a 24px Coral line. H1: Archivo Black clamp(58px, 8.6vw, 124px), line-height 0.9, letter-spacing -0.035em. H2: Archivo Black clamp(42px, 5.8vw, 78px), line-height 0.94, letter-spacing -0.025em. H3: Manrope 800 24px / 1.2. Lead: Manrope 500 19px / 1.6, max-width 56ch. Body: Manrope 400 16px / 1.7, max-width 66ch. Buttons: minimum 48px high, pill shaped, padding 0 24px, Manrope 800 13px uppercase with 0.06em tracking. Primary is Coral with Ink text; secondary is 1px currentColor with transparent fill. Inputs are 52px high with 16px text. Every interactive element gets a 2px Coral focus outline with 3px offset."
radius: "24px on large photographic and content panels, 16px on class rows and small cards, 12px on inputs, and 999px only for buttons, chips, pills and status dots. Avoid nesting rounded cards inside identical rounded cards."
---
# Dance Studio Website — Design System
Apply this design system to an existing project. It describes the look and feel only; for the full site, use prompt.md.
## Colors
- **Ink** `#17111C` — Primary page background, dark text on Paper and Coral, footer and dialog backdrop.
- **Plum** `#281A32` — Hero gradient, alternate dark sections, program cards and mobile menu.
- **Raised** `#382443` — Class rows, form fields, drawer and elevated dark surfaces.
- **Paper** `#F4EEE5` — Light sections, trial form panel, pricing background and primary text on dark.
- **White** `#FFFCF7` — Bright headlines, portrait-card text and selected highlights.
- **Coral** `#FF7452` — Primary action fill, active filters, countdown accents, focus ring and small editorial marks; always pair with Ink text.
- **Coral Deep** `#E95C3B` — Hover and pressed state for Coral buttons and filters.
- **Lilac** `#C7B9FF` — Secondary accent for level pills, recital details, outlined type and links on dark; pair with Ink when used as a fill.
- **Muted** `#B9AFBF` — Secondary text, metadata and captions on Ink or Plum; on Paper use Ink at 68% instead.
- **Rule** `#4B3954` — Dark-section borders and separators; light-section rules use Ink at 16%.
## Typography
- **Display: wordmark, H1, H2, large prices, program names and countdown numerals; uppercase with tight line spacing** — Archivo Black (OFL), weights 400. Self-host the font files.
- **Text and UI: body, navigation, buttons, class rows, biographies, form labels and FAQ** — Manrope (OFL), weights 400/500/600/700/800. Self-host the font files.
- **Mono: eyebrows, section indices, schedule times, age and level metadata, spots, reservation reference and small print** — IBM Plex Mono (OFL), weights 400/500. Self-host the font files.
## Spacing & shape
- Spacing: 8px base unit. Container max-width 1240px, centered, side padding 40px desktop, 28px tablet and 20px under 640px. Twelve-column grid with 24px gaps. Section padding 112px desktop, 80px tablet and 64px mobile. Eyebrow: IBM Plex Mono 500 12px uppercase, letter-spacing 0.14em, with a 24px Coral line. H1: Archivo Black clamp(58px, 8.6vw, 124px), line-height 0.9, letter-spacing -0.035em. H2: Archivo Black clamp(42px, 5.8vw, 78px), line-height 0.94, letter-spacing -0.025em. H3: Manrope 800 24px / 1.2. Lead: Manrope 500 19px / 1.6, max-width 56ch. Body: Manrope 400 16px / 1.7, max-width 66ch. Buttons: minimum 48px high, pill shaped, padding 0 24px, Manrope 800 13px uppercase with 0.06em tracking. Primary is Coral with Ink text; secondary is 1px currentColor with transparent fill. Inputs are 52px high with 16px text. Every interactive element gets a 2px Coral focus outline with 3px offset.
- Radius: 24px on large photographic and content panels, 16px on class rows and small cards, 12px on inputs, and 999px only for buttons, chips, pills and status dots. Avoid nesting rounded cards inside identical rounded cards.
## Motion
- Use --ease-out cubic-bezier(0.22, 1, 0.36, 1) for photographic and content reveals and --ease-beat cubic-bezier(0.76, 0, 0.24, 1) for masks, rail transitions and drawer movement.
- MaskedHeading wraps each supplied line in overflow-hidden and raises its inner span from translateY(110%) to 0 over 720ms --ease-beat, with 80ms between lines. Trigger H2s once at 25% visibility.
- Reveal moves section content from opacity 0 and translateY(22px) to rest over 650ms --ease-out when 15% visible; grids stagger children by 70ms. Never hide content permanently if IntersectionObserver is unavailable.
- The hero photograph scales from 1.07 to 1 over 1600ms on load and translates no more than 5% vertically as the hero leaves the viewport. The headline and actions enter after 120ms.
- ProgramRail translates two identical tracks linearly by -50% over 32s. Pause on hover and focus-within; expose one visually hidden static list to screen readers.
- Filter updates use Motion AnimatePresence with opacity and 10px vertical movement over 180ms; preserve layout stability and announce the result count with aria-live polite.
- Recital digits crossfade and move 8px on value changes only; seconds do not cause layout shift. Buttons translate -2px on hover and return on press. Portraits scale to 1.035 inside their crop on hover.
- The class drawer enters from the right over 360ms --ease-beat while its backdrop fades in over 180ms. Trial confirmation replaces the form with a 12px rise and 250ms fade; errors reveal without pushing the submit button off-screen.
- prefers-reduced-motion: render all content at rest, stop the rail, remove parallax, scaling, stagger and digit movement, disable smooth scrolling, and use only a 100ms opacity change for menus and dialogs. Countdown values still update accessibly without animation.
## Imagery
Use only the six generated editorial dance photographs listed under Assets. They form one shoot: documentary movement photography, deep aubergine shadows, warm coral rim light, soft lilac fill, unbranded dark rehearsal clothes, subtle film grain and clean studio architecture. The hero is a wide ensemble scene with generous negative space, never a close-up face. The class and recital photographs show full-body movement with faces turned away, obscured by pose or naturally motion-softened. The three instructor images are professional portraits of explicitly fictional adults, not resembling any real individual, with varied age and ethnicity and consistent chest-up framing. Do not substitute real dancers, celebrities, stock portraits, initials-only instructor cards or unrelated gym photos. Apply object-fit cover and the listed object-position; retain natural skin texture. All other graphics are code-drawn: the wordmark is text, the favicon uses two offset beat bars, the program rail and pills are CSS, availability tracks are divs, and the trial-pass perforation is CSS. Icons come only from lucide-react at 1.75px stroke width. No readable signage, clothing logos or brand marks in any image.
## Tone
Energetic, encouraging and precise. Short declarative sentences, concrete times, ages, durations and prices. Celebrate effort rather than body image or competition. No dance clichés, no promises of fame, no exclamation marks, no pressure to buy.
---
— Prompt by VibeFather · https://vibefather.ai/t/dance-studio-website · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown