193 lines
7.8 KiB
Markdown
193 lines
7.8 KiB
Markdown
# 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
|
||
<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 (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
|
||
<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 (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
|
||
<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 (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
|
||
<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.
|