← Back to site

Site Components

Components are organized by feature in subdirectories under src/components/. This page covers non-MDX components used by pages and layouts.

Layout Components

Directory: src/components/layout/

Sticky navigation bar with mobile menu and full-site search.

No external props — navigation links are hardcoded in the component.

Alpine.js features:

  • Search — Pagefind integration with 150ms debounce, keyboard navigation (arrows, Enter, Escape), and Cmd/Ctrl+K global hotkey
  • Mobile menu — Slide-out overlay with staggered link animations
  • Scroll behavior — Hides on scroll down, shows on scroll up

Site-wide footer with navigation columns, social links, and legal info.

No external props — loads content from multiple page-text entries:

  • social — Social media icons with custom hover colors
  • contact-details — Email + multiline address field, shared with the Contact page so both surfaces stay in sync
  • nav-columns — Navigation columns
  • nav-links/footer-bottom — Copyright and legal links

BackToTopButton

Floating button that appears after scrolling 300px. Uses Alpine.js for scroll detection and smooth scroll back to top.


Post Catalog Components

Directory: src/components/posts-catalog/

These components work together with the Alpine.js grid filtering pattern in events.astro and projects.astro.

PostShowcase

Prop Type Default Description
coverImage ImageMetadata — Card background image
imageAlt string — Alt text
date string — Formatted date string
title string — Card title
description string — Card description
href string? — Link URL (renders <a> if set)
isCompleted boolean? — Show “Completed” badge
isUpcoming boolean? — Show “Upcoming” badge
category string? — Category label badge

Fixed height card (320px) with image zoom on hover, glass-morphism badges, and accent glow border effect on desktop hover.

FilterMenu

Prop Type Description
filterGroups FilterGroup[] Array of { label, stateVariable, categories, categoryLabels }

Dropdown panel with filter groups. Shows active filter count badge. Provides clearFilters() method.

SortMenu

Prop Type Default Description
stateVariable string? 'sortOrder' Alpine state variable to bind to

Dropdown toggle between “Newest first” and “Oldest first” with animated direction icon.

CategoryFilter

Prop Type Default Description
categories string[] — Category values
categoryLabels Record<string, string> — Display labels
stateVariable string? 'activeCategory' Alpine state array to toggle

Row of filter chip buttons that call toggleFilter() on the Alpine state.


Reusable Components

Directory: src/components/reusable/

PageHeroImage

Prop Type Default Description
image ImageMetadata — Background image
alt string — Alt text
title string — Title (bottom-left)
subtitle string? — Subtitle
variant 'dark' | 'light' 'dark' Gradient color
loading 'eager' | 'lazy' 'eager' Loading strategy

Full viewport hero section (h-[50vh] lg:h-[60vh]) with gradient overlays for text readability. Title takes half width on desktop.

ImageGrid

Prop Type Default Description
images ImageWithAlt[] — Images with alt text + optional description (rendered as a gradient overlay)
cols 2-6 4 Grid columns
gap 'sm' | 'md' | 'lg' 'md' Item spacing
enableClickToEnlarge boolean true Click-to-enlarge modal
aspectRatio 'square' | 'native' 'square' Layout mode

Two modes: square uses CSS Grid with 1:1 aspect ratio, native uses CSS Columns for masonry layout. Mobile always shows 2 columns. First cols * 2 images use eager loading.

CollapsibleImageGrid

Prop Type Default Description
images ImageWithAlt[] — Images with alt text + optional description (rendered as a gradient overlay)
cols 2-6 4 Grid columns
gap 'sm' | 'md' | 'lg' 'md' Item spacing
previewRows number 1 Visible rows when collapsed

Wraps ImageGrid with a gradient overlay and expand/collapse button. Uses Alpine.js for height animation with scrollHeight measurement.

MediaAccordion

Prop Type Default Description
title string — Section title
images ImageMetadata[] — Images to display
cols 2-6 4 Grid columns
gap 'sm' | 'md' | 'lg' 'md' Item spacing

Smart wrapper: if all images fit in one row, renders a static header. Otherwise renders a clickable header with CollapsibleImageGrid.

CarouselArrow

Prop Type Default Description
direction 'prev' | 'next' | 'down' — Arrow direction
onClick string — Alpine click handler
variant 'flex' | 'absolute' 'flex' Positioning mode
position 'left' | 'right' 'left' Position for absolute variant
inverted boolean false White border for dark backgrounds

Responsive SVG arrow button (w-10 h-10 sm:w-12 sm:h-12). Standard variant uses red accent; inverted uses white border with mix-blend-difference.

GradientDivider

Prop Type Default Description
variant 'dark' | 'light' 'dark' Color scheme

Thin gradient line used as a visual separator.

CrosslinkBanner

Prop Type Description
text string Prompt text
linkText string Link label
href string Destination URL

Subtle banner with text and arrow link, used below pagination to cross-link between events and projects pages.


Landing Components

Directory: src/components/landing/

SponsorTier

Prop Type Description
sponsors SponsorData[] Array of sponsor objects
tier SponsorTier Tier key for size styling

Each sponsor object: { name, logo (ImageMetadata), url?, tier, slug, bgColor? }.

Renders sponsor logos in a flex-wrap row with tier-proportional sizing. Each logo sits inside a white card container with soft shadow, rounded corners, and padding that scales with the tier (larger cards for higher tiers). The card background color defaults to #ffffff but can be overridden per sponsor via the bgColor frontmatter field to meet corporate identity requirements.

Used by both BecomeSponsor (landing page) and SponsorShowcase (dedicated sponsors page).

SponsorShowcase

Prop Type Default Description
title string? — Section heading
subtitle string? — Accent label above heading
description string? — Intro paragraph
tiers TierGroup[] — Tier groups with sponsors

Light-background section with accordion-style tier groups (all open by default). Each tier header is a clickable button with height animation. Uses SponsorTier internally for logo display.

LandingHero

Prop Type Default Description
autoScroll boolean? — Auto-advance slides
autoScrollInterval number? 8000 Interval (ms)
showArrows boolean? true Show navigation arrows
showDots boolean? false Show dot indicators
ctas HeroCTAItem[]? — 1–3 CTA buttons
tagline string? — Text below BEARS logo

Full viewport hero with video/image carousel background. Loads media from src/assets/hero/landingpage/. Videos autoplay muted. Touch swipe support for mobile.

The CTA grid (HeroCTA.astro) uses CSS-only hover effects — no client-side JS required.


Docs Components

Directory: src/components/docs/

DocsSidebar

Navigation sidebar for documentation pages. No external props — fetches docs via getDocsBySection().

  • Collapsible sections (Guides, Dev Docs) and groups within sections
  • localStorage persistence for expansion state
  • Active page highlighting
  • Desktop: sticky sidebar; Mobile: slide-out overlay

DocsToc

Prop Type Description
headings Array<{depth, slug, text}> Page heading hierarchy

Table of contents sidebar (right column, XL+ screens only). Filters to depth 2–3 headings. Only renders if 2+ headings exist.