Skip to content

Commit 867185f

Browse files
committed
Initialize saacchq.org project with Astro framework, Tailwind CSS, and bilingual support. Add essential configuration files, project structure, and deployment workflow for GitHub Pages. Include initial content for the manifesto, footer, and header components, along with language toggle functionality.
0 parents  commit 867185f

33 files changed

Lines changed: 4724 additions & 0 deletions

.claude/launch.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"version": "0.0.1",
3+
"configurations": [
4+
{
5+
"name": "dev",
6+
"runtimeExecutable": "npx",
7+
"runtimeArgs": ["astro", "dev"],
8+
"port": 4321
9+
}
10+
]
11+
}

.cursor/rules/pd.mdc

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
---
2+
alwaysApply: true
3+
---
4+
5+
# saacchq.org — Project Rules
6+
7+
## Project Overview
8+
9+
Community website for sa/acc (saacchq.org), inspired by [CursorThailand.com](https://cursorthailand.com). Single-page site with hero, upcoming events, past events, and footer.
10+
11+
## Stack
12+
13+
- **Framework**: Astro 5.x (static site generation)
14+
- **Styling**: Tailwind CSS v4 via `@tailwindcss/vite`
15+
- **Language**: TypeScript (strict)
16+
- **Package manager**: pnpm
17+
- **Deployment**: GitHub Pages via GitHub Actions
18+
- **Domain**: cursorsaudi.com (CNAME in `public/`)
19+
20+
## Key Constraints
21+
22+
- **Bilingual**: Arabic (default, RTL) + English (LTR) with client-side toggle stored in `localStorage`
23+
- **Dark mode only**: No theme toggle. Single dark color scheme.
24+
- **Minimal scope**: Hero, upcoming events, past events, footer. No blog, search, or RSS.
25+
- **Content collections**: Events managed as Markdown files in `src/data/events/` with Zod-validated frontmatter.
26+
- **Community links**: Luma (event registration) + X/Twitter
27+
28+
## Project Structure
29+
30+
```
31+
cursorsaudi.com/
32+
├── .github/workflows/deploy.yml # GitHub Pages deployment
33+
├── astro.config.ts # site: "https://cursorsaudi.com", Tailwind v4, sitemap
34+
├── package.json
35+
├── tsconfig.json # base: astro/tsconfigs/strict, paths: @/* -> ./src/*
36+
├── public/
37+
│ ├── .nojekyll
38+
│ ├── CNAME # cursorsaudi.com
39+
│ ├── favicon.svg
40+
│ └── toggle-lang.js # Language toggle script (runs before hydration)
41+
└── src/
42+
├── components/
43+
│ ├── Header.astro # Logo + LangToggle
44+
│ ├── Hero.astro # Tagline, description, CTA
45+
│ ├── EventCard.astro # Reusable card for upcoming/past events
46+
│ ├── UpcomingEvents.astro # Future events list
47+
│ ├── PastEvents.astro # Past events with speakers, slides
48+
│ ├── Footer.astro # Social links (Luma, X), copyright
49+
│ └── LangToggle.astro # AR/EN switcher
50+
├── config.ts # Site-wide constants (title, description, socials, ambassadors)
51+
├── content.config.ts # Event collection schema (Zod)
52+
├── data/
53+
│ └── events/ # Markdown event files
54+
├── i18n/
55+
│ ├── ar.json # Arabic UI strings
56+
│ ├── en.json # English UI strings
57+
│ └── index.ts # getTranslation(lang, key) utility
58+
├── layouts/
59+
│ └── Layout.astro # Base HTML: dark mode, RTL/LTR dir, meta, OG
60+
├── pages/
61+
│ └── index.astro # Homepage assembling all sections
62+
├── styles/
63+
│ └── global.css # Tailwind imports, dark theme CSS variables
64+
└── utils/
65+
└── events.ts # getSortedEvents, getUpcoming, getPast (computed from date)
66+
```
67+
68+
## Event Content Collection Schema
69+
70+
Each Markdown file in `src/data/events/` uses this frontmatter. The `isPast` status is **computed at build time** from `date < today` — not stored in frontmatter.
71+
72+
```yaml
73+
title: "Kickoff" # Event name (English, required)
74+
titleAr: "الانطلاقة" # Arabic name (optional, for future)
75+
date: 2025-05-28 # Event date (required)
76+
type: "meetup" # "meetup" | "hackathon" | "workshop" (required)
77+
location: "Riyadh" # City (required)
78+
locationAr: "الرياض" # Arabic city (optional)
79+
speakers: # Speaker list (optional)
80+
- "Mazen Alotaibi"
81+
- "Dan (Cursor)"
82+
slides: # Slide URLs (optional)
83+
- "https://github.com/cursor-sa/events-slides/blob/main/..."
84+
place: "" # Venue name (optional)
85+
lumaUrl: "https://lu.ma/..." # Registration link (optional)
86+
description: "Community kickoff event" # English description (required)
87+
descriptionAr: "" # Arabic description (optional)
88+
```
89+
90+
### Data Source
91+
92+
Event data was imported from a Notion export (`ExportBlock-f616ed77-905b-4068-9702-1263e7bca7eb-Part-1/Cursor Community in 🇸🇦/Events 27d321ff1409804880b6de61fa1c6336.csv`). 17 events total (7 past, 10 upcoming as of Feb 2026).
93+
94+
## i18n Approach
95+
96+
- JSON files (`ar.json`, `en.json`) hold UI string translations (hero text, section headings, button labels, footer text).
97+
- `toggle-lang.js` in `public/` reads `localStorage` before page render to set `<html dir="rtl" lang="ar">` or `<html dir="ltr" lang="en">`, preventing layout flash.
98+
- Components use `getTranslation(lang, key)` to resolve strings.
99+
- Arabic font stack: `"Noto Kufi Arabic", "IBM Plex Arabic", system-ui`
100+
- English font stack: `Inter, system-ui, sans-serif`
101+
102+
## Visual Design (Dark Mode Only)
103+
104+
- **Background**: `#0d1117` (deep dark)
105+
- **Surface/Cards**: `#161b22` with `1px solid #30363d` border
106+
- **Primary text**: `#e6edf3`
107+
- **Secondary text**: `#8b949e`
108+
- **Accent**: `#58a6ff` (links, CTAs)
109+
- **Accent hover**: `#79c0ff`
110+
- RTL layout: mirrored padding, alignment, and flow direction
111+
112+
## GitHub Actions Deployment
113+
114+
Trigger on push to `main`. Steps: checkout → setup pnpm v9 → setup Node 20 → `pnpm install --frozen-lockfile` → `pnpm run build` → upload pages artifact → deploy pages.
115+
116+
## Site Configuration (`src/config.ts`)
117+
118+
Single source of truth for site metadata, social links, and ambassadors:
119+
120+
```typescript
121+
export const SITE = {
122+
title: "Cursor Saudi",
123+
titleAr: "كيرسر السعودية",
124+
description: "Cursor Saudi Community",
125+
descriptionAr: "مجتمع كيرسر السعودية",
126+
author: "Cursor Saudi",
127+
social: {
128+
luma: "https://lu.ma/...",
129+
twitter: "https://x.com/cursorsaudi",
130+
},
131+
ambassadors: [
132+
{ name: "Mazen Alotaibi", city: "Riyadh", cityAr: "الرياض", twitter: "https://x.com/ma7dev" },
133+
{ name: "Abdulhakeem Almidan", city: "Khobar", cityAr: "الخبر", twitter: "https://x.com/abdulhakeem_mdn" },
134+
],
135+
} as const;
136+
```
137+
138+
## Coding Conventions
139+
140+
- All `.ts` files use type hints and JSDoc/docstrings.
141+
- Prefer stateless, pure functions in `utils/`.
142+
- Components are black-box: props in, HTML out. No side effects.
143+
- Content collection access only through utility functions in `src/utils/events.ts`.
144+
- Keep `config.ts` as the single source of truth for site metadata.
145+
146+
## Reference Projects
147+
148+
- **CursorThailand.com**: Design/UX inspiration (hero, events, community feel)
149+
- **ma7.dev** (`/Users/ma7dev/Projects/ma7.dev`): Astro + Tailwind v4 + GitHub Pages deployment reference

.github/workflows/deploy.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Deploy to GitHub Pages
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
pages: write
11+
id-token: write
12+
13+
concurrency:
14+
group: pages
15+
cancel-in-progress: true
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
24+
- name: Setup pnpm
25+
uses: pnpm/action-setup@v4
26+
with:
27+
version: 9
28+
29+
- name: Setup Node
30+
uses: actions/setup-node@v4
31+
with:
32+
node-version: 20
33+
cache: "pnpm"
34+
35+
- name: Install dependencies
36+
run: pnpm install --frozen-lockfile
37+
38+
- name: Build site
39+
run: pnpm build
40+
41+
- name: Setup Pages
42+
uses: actions/configure-pages@v5
43+
44+
- name: Upload artifact
45+
uses: actions/upload-pages-artifact@v3
46+
with:
47+
path: ./dist
48+
49+
deploy:
50+
needs: build
51+
runs-on: ubuntu-latest
52+
environment:
53+
name: github-pages
54+
url: ${{ steps.deployment.outputs.page_url }}
55+
steps:
56+
- name: Deploy
57+
id: deployment
58+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules
2+
dist
3+
.astro
4+
.DS_Store
5+
src/data/events/
6+
public/events/
7+

CLAUDE.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# CLAUDE.md — saacchq.org
2+
3+
## Commands
4+
5+
```bash
6+
pnpm install # Install dependencies
7+
npx astro dev # Dev server (localhost:4321)
8+
npx astro build # Production build → ./dist
9+
npx astro preview # Preview production build
10+
```
11+
12+
## Architecture
13+
14+
Astro 5 static site, single page (`src/pages/index.astro`). Bilingual (Arabic RTL default, English LTR) with client-side `localStorage` toggle. Dark mode only — no theme switcher. Minimal manifesto-style design.
15+
16+
### Stack
17+
18+
- **Framework**: Astro 5 (static SSG)
19+
- **Styling**: Tailwind CSS v4 via `@tailwindcss/vite` plugin (configured in `astro.config.ts`)
20+
- **TypeScript**: Strict mode (`astro/tsconfigs/strict`)
21+
- **Package manager**: pnpm
22+
- **Deployment**: GitHub Pages via Actions (pnpm v9, Node 20) on push to `main`
23+
24+
### Path alias
25+
26+
`@/*``./src/*` (configured in `tsconfig.json`)
27+
28+
## Project Structure
29+
30+
```
31+
src/
32+
├── pages/index.astro # Single page (manifesto layout)
33+
├── layouts/Layout.astro # Base HTML shell (dark mode, RTL/LTR, meta)
34+
├── components/ # Astro components (Header, Manifesto, Footer, LangToggle)
35+
├── config.ts # Site metadata and social links (single source of truth)
36+
├── i18n/{ar,en}.json # UI translation strings (manifesto content)
37+
├── i18n/index.ts # getTranslation(lang, key) and t(lang, key) helpers
38+
└── styles/global.css # Tailwind imports, dark theme CSS variables
39+
public/
40+
├── toggle-lang.js # Runs before hydration to set <html dir/lang> from localStorage
41+
└── CNAME # saacchq.org
42+
```
43+
44+
## i18n
45+
46+
- JSON translation files: `src/i18n/ar.json`, `src/i18n/en.json`
47+
- `public/toggle-lang.js` sets `<html dir>` and `lang` from `localStorage` before render (prevents layout flash)
48+
- Components call `getTranslation(lang, key)` or `t(lang, key)` from `src/i18n/index.ts`
49+
- Manifesto content lives in the i18n JSON files (6 numbered points + intro + disclaimer)
50+
51+
## Design Tokens (Dark Only)
52+
53+
- Background: `#0F0F0F` | Surface: `#171717` | Border: `#252525`
54+
- Primary text: `#FFFFFF` | Secondary: `#999999` | Dim: `#6E6E6E`
55+
56+
## Conventions
57+
58+
- Components are stateless: props in, HTML out, no side effects
59+
- `src/config.ts` is the single source of truth for site metadata and social links
60+
- Bilingual content uses `lang-ar`/`lang-en` CSS classes toggled by `html[lang]`
61+
- Use `getTranslation()` for dynamic keys, `t()` for static typed keys

CNAME

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
saacchq.org

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# saacchq.github.io

astro.config.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { defineConfig } from "astro/config";
2+
import sitemap from "@astrojs/sitemap";
3+
import tailwind from "@tailwindcss/vite";
4+
5+
export default defineConfig({
6+
site: "https://saacchq.org",
7+
integrations: [sitemap()],
8+
vite: {
9+
plugins: [tailwind()],
10+
},
11+
});
12+

0 commit comments

Comments
 (0)