# Seasonal Events Banner The seasonal banner is a full-width strip that sits above the site header across the public site. It is used for time-sensitive announcements tied to holidays or events — booking reminders, holiday hour notices, etc. ## Component `frontend/src/components/SeasonalBanner.svelte` Integrated at the layout level in `frontend/src/routes/+layout.svelte`. The banner renders site wide on public routes and is excluded from `/admin`. --- ## Props | Prop | Type | Default | Description | |-----------|---------------------|---------------------|-----------------------------------------------| | `theme` | `string` | `'christmas'` | Controls colours and particle animation | | `message` | `string` | Christmas greeting | Main bold text shown in the banner | | `sub` | `string` | — | Smaller secondary text (hidden on mobile) | | `link` | `{ label, url }` | Book now → /contact | Optional CTA button rendered to the right | | `visible` | `boolean` | `true` | Set `false` to suppress the banner entirely | --- ## Themes Switching themes changes the banner background, text colours, button colours, and the particle animation. To activate a theme, update the `theme` prop in `+layout.svelte` along with a matching `message` and `sub`. ### Christmas — `theme="christmas"` | Property | Value | |------------|----------------------------------------------------| | Background | Dark green gradient `#1a3a1a → #213021` | | Text | White `#ffffff` | | Accent | Yellow `#FFD100` | | Animation | ❄ Snowflakes falling straight down with slow rotation | Particles: 18 snowflakes at varied horizontal positions, sizes (8–14 px), and durations (3–4.5 s). **Example usage:** ```svelte ``` --- ### Easter — `theme="easter"` | Property | Value | |------------|-----------------------------------------------------| | Background | Purple gradient `#7c3aed → #a855f7` | | Text | White `#ffffff` | | Accent | Soft yellow `#fde68a` | | Animation | 🌸 Cherry blossom petals drifting down with a gentle lateral sway and rotation | Particles: 14 petals at varied positions, sizes (8–13 px), and durations (3.5–5.5 s). The `petal-fall` keyframe adds horizontal drift at each quarter-step to mimic a natural tumbling fall. **Example usage:** ```svelte ``` **Active window:** Good Friday through Easter Monday (exact dates vary — check annually). --- ### Halloween — `theme="halloween"` | Property | Value | |------------|-----------------------------------------------------| | Background | Near-black gradient `#1c1917 → #292524` | | Text | Orange `#f97316` | | Accent | Orange `#f97316` | | Animation | 🦇 Bats flying right-to-left across the banner with a sinusoidal vertical wobble | Particles: 8 bats staggered across vertical positions (10–80% height), sizes (11–18 px), delays (0–7 s) and durations (6–10.5 s). The `bat-fly` keyframe starts off the right edge (`left: 108%`) and translates to `-115vw`, with Y offsets at 30 %, 60 %, and 85 % of the animation to create the swooping motion. **Example usage:** ```svelte ``` **Active window:** ~October 28 – November 1. --- ### New Year's Eve / New Year's Day — `theme="newYear"` | Property | Value | |------------|---------------------------------------------------------| | Background | Deep navy gradient `#0a0a1a → #1a102e` | | Text | Gold `#FFD700` | | Accent | Gold `#FFD700` | | Animation | ✨ Sparkles and confetti (✨ 🎊 ⭐ 💫) falling and rotating with a scale pulse | Particles: 20 sparkles cycling through four emoji types, varied positions, sizes (10–14 px), and durations (2.5–4.5 s). The `sparkle-fall` keyframe scales up at 40 % for a "pop" effect before fading out. **Example usage:** ```svelte ``` **Active window:** December 31 – January 1 (and optionally through January 2 if there is a holiday schedule notice). --- ### Summer — `theme="summer"` | Property | Value | |------------|--------------------------------------| | Background | Blue gradient `#0ea5e9 → #06b6d4` | | Text | White `#ffffff` | | Accent | Pale yellow `#fef08a` | | Animation | None | General-purpose warm-weather banner. No particle effect. Good for school holiday or summer schedule notices. --- ### Custom — `theme="custom"` Falls back to dark green with yellow accents (same palette as Christmas but without snow). Use this as a neutral base for one-off announcements that don't fit a seasonal theme. --- ## Behaviour **Dismissal** — The ✕ button sets a local `dismissed` boolean. The banner hides for the remainder of the session but reappears on next page load (no localStorage persistence). **Mobile** — Below 600 px the `sub` text is hidden and the main message font drops to 0.82 rem. The CTA button and dismiss button remain visible. **z-index** — The banner sits at `z-index: 200`, above the header (`z-index: 20`). **Analytics** — CTA button clicks fire a `banner_click` signal event via `signalClick` (see `frontend/src/lib/signals.js`). Metadata includes the button label and destination URL. --- ## How to switch themes Edit `frontend/src/routes/+layout.svelte` and update the three props on ``: ```svelte ``` To disable the banner entirely, set `visible={false}` or remove the component from the layout. To limit it to specific routes again, pass a route-based condition from `+layout.svelte`. --- ## Adding a new theme 1. Add an entry to the `THEMES` object in `SeasonalBanner.svelte`: ```js myTheme: { bg: 'linear-gradient(90deg, #colour1, #colour2)', accent: '#hex', text: '#hex', sub: 'rgba(r,g,b,0.75)', btn: '#hex', btnText: '#hex', particles: false, // or 'snow' | 'bats' | 'petals' | 'confetti' }, ``` 2. If you need a custom particle effect, add a particle array and a matching `{:else if t.particles === 'myEffect'}` block in the template, plus a `@keyframes` rule in the `