Files

193 lines
7.8 KiB
Markdown
Raw Permalink Normal View History

2026-04-18 07:23:55 +12:00
# 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 (814 px), and durations (34.5 s).
**Example usage:**
```svelte
<SeasonalBanner
theme="christmas"
message="🎄 Merry Christmas from the Tiny Gang! Walks continue over the holidays."
sub="Book before 20 Dec to secure your spot."
link={{ label: 'Book now', url: '/contact' }}
/>
```
---
### 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 (813 px), and durations (3.55.5 s). The `petal-fall` keyframe adds horizontal drift at each quarter-step to mimic a natural tumbling fall.
**Example usage:**
```svelte
<SeasonalBanner
theme="easter"
message="🐣 Happy Easter from the Tiny Gang! We're walking all through the long weekend."
sub="Book your spot before it fills up."
link={{ label: 'Book now', url: '/contact' }}
/>
```
**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 (1080% height), sizes (1118 px), delays (07 s) and durations (610.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
<SeasonalBanner
visible={true}
theme="halloween"
message="🎃 Boo! The Tiny Gang is still walking this Halloween weekend."
sub="Spooky walks, same great dogs."
link={{ label: 'Book now', url: '/contact' }}
/>
```
**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 (1014 px), and durations (2.54.5 s). The `sparkle-fall` keyframe scales up at 40 % for a "pop" effect before fading out.
**Example usage:**
```svelte
<SeasonalBanner
theme="newYear"
message="🥂 Happy New Year from the Tiny Gang! Walks resume 2 Jan."
sub="Book ahead for the first week — spots go fast."
link={{ label: 'Book now', url: '/contact' }}
/>
```
**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 `<SeasonalBanner>`:
```svelte
<SeasonalBanner
visible={true}
theme="halloween"
message="🎃 Boo! The Tiny Gang is still walking this Halloween weekend."
sub="Spooky walks, same great dogs."
link={{ label: 'Book now', url: '/contact' }}
/>
```
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 `<style>` block.
3. Update `+layout.svelte` to use the new theme key.