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 presentations
array:
{
title: "Your Presentation Title",
slug: "your-presentation-slug",
description: "Brief description of your presentation",
date: "YYYY-MM-DD",
icon: "๐ฏ" // Choose an appropriate emoji
}
theme: "water"
or theme: "default"
transition: "slide"
, "fade"
, "none"
, etc.data-background-color
or data-background-image
to sectionsclass="fragment"
for step-by-step animations<!-- .element: class="notes" -->
Run the development server to see your changes:
pnpm dev
Then 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 event slug
(the URL path desired that is unique to the event) as the filename (e.g., event-slug.md
for /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: "[email protected]"
contact_phone: "+49 177 4543720"
event_website: "https://eventwebsite.com/"
---
/public/share-banners/
The system automatically creates event pages at /events/[slug]
based on your markdown files. Each event page includes:
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 websiteEvents automatically appear on the main events page (/events
) when:
src/content/events/
Each event page includes:
/public/share-banners/
http://localhost:4321/events/[slug]
contain
and content-visibility
@theme
directive with CSS custom propertiesThemeSwitcher
and ModeSwitcher
classesBoilerPlateHTML
and BaseThemeLayout
componentsThe application features a comprehensive button system with multiple variants and sizes for consistent UI/UX:
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"
/>
/slides/
to view available presentationssrc/content/slides/
directory.astro
files for component-based slides or .md
for Markdown contenttwf-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
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 dev
The 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
// 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'
All responsive components maintain:
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 |
@tailwindcss/vite
pluginsrc/pages/
- File-based routing. Each .astro
or .md
file becomes a routeindex.astro
- Homepage with project overviewbrand-kit/index.astro
- Interactive theme system demonstrationbrand-kit/heros.astro
- Hero component examples and documentationsrc/components/
- Reusable UI componentsbasics/
- Core UI componentsHero.astro
- Full-width hero component with background cycling and responsive designdesign-system/
- Theme-aware components (ColorVariableGrid, TextStylePatternsGrid)src/layouts/
- Page layout componentsBoilerPlateHTML.astro
- HTML boilerplate with meta tags and fontsBaseThemeLayout.astro
- Theme-specific layout wrappersrc/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 definitionspublic/
- Static assets served directlyastro.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:
Build for production:
cd site
pnpm build
site/
directorypnpm dev
pnpm build
[Add your license information here]
Built by The Lossless Group with โค๏ธ using Astro