Files
gw/seasonalthemes.md
ponzischeme89 6d44e05de4 v1
2026-04-18 07:23:55 +12:00

7.8 KiB
Raw Permalink Blame History

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:

<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:

<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:

<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:

<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>:

<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:
    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.