A modern web application built with
β€οΈ
by
The Lossless Group
SSG and Styles with
Astro
and
Tailwind CSS v4
for The Water Foundation
Β Β β’Β Β
Β Β β’Β Β
Β Β β’Β Β
Modern site generation, presentations, styling, and testing.
This project uses Astro with RevealJS to create beautiful, interactive slide presentations. Here's how to create a new slide deck:
-
Create a new markdown file in
src/content/slides/with this structure:--- title: "Your Presentation Title" description: "Brief description of your presentation" theme: "water" # or "default" transition: "slide" # or "fade", "none", etc. tags: ["tag1", "tag2"] # Optional tags --- # Your First Slide Content goes here... --- ## Second Slide More content...
-
Add your content using Markdown syntax. Use
---to separate slides.
-
Open
src/pages/slides/[...slug].astro -
Add a new entry to the
getStaticPaths()function:{ params: { slug: 'your-presentation-slug' }, props: { title: "Your Presentation Title", description: "Brief description of your presentation", slideshow: "your-presentation-slug" } }
-
Add a new condition to render your slides:
{slideshow === 'your-presentation-slug' && ( <!-- Your slides go here --> <section> <h1>Your First Slide</h1> <p>Content goes here...</p> </section> <section> <h2>Second Slide</h2> <p>More content...</p> </section> )}
-
Open
src/pages/slides/index.astro -
Add a new entry to the
presentationsarray:{ title: "Your Presentation Title", slug: "your-presentation-slug", description: "Brief description of your presentation", date: "YYYY-MM-DD", icon: "π―" // Choose an appropriate emoji }
- Themes: Use
theme: "water"ortheme: "default" - Transitions: Set
transition: "slide","fade","none", etc. - Backgrounds: Add
data-background-colorordata-background-imageto sections - Fragments: Use
class="fragment"for step-by-step animations - Speaker Notes: Add notes with
<!-- .element: class="notes" -->
Run the development server to see your changes:
pnpm devThen visit http://localhost:4321/slides/your-presentation-slug
This project includes a comprehensive event management system for creating splash pages and managing event information.
-
Create a new markdown file in
src/content/events/using the eventslug(the URL path desired that is unique to the event) as the filename (e.g.,event-slug.mdfor/events/event-slug). -
Add the event information to the markdown file with this structure:
--- title: "Meet The Water Foundation at [Event Name]" event_name: "EventName" upcoming_dates: "2025-09-15--2025-09-18" upcoming_location: "City, Country" url: https://eventwebsite.com/ splash_page_path: /events/event-slug twf_zinger: "The Water Foundation is a think tank and capital catalyst, assuring full-stack financial innovations are tackling the urgent challenge of our time." invite_message: "Meet us at [Event Name], a gathering of water innovation leaders, investors, and changemakers." share_image: /share-banners/bannerImage--Event-Name.webp contact_email: "dive.deep@the-water-foundation.org" contact_phone: "+49 177 4543720" event_website: "https://eventwebsite.com/" ---
- twf_zinger: The current positioning statement of the The Water Foundation that is most relevant for this event.
- invite_message: The message you want to invite people to meet or join the team at the event.
- share_image: The banner image for the event splash page that will be used in open graph social media shares.
- Add the banner image to
/public/share-banners/
The system automatically creates event pages at /events/[slug] based on your markdown files. Each event page includes:
- Dynamic content loaded from markdown frontmatter
- Social sharing with LinkedIn and WhatsApp integration
- Open Graph meta tags for proper social media previews
- Contact information with email and phone links
- Event details with formatted dates and location
- Responsive design optimized for all devices
title: Page title and meta title for SEOevent_name: Display name of the event (e.g., "TheDrop")upcoming_dates: Date range in format "YYYY-MM-DD--YYYY-MM-DD"upcoming_location: City and country where event takes placeurl: Official event website URLsplash_page_path: Internal path for the event pagetwf_zinger: The Water Foundation's positioning statementinvite_message: Main invitation message for the eventshare_image: Banner image for social media sharing (recommended: 1200x630px)contact_email: Contact email for event inquiriescontact_phone: Contact phone number (optional)event_website: Link to event's official website
Events automatically appear on the main events page (/events) when:
- The markdown file exists in
src/content/events/ - The event data matches the collection schema
- The event is referenced in the events index page logic
Each event page includes:
- LinkedIn sharing with proper Open Graph tags
- WhatsApp sharing with formatted message
- Custom banner images for social media previews
- SEO optimization with meta descriptions and titles
- Create the markdown file with event details
- Add the banner image to
/public/share-banners/ - Test the page at
http://localhost:4321/events/[slug] - Verify social sharing previews work correctly
- Dual Theme Support: Default and Water themes with complete color palettes
- Dark/Light Mode: Automatic color inversion with proper contrast ratios
- State Persistence: localStorage integration for user preferences
- Component Integration: Theme-aware components with semantic CSS classes
- Event System: Custom events for coordinated UI updates
- Comprehensive Testing: 51 unit and integration tests with 100% pass rate
- Media Queries: Mobile-first breakpoints for all device sizes
- Container Queries: Component-level responsive design
- Utility Classes: Comprehensive set of responsive utilities
- Performance Optimized: Efficient CSS with
containandcontent-visibility - Accessibility: Responsive design that maintains accessibility
- Tailwind CSS v4: Modern
@themedirective with CSS custom properties - JavaScript Utilities:
ThemeSwitcherandModeSwitcherclasses - Astro Layouts: Reusable
BoilerPlateHTMLandBaseThemeLayoutcomponents - Brand Kit Page: Interactive demonstration of all theme combinations
- Hero Component: Full-width hero component with background cycling and responsive design
- Responsive Components: Built with both media and container queries for maximum flexibility
- Header Component: Responsive navigation with dark/light mode toggle and mobile menu
- Footer Component: Site-wide footer with navigation and contact information
- Slides System: Interactive presentations powered by RevealJS with Water Theme integration
The application features a comprehensive button system with multiple variants and sizes for consistent UI/UX:
- Lean: Glassmorphic effect with subtle hover states
- Icon: Circular buttons for icon-only actions
- Gradient: Filled gradient buttons with hover effects
- Animated: Buttons with animated hover effects
- Ghost: Transparent buttons with border
- Text Gradient: Buttons with gradient text and glassmorphic background
- Partner: Special variant with custom styling for partnership actions
xs: Extra smallsm: Smallmd: Medium (default)lg: Largexl: Extra largecompact: Compact size with standard padding
<ButtonVariants
href="/example"
text="Click Me"
variant="gradient"
size="md"
external={false}
className="custom-class"
/>- Astro: v5.12.9 - Modern static site generator
- Tailwind CSS: v4.1.11 - Utility-first CSS framework
- Vite: Next generation frontend tooling (via Astro)
- TypeScript: Type-safe JavaScript
- @tailwindcss/vite: v4.1.11 - Vite plugin for Tailwind CSS
- PostCSS: CSS processing with Tailwind and Autoprefixer
- Autoprefixer: Add vendor prefixes to CSS rules
- Vitest: v3.2.4 - Fast unit testing framework
- @vitest/ui: v3.2.4 - UI for Vitest
- jsdom: v26.1.0 - JavaScript implementation of web standards
- pnpm: v10.13.1 - Fast, disk space efficient package manager
- ESLint: Code quality and style checking
- Prettier: Code formatting
- Features:
- Responsive navigation that collapses into a mobile menu on smaller screens
- Dark/light mode toggle with system preference detection
- Accessible dropdown menus with keyboard navigation
- Smooth transitions and animations
- Support for custom logos and navigation items
- Call-to-action button with configurable variants
- Features:
- Multi-column layout with configurable sections
- Social media links with SVG icons
- Copyright and legal links
- Responsive design that adapts to different screen sizes
- Consistent theming with the rest of the application
- Features:
- Interactive presentations powered by RevealJS 4.5.0
- Full Water Theme integration with automatic dark/light mode support
- Four-way navigation (horizontal and vertical slides)
- Control buttons (exit, restart, fullscreen toggle)
- Responsive design (16:9 aspect ratio) that works on all devices
- Syntax highlighting for code blocks
- CDN-based RevealJS loading (no npm dependencies required)
- Content collections support for slide management
- Usage:
- Visit
/slides/to view available presentations - Create new slides in
src/content/slides/directory - Use
.astrofiles for component-based slides or.mdfor Markdown content
- Visit
twf-site/
βββ site/ # Main Astro application
β βββ src/
β β βββ pages/ # Route pages
β βββ public/ # Static assets
β βββ package.json # Dependencies and scripts
β βββ README.md # Astro-specific documentation
βββ README.md # This file
- Node.js (version 18 or later)
- pnpm (recommended package manager)
-
Clone this repository
-
Navigate to the site directory:
cd site -
Install dependencies:
pnpm install
pnpm add -D vitest @vitest/ui
Start the development server:
cd site
pnpm devThe site will be available at http://localhost:4321
The project includes comprehensive test coverage for theme and mode switching functionality:
# Run all tests
pnpm test
# Run tests with UI
pnpm test:ui
# Run tests once (CI mode)
pnpm test:run- 51 total tests across 4 test suites
- ThemeSwitcher: 24 unit tests covering initialization, switching, storage, and events
- ModeSwitcher: 7 unit tests for light/dark mode functionality
- Integration: 14 tests for combined theme/mode operations and state management
- Hero Component: 6 unit tests covering rendering, background cycling, and interactive elements
- Background Cycling: Smooth transitions between multiple background types (image, gradient, video, GIF)
- Responsive Design: Adapts to all screen sizes with proper aspect ratios
- Overlay Support: Configurable color and gradient overlays with opacity control
- Content Areas: Flexible layout for headers, subheaders, and call-to-action buttons
- Accessible: Proper ARIA attributes and semantic HTML structure
- Tested: Comprehensive test coverage for all interactive features
- Default Theme: Professional blue/gray color palette
- Water Theme: Ocean-inspired cyan/blue color palette
// Theme switching
import { ThemeSwitcher } from './src/utils/theme-switcher.js';
const themeSwitcher = new ThemeSwitcher();
// Set specific theme
themeSwitcher.setTheme('water');
// Toggle between themes
themeSwitcher.toggleTheme();
// Get current theme
const currentTheme = themeSwitcher.getCurrentTheme();// Mode switching
import { ModeSwitcher } from './src/utils/mode-switcher.js';
const modeSwitcher = new ModeSwitcher();
// Toggle dark/light mode
modeSwitcher.toggleMode();
// Set specific mode
modeSwitcher.setMode('dark');Themes use semantic CSS variables that automatically adapt to dark/light modes:
/* Example theme variables */
--color-primary-500: #3b82f6; /* Default theme */
--color-secondary-100: #f1f5f9; /* Light backgrounds */
--color-secondary-800: #1e293b; /* Dark text */Our responsive design system combines traditional media queries with modern container queries for optimal flexibility across all devices.
We use a mobile-first approach with the following breakpoints:
| Breakpoint | Min-Width | Description |
|---|---|---|
sm |
640px | Small devices |
md |
768px | Tablets |
lg |
1024px | Laptops |
xl |
1280px | Desktops |
2xl |
1536px | Large desktops |
/* Mobile-first media query example */
.component {
/* Mobile styles */
padding: 1rem;
/* Small devices and up */
@media (min-width: 640px) {
padding: 1.5rem;
}
/* Large devices and up */
@media (min-width: 1024px) {
padding: 2rem;
}
}Container queries allow components to adapt based on their container size rather than viewport size:
/* Parent container */
.container {
container-type: inline-size;
container-name: component;
width: 100%;
}
/* Component styles that respond to container size */
@container component (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 1.5rem;
}
}We provide responsive utility classes for common patterns:
<!-- Hide on mobile, show on medium screens and up -->
<div class="hidden md:block">Visible on medium+</div>
<!-- Stack on mobile, row on larger screens -->
<div class="flex flex-col md:flex-row gap-4">
<div>Item 1</div>
<div>Item 2</div>
</div>//.env
UNIPILE_API_CUSTOM_URL=
UNIPILE_API_KEY=
The Unipile API is used to retrieve data for people.
curl --request GET --url ${UNIPILE_API_CUSTOM_URL}/api/v1/accounts --header 'X-API-KEY:'${UNIPILE_API_KEY}' --header 'accept: application/json'- CSS Containment: Used to optimize rendering performance
- Content Visibility: Applied to off-screen content
- Efficient Selectors: Optimized for better rendering performance
All responsive components maintain:
- Proper heading hierarchy
- Sufficient color contrast
- Keyboard navigation support
- Screen reader compatibility
All commands should be run from the root directory:
| Command | Action |
|---|---|
pnpm install |
Install dependencies |
pnpm dev |
Start local development server |
pnpm build |
Build production site to ./dist/ |
pnpm preview |
Preview production build locally |
pnpm test |
Run test suite |
pnpm test:ui |
Run tests with interactive UI |
pnpm test:run |
Run tests once (CI mode) |
pnpm astro ... |
Run Astro CLI commands |
- Framework: Astro v5.12.9 - The web framework for content-driven websites
- Styling: Tailwind CSS v4.1.11 - Utility-first CSS framework
- Presentations: RevealJS v4.5.0 - HTML presentation framework (CDN-based)
- Testing: Vitest v3.2.4 - Fast unit testing framework
- Package Manager: pnpm - Fast, disk space efficient package manager
- Language: JavaScript/TypeScript
- Build Tool: Vite (via Astro) with
@tailwindcss/viteplugin
src/pages/- File-based routing. Each.astroor.mdfile becomes a routeindex.astro- Homepage with project overviewbrand-kit/index.astro- Interactive theme system demonstrationbrand-kit/heros.astro- Hero component examples and documentation
src/components/- Reusable UI componentsbasics/- Core UI componentsHero.astro- Full-width hero component with background cycling and responsive design
design-system/- Theme-aware components (ColorVariableGrid, TextStylePatternsGrid)
src/layouts/- Page layout componentsBoilerPlateHTML.astro- HTML boilerplate with meta tags and fontsBaseThemeLayout.astro- Theme-specific layout wrapper
src/utils/- JavaScript utilitiestheme-switcher.js- Theme management utilitymode-switcher.js- Dark/light mode utility__tests__/- Comprehensive test suite (45 tests)
src/styles/- Global CSS and Tailwind configurationglobal.css- Tailwind imports and theme definitions
public/- Static assets served directly
astro.config.mjs- Main Astro configuration with Tailwind CSS v4 integrationvitest.config.js- Test configuration with jsdom environmenttsconfig.json- TypeScript configurationpackage.json- Project dependencies and scripts
// astro.config.mjs - Tailwind CSS v4 integration
import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
vite: {
plugins: [tailwindcss()],
},
});// vitest.config.js - Test environment setup
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
environment: 'jsdom',
setupFiles: ['./src/utils/__tests__/setup.js'],
},
});The site can be deployed to various platforms that support static sites or SSR:
- Static Hosting: Netlify, Vercel, GitHub Pages
- SSR Hosting: Cloudflare Pages, Deno Deploy, Node.js servers
Build for production:
cd site
pnpm build- Fork the repository
- Create a feature branch
- Make your changes in the
site/directory - Test your changes with
pnpm dev - Build and verify with
pnpm build - Submit a pull request
[Add your license information here]
Built by The Lossless Group with β€οΈ using Astro

