diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 81c14327..08903ba5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: CI on: pull_request: - branches: [develop] + branches: [develop, main] push: branches: [main] @@ -18,6 +18,7 @@ permissions: id-token: write jobs: + # ── Rust ── check: name: Check runs-on: ubuntu-latest @@ -49,7 +50,7 @@ jobs: - run: cargo clippy --all-targets -- -D warnings audit: - name: Security Audit + name: Security Audit (CVE) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -75,4 +76,64 @@ jobs: - uses: Swatinem/rust-cache@v2 - run: cargo build --release + # ── Website ── + website-lint: + name: Website Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 24 + cache: npm + cache-dependency-path: website/package-lock.json + - run: npm ci + working-directory: website + - run: npx svelte-check --tsconfig ./tsconfig.json --output human + working-directory: website + + website-build: + name: Website Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 24 + cache: npm + cache-dependency-path: website/package-lock.json + - run: npm ci + working-directory: website + - run: npm run build + working-directory: website + - name: Verify build output + run: | + if [ ! -d "website/build" ] || [ -z "$(ls -A website/build)" ]; then + echo "::error::Build output is empty or missing." + exit 1 + fi + # ── Dependency freshness ── + npm-audit: + name: NPM Audit + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 24 + cache: npm + cache-dependency-path: website/package-lock.json + - run: npm audit --audit-level=moderate || true + working-directory: website + + cargo-outdated: + name: Cargo Outdated + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - name: Install cargo-outdated + run: cargo install cargo-outdated --locked 2>/dev/null || true + - run: cargo outdated || true diff --git a/website/src/app.css b/website/src/app.css index eb16a7aa..d0b315da 100644 --- a/website/src/app.css +++ b/website/src/app.css @@ -587,3 +587,113 @@ code, .font-mono { padding: var(--space-6) var(--space-4) var(--space-12); } } + +/* ---- Separator Gradient ---- */ +.separator-gradient { + max-width: 1152px; + margin-left: auto; + margin-right: auto; + padding-left: var(--space-6); + padding-right: var(--space-6); + height: 1px; + background: linear-gradient( + 90deg, + transparent, + oklch(0.65 0.22 270 / 0.3), + transparent + ); +} + +@media (min-width: 768px) { + .separator-gradient { + padding-left: var(--space-8); + padding-right: var(--space-8); + } +} + +@media (min-width: 1280px) { + .separator-gradient { + padding-left: var(--space-10); + padding-right: var(--space-10); + } +} + +/* ---- Grid Background ---- */ +.grid-bg { + background-image: + linear-gradient(oklch(0.27 0.01 270 / 0.3) 1px, transparent 1px), + linear-gradient(90deg, oklch(0.27 0.01 270 / 0.3) 1px, transparent 1px); + background-size: 64px 64px; +} + +/* ---- Architecture Flow ---- */ +.arch-step { + width: 100%; + max-width: 320px; + padding: var(--space-5) var(--space-6); + border-radius: var(--space-4); + background: var(--card); + border: 1px solid oklch(0.27 0.01 270 / 0.5); + text-align: center; +} + +.arch-step-highlight { + width: 100%; + max-width: 320px; + padding: var(--space-5) var(--space-6); + border-radius: var(--space-4); + text-align: center; + border: 2px solid var(--accent); + background: oklch(0.65 0.22 270 / 0.08); +} + +.arch-connector { + display: flex; + flex-direction: column; + align-items: center; + padding: var(--space-1) 0; +} + +.arch-connector-line { + width: 1px; + height: var(--space-4); + background: oklch(0.65 0.22 270 / 0.3); +} + +.arch-connector-label { + padding: var(--space-1) var(--space-3); + border-radius: var(--space-1); + font-family: var(--font-mono); + font-size: 12px; + color: var(--accent); + background: var(--card); + border: 1px solid oklch(0.65 0.22 270 / 0.2); +} + +/* ---- Audience Table ---- */ +.audience-table { + width: 100%; + border-collapse: collapse; +} + +.audience-table th, +.audience-table td { + padding: var(--space-3) var(--space-5); + border-bottom: 1px solid oklch(0.27 0.01 270 / 0.5); + text-align: left; + font-size: 14px; + color: var(--foreground); +} + +.audience-table thead th { + color: var(--muted-foreground); + font-weight: 500; + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.05em; + padding-bottom: var(--space-3); +} + +.audience-table tbody tr:last-child td { + border-bottom: none; +} diff --git a/website/src/routes/+layout.svelte b/website/src/routes/+layout.svelte index 43d67712..6445718e 100644 --- a/website/src/routes/+layout.svelte +++ b/website/src/routes/+layout.svelte @@ -7,35 +7,34 @@ const isDocs = $derived($page.url.pathname.startsWith('/docs')); -