-
Welcome to
+
+
+
+
+ Welcome to
+
{name}
{tagline}
{
memberCount && (
-
{memberCount} members and growing
+
+ {memberCount} members and growing
+
)
}
{description}
-
+
-
- HTML
- CSS
- JavaScript
- Design
- Accessibility
-
+
+ {
+ techPills.map((pill) => (
+ -
+ {pill}
+
+ ))
+ }
+
diff --git a/src/components/astro/Hero.astro.test.ts b/src/components/astro/Hero.astro.test.ts
index 72bcaf1..2c4c39e 100644
--- a/src/components/astro/Hero.astro.test.ts
+++ b/src/components/astro/Hero.astro.test.ts
@@ -3,12 +3,12 @@ import { createTestContainer } from '../../test/createTestContainer';
import Hero from './Hero.astro';
describe('Hero', () => {
- it('renders tagline and member count placeholder', async () => {
+ it('renders tagline, logo, and member count', async () => {
const container = await createTestContainer();
const html = await container.renderToString(Hero, {
props: {
name: 'Web Dev & Design',
- tagline: 'A Discord community',
+ tagline: 'A place to learn, help, and belong',
description: 'Community description',
discordUrl: 'https://discord.gg/example',
memberCount: '1,000+',
@@ -17,8 +17,11 @@ describe('Hero', () => {
expect(html).toContain('Welcome to');
expect(html).toContain('Web Dev & Design');
- expect(html).toContain('A Discord community');
+ expect(html).toContain('A place to learn, help, and belong');
expect(html).toContain('1,000+ members and growing');
expect(html).toContain('Browse resources');
+ expect(html).toContain('/logo.png');
+ expect(html).toContain('bg-mod');
+ expect(html).toContain('from-surface-elevated');
});
});
diff --git a/src/components/astro/ResourceCard.astro b/src/components/astro/ResourceCard.astro
index 21c999c..34f64ae 100644
--- a/src/components/astro/ResourceCard.astro
+++ b/src/components/astro/ResourceCard.astro
@@ -10,19 +10,19 @@ interface Props {
const { title, url, description, category, featured = false } = Astro.props;
---
-
+
{featured && (
-
+
Featured
)}
{description && {description}
}
- {category}
+ {category}
diff --git a/src/components/astro/ServerLogo.astro b/src/components/astro/ServerLogo.astro
new file mode 100644
index 0000000..0ff6e52
--- /dev/null
+++ b/src/components/astro/ServerLogo.astro
@@ -0,0 +1,23 @@
+---
+interface Props {
+ size?: "sm" | "md" | "lg";
+ class?: string;
+}
+
+const { size = "md", class: className = "" } = Astro.props;
+
+const sizes = {
+ sm: "h-6 w-6",
+ md: "h-12 w-12",
+ lg: "h-20 w-20",
+};
+---
+
+
diff --git a/src/components/astro/ValueCards.astro b/src/components/astro/ValueCards.astro
new file mode 100644
index 0000000..4e7d9d1
--- /dev/null
+++ b/src/components/astro/ValueCards.astro
@@ -0,0 +1,65 @@
+---
+const cards = [
+ {
+ title: 'Learn',
+ description: 'Share tutorials, docs, and tips — from your first line of HTML to advanced patterns.',
+ accent: 'border-t-brand-500',
+ icon: '📚',
+ },
+ {
+ title: 'Help',
+ description: 'Stuck on a bug or design decision? Ask the community — someone has been there.',
+ accent: 'border-t-mod',
+ icon: '🤝',
+ },
+ {
+ title: 'Connect',
+ description: 'Meet developers and designers who care about craft, accessibility, and good code.',
+ accent: 'border-t-admin',
+ icon: '💬',
+ },
+ {
+ title: 'Belong',
+ description: 'An inclusive space where everyone is welcome — learners, hobbyists, and pros alike.',
+ accent: 'border-t-transparent',
+ icon: '🌈',
+ prideStripe: true,
+ },
+];
+---
+
+
+
+
+ What we're about
+
+
+ A cozy corner of the internet for people who build for the web.
+
+
+ {
+ cards.map((card) => (
+ -
+ {card.prideStripe && (
+
+ )}
+
+ {card.icon}
+
+
{card.title}
+ {card.description}
+
+ ))
+ }
+
+
+
diff --git a/src/components/astro/ValueCards.astro.test.ts b/src/components/astro/ValueCards.astro.test.ts
new file mode 100644
index 0000000..1b9b5a8
--- /dev/null
+++ b/src/components/astro/ValueCards.astro.test.ts
@@ -0,0 +1,16 @@
+import { describe, expect, it } from 'vitest';
+import { createTestContainer } from '../../test/createTestContainer';
+import ValueCards from './ValueCards.astro';
+
+describe('ValueCards', () => {
+ it('renders all four value cards', async () => {
+ const container = await createTestContainer();
+ const html = await container.renderToString(ValueCards, { props: {} });
+
+ expect(html).toContain("What we're about");
+ expect(html).toContain('Learn');
+ expect(html).toContain('Help');
+ expect(html).toContain('Connect');
+ expect(html).toContain('Belong');
+ });
+});
diff --git a/src/components/react/MobileNav.tsx b/src/components/react/MobileNav.tsx
index 5403c93..efea091 100644
--- a/src/components/react/MobileNav.tsx
+++ b/src/components/react/MobileNav.tsx
@@ -33,7 +33,7 @@ export default function MobileNav({ navLinks, discordUrl }: MobileNavProps) {