← 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

PropTypeDefaultDescription
coverImageImageMetadataCard background image
imageAltstringAlt text
datestringFormatted date string
titlestringCard title
descriptionstringCard description
hrefstring?Link URL (renders <a> if set)
isCompletedboolean?Show “Completed” badge
isUpcomingboolean?Show “Upcoming” badge
categorystring?Category label badge

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

FilterMenu

PropTypeDescription
filterGroupsFilterGroup[]Array of { label, stateVariable, categories, categoryLabels }

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

SortMenu

PropTypeDefaultDescription
stateVariablestring?'sortOrder'Alpine state variable to bind to

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

CategoryFilter

PropTypeDefaultDescription
categoriesstring[]Category values
categoryLabelsRecord<string, string>Display labels
stateVariablestring?'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

PropTypeDefaultDescription
imageImageMetadataBackground image
altstringAlt text
titlestringTitle (bottom-left)
subtitlestring?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

PropTypeDefaultDescription
imagesImageWithAlt[]Images with alt text + optional description (rendered as a gradient overlay)
cols2-64Grid columns
gap'sm' | 'md' | 'lg''md'Item spacing
enableClickToEnlargebooleantrueClick-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

PropTypeDefaultDescription
imagesImageWithAlt[]Images with alt text + optional description (rendered as a gradient overlay)
cols2-64Grid columns
gap'sm' | 'md' | 'lg''md'Item spacing
previewRowsnumber1Visible rows when collapsed

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

MediaAccordion

PropTypeDefaultDescription
titlestringSection title
imagesImageMetadata[]Images to display
cols2-64Grid 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

PropTypeDefaultDescription
direction'prev' | 'next' | 'down'Arrow direction
onClickstringAlpine click handler
variant'flex' | 'absolute''flex'Positioning mode
position'left' | 'right''left'Position for absolute variant
invertedbooleanfalseWhite 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

PropTypeDefaultDescription
variant'dark' | 'light''dark'Color scheme

Thin gradient line used as a visual separator.

CrosslinkBanner

PropTypeDescription
textstringPrompt text
linkTextstringLink label
hrefstringDestination 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

PropTypeDescription
sponsorsSponsorData[]Array of sponsor objects
tierSponsorTierTier 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

PropTypeDefaultDescription
titlestring?Section heading
subtitlestring?Accent label above heading
descriptionstring?Intro paragraph
tiersTierGroup[]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

PropTypeDefaultDescription
autoScrollboolean?Auto-advance slides
autoScrollIntervalnumber?8000Interval (ms)
showArrowsboolean?trueShow navigation arrows
showDotsboolean?falseShow dot indicators
ctasHeroCTAItem[]?1–3 CTA buttons
taglinestring?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

PropTypeDescription
headingsArray<{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.