diff --git a/openspec/changes/setup-base-layout/.openspec.yaml b/openspec/changes/archive/2026-04-10-step-001-project-scaffold/.openspec.yaml
similarity index 100%
rename from openspec/changes/setup-base-layout/.openspec.yaml
rename to openspec/changes/archive/2026-04-10-step-001-project-scaffold/.openspec.yaml
diff --git a/openspec/changes/archive/2026-04-10-step-001-project-scaffold/design.md b/openspec/changes/archive/2026-04-10-step-001-project-scaffold/design.md
new file mode 100644
index 0000000..acfe906
--- /dev/null
+++ b/openspec/changes/archive/2026-04-10-step-001-project-scaffold/design.md
@@ -0,0 +1,77 @@
+## Context
+
+The Astro project was scaffolded with `astro@6.1.5` and directory structure in place, but `astro.config.mjs` is empty and no Tailwind integration exists. The Archia woff2 font files are already present at `src/assets/fonts/archia/`. The migration steps doc was written expecting Tailwind v3 patterns (`tailwind.config.mjs`); we are using Tailwind v4 instead.
+
+## Goals / Non-Goals
+
+**Goals:**
+- Tailwind v4 fully wired into the Astro 6 build pipeline
+- All Qumo brand color tokens available as Tailwind utility classes (`bg-midnight`, `text-snow`, etc.)
+- `font-archia` available as a Tailwind font utility
+- All 6 Archia weights loaded via `@font-face` with `font-display: swap`
+- `@astrojs/sitemap` configured with `site: 'https://qumo.io'`
+- A smoke test page that confirms every token and weight renders correctly
+
+**Non-Goals:**
+- No real page content, layout, or navigation (those are steps 002–004)
+- No NL locale routing yet
+- No SEO meta tags or structured data yet
+- No production optimisation of font loading (preloads come in step 002 with BaseLayout)
+
+## Decisions
+
+### Tailwind v4 over v3
+
+**Decision:** Use `@tailwindcss/vite` (Tailwind v4) rather than `tailwindcss@3` + `@astrojs/tailwind`.
+
+**Rationale:** Tailwind v4 is the current major version and integrates natively with Vite via a single Vite plugin — no Astro integration adapter needed. Configuration is CSS-based (`@theme` block), which keeps brand tokens co-located with the font-face declarations in one file. Astro 6 ships with Vite 6, which is fully supported.
+
+**Alternative considered:** Tailwind v3 (`tailwind.config.mjs`). Rejected because it requires an additional `@astrojs/tailwind` adapter with limited Astro 6 testing, and the JS config file adds complexity for what is simply a set of color + font token definitions.
+
+### CSS-based token definition
+
+**Decision:** Brand tokens defined in `src/styles/global.css` using the `@theme` block, not in a JS config.
+
+```css
+@import "tailwindcss";
+
+@theme {
+ --color-midnight: #102022;
+ --color-snow: #F3F3F3;
+ --color-brand-blue: #5257E4;
+ --color-brand-red: #F71E3E;
+ --font-archia: "Archia", ui-sans-serif, system-ui, sans-serif;
+}
+```
+
+**Rationale:** Tailwind v4 CSS variables in `@theme` are automatically exposed as utilities (`bg-midnight`, `text-snow`, `font-archia`, etc.) with no additional config. This is the idiomatic v4 pattern.
+
+### Gradient as CSS custom property, not a Tailwind utility
+
+**Decision:** Define the brand gradient as a CSS custom property in `global.css` rather than a Tailwind background utility.
+
+```css
+:root {
+ --gradient-brand: linear-gradient(135deg, #5257E4, #F71E3E);
+}
+```
+
+**Rationale:** The gradient is used in specific, controlled contexts (hero accent, CTA sections) — never as a flat background. A raw CSS variable is easier to apply precisely than a generated utility class, and avoids accidentally using the gradient colors as standalone flat colors.
+
+### Font loading strategy
+
+**Decision:** `@font-face` declarations in `global.css` with `font-display: swap`. Load Regular, SemiBold, and Bold in the initial stylesheet; defer Thin, Light, and Medium.
+
+**Rationale:** Archia Regular/SemiBold/Bold covers all visible text in the design. Thin/Light/Medium are used sparingly if at all. Font preloads (``) will be added to BaseLayout in step 002 for the three primary weights.
+
+### Smoke test in index.astro
+
+**Decision:** Replace the default `index.astro` with a dev-only smoke test. It is not a real page — it will be fully replaced in the homepage step.
+
+**Structure:** Color swatch grid (4 swatches + gradient bar) + font weight table (Thin → Bold, each showing uppercase and sentence-case samples) + a note that this is a dev artifact.
+
+## Risks / Trade-offs
+
+- **Tailwind v4 is newer** → Less community Q&A available. Mitigation: Astro Docs MCP server has current documentation; the API surface for what we need (colors, fonts) is stable.
+- **`@tailwindcss/typography` compatibility** → Already in devDeps; v4-compatible version should be installed. Mitigation: verify it installs without peer dep errors after `npm install`.
+- **Smoke test left in place too long** → If step 002 is delayed, the index route shows a dev page. Acceptable: this is a dev-only environment until deployment.
diff --git a/openspec/changes/archive/2026-04-10-step-001-project-scaffold/proposal.md b/openspec/changes/archive/2026-04-10-step-001-project-scaffold/proposal.md
new file mode 100644
index 0000000..f35c3cf
--- /dev/null
+++ b/openspec/changes/archive/2026-04-10-step-001-project-scaffold/proposal.md
@@ -0,0 +1,33 @@
+## Why
+
+The Astro project scaffold exists but has no Tailwind CSS integration or brand tokens configured. Before any UI work can begin, the design system foundation must be in place: brand colors, the Archia typeface, and the gradient — all wired into Tailwind so every subsequent step can use utility classes directly.
+
+## What Changes
+
+- Install `tailwindcss` and `@tailwindcss/vite` (Tailwind v4) and `@astrojs/sitemap`
+- Configure `astro.config.mjs` with the Vite Tailwind plugin and sitemap integration
+- Create `src/styles/global.css` with:
+ - `@import "tailwindcss"`
+ - `@theme` block defining brand color tokens and `font-archia`
+ - `@font-face` declarations for all 6 Archia weights (Thin, Light, Regular, Medium, SemiBold, Bold)
+- Replace the default `src/pages/index.astro` with a brand smoke test page showing color swatches, font weight samples, and a gradient bar
+- No `tailwind.config.mjs` — configuration is CSS-based (Tailwind v4 pattern)
+
+## Capabilities
+
+### New Capabilities
+
+- `brand-tokens`: Qumo design system tokens available as Tailwind utilities — brand colors (`midnight`, `snow`, `brand-blue`, `brand-red`), `font-archia`, and the gradient definition
+
+### Modified Capabilities
+
+_(none)_
+
+## Impact
+
+- `website/package.json` — new dependencies: `tailwindcss`, `@tailwindcss/vite`, `@astrojs/sitemap`
+- `website/astro.config.mjs` — adds Vite plugin and sitemap integration
+- `website/src/styles/global.css` — new file, imported globally
+- `website/src/pages/index.astro` — replaced with temporary smoke test (will be replaced again in a later step when the homepage is built)
+- No SEO impact — smoke test page is a dev-only visual check
+- No content strings needed — smoke test has no user-visible text to localize
diff --git a/openspec/changes/archive/2026-04-10-step-001-project-scaffold/specs/brand-tokens/spec.md b/openspec/changes/archive/2026-04-10-step-001-project-scaffold/specs/brand-tokens/spec.md
new file mode 100644
index 0000000..cb95bed
--- /dev/null
+++ b/openspec/changes/archive/2026-04-10-step-001-project-scaffold/specs/brand-tokens/spec.md
@@ -0,0 +1,81 @@
+## ADDED Requirements
+
+### Requirement: Brand color tokens available as Tailwind utilities
+The build system SHALL expose Qumo brand colors as Tailwind utility classes via the `@theme` block in `global.css`. The following tokens SHALL be defined:
+- `--color-midnight: #102022` → `bg-midnight`, `text-midnight`, `border-midnight`
+- `--color-snow: #F3F3F3` → `bg-snow`, `text-snow`, `border-snow`
+- `--color-brand-blue: #5257E4` → `bg-brand-blue`, `text-brand-blue`
+- `--color-brand-red: #F71E3E` → `bg-brand-red`, `text-brand-red`
+
+#### Scenario: Color utilities compile correctly
+- **WHEN** a component uses `bg-midnight text-snow`
+- **THEN** the compiled CSS contains the exact hex values `#102022` and `#F3F3F3`
+
+#### Scenario: Gradient is available as a CSS variable
+- **WHEN** a component applies `style="background: var(--gradient-brand)"`
+- **THEN** the element renders a linear gradient from `#5257E4` to `#F71E3E`
+
+---
+
+### Requirement: Archia font available as a Tailwind utility
+The build system SHALL expose `font-archia` as a Tailwind font-family utility via `--font-archia` in the `@theme` block. The font stack SHALL be `"Archia", ui-sans-serif, system-ui, sans-serif`.
+
+#### Scenario: Font utility applies correct stack
+- **WHEN** a component uses `font-archia`
+- **THEN** the compiled CSS sets `font-family: "Archia", ui-sans-serif, system-ui, sans-serif`
+
+---
+
+### Requirement: All 6 Archia weights loaded via @font-face
+`global.css` SHALL declare `@font-face` rules for all 6 Archia weights using the woff2 files in `src/assets/fonts/archia/`. Each declaration SHALL use `font-display: swap`.
+
+| Weight name | CSS font-weight | File |
+|-------------|-----------------|-------------------------------|
+| Thin | 100 | archia-thin-webfont.woff2 |
+| Light | 300 | archia-light-webfont.woff2 |
+| Regular | 400 | archia-regular-webfont.woff2 |
+| Medium | 500 | archia-medium-webfont.woff2 |
+| SemiBold | 600 | archia-semibold-webfont.woff2 |
+| Bold | 700 | archia-bold-webfont.woff2 |
+
+#### Scenario: Font renders with correct weight
+- **WHEN** a component uses `font-archia font-bold`
+- **THEN** the browser loads `archia-bold-webfont.woff2` and renders text at weight 700
+
+#### Scenario: Fallback renders while font loads
+- **WHEN** the woff2 file has not yet loaded
+- **THEN** the browser renders text using the system fallback font (`ui-sans-serif`) due to `font-display: swap`
+
+---
+
+### Requirement: global.css imported globally by Astro
+`src/styles/global.css` SHALL be imported in `astro.config.mjs` or in the root layout so that brand tokens and font-face declarations apply to every page.
+
+#### Scenario: Tokens available without per-page import
+- **WHEN** any `.astro` page component uses `bg-midnight`
+- **THEN** the class applies without that page importing `global.css` directly
+
+---
+
+### Requirement: Sitemap integration configured
+`astro.config.mjs` SHALL include `@astrojs/sitemap` with `site: 'https://qumo.io'` so that `sitemap-index.xml` is generated on every build.
+
+#### Scenario: Sitemap generated on build
+- **WHEN** `npm run build` is executed
+- **THEN** `dist/sitemap-index.xml` and `dist/sitemap-0.xml` are present in the output
+
+---
+
+### Requirement: Brand smoke test page
+`src/pages/index.astro` SHALL be a temporary visual smoke test page (not production content) that allows a developer to verify all brand tokens render correctly. It SHALL show:
+- A color swatch for each brand color token (Midnight, Snow, Brand Blue, Brand Red)
+- A gradient bar using `--gradient-brand`
+- A font weight sample row for each of the 6 Archia weights (showing uppercase and sentence-case text)
+
+#### Scenario: Smoke test builds without errors
+- **WHEN** `npm run build` is run after setup
+- **THEN** the build succeeds with zero errors
+
+#### Scenario: All font weights visible in dev
+- **WHEN** `npm run dev` is run and the index page is opened
+- **THEN** 6 distinct font weights are visible and the gradient bar shows the blue-to-red gradient
diff --git a/openspec/changes/archive/2026-04-10-step-001-project-scaffold/tasks.md b/openspec/changes/archive/2026-04-10-step-001-project-scaffold/tasks.md
new file mode 100644
index 0000000..1c5bc0e
--- /dev/null
+++ b/openspec/changes/archive/2026-04-10-step-001-project-scaffold/tasks.md
@@ -0,0 +1,30 @@
+## 1. Install dependencies
+
+- [x] 1.1 Install `tailwindcss` and `@tailwindcss/vite` in `website/`
+- [x] 1.2 Install `@astrojs/sitemap` in `website/`
+
+## 2. Configure Astro
+
+- [x] 2.1 Update `astro.config.mjs` to add `@tailwindcss/vite` as a Vite plugin and `@astrojs/sitemap` as an integration with `site: 'https://qumo.io'`
+
+## 3. Create global.css
+
+- [x] 3.1 Create `src/styles/global.css` with `@import "tailwindcss"`
+- [x] 3.2 Add `@theme` block with brand color tokens: `--color-midnight`, `--color-snow`, `--color-brand-blue`, `--color-brand-red`
+- [x] 3.3 Add `--font-archia` to the `@theme` block with system fallback stack
+- [x] 3.4 Add `:root` block with `--gradient-brand: linear-gradient(135deg, #5257E4, #F71E3E)`
+- [x] 3.5 Add `@font-face` declarations for all 6 Archia weights (Thin/100, Light/300, Regular/400, Medium/500, SemiBold/600, Bold/700) pointing to `../assets/fonts/archia/` woff2 files, each with `font-display: swap`
+
+## 4. Wire global.css into Astro
+
+- [x] 4.1 Import `../styles/global.css` in `src/pages/index.astro` (will move to BaseLayout in step 002)
+
+## 5. Brand smoke test page
+
+- [x] 5.1 Replace the default `src/pages/index.astro` content with a smoke test page: a color swatch grid (Midnight, Snow, Brand Blue, Brand Red, + gradient bar) and a font weight table (Thin through Bold, each row showing uppercase + sentence-case sample text)
+
+## 6. Verify
+
+- [x] 6.1 Run `npm run build` inside `website/` — must succeed with zero errors
+- [x] 6.2 Run `npm run dev` and open the index page — verify all 4 color swatches, the gradient bar, and all 6 font weights render correctly
+- [x] 6.3 Confirm `dist/sitemap-index.xml` is present in the build output
diff --git a/openspec/changes/archive/2026-04-10-step-002-base-layout/.openspec.yaml b/openspec/changes/archive/2026-04-10-step-002-base-layout/.openspec.yaml
new file mode 100644
index 0000000..e49efd1
--- /dev/null
+++ b/openspec/changes/archive/2026-04-10-step-002-base-layout/.openspec.yaml
@@ -0,0 +1,2 @@
+schema: spec-driven
+created: 2026-04-10
diff --git a/openspec/changes/archive/2026-04-10-step-002-base-layout/design.md b/openspec/changes/archive/2026-04-10-step-002-base-layout/design.md
new file mode 100644
index 0000000..2324b7b
--- /dev/null
+++ b/openspec/changes/archive/2026-04-10-step-002-base-layout/design.md
@@ -0,0 +1,79 @@
+## Context
+
+Step 001 produced a working Astro project with Tailwind v4 brand tokens, Archia font-face declarations, and a smoke-test `index.astro` that manually constructs its own `` document. Every subsequent page (homepage, about, AI Launchpad, contact, privacy — plus `/nl/*` variants) will need the same HTML shell with correct `
` meta, hreflang, OG tags, and body defaults. Without a shared layout this is copied per page, creating drift and SEO inconsistency.
+
+Current state of note:
+- `global.css` is Tailwind v4 (`@import "tailwindcss"` + `@theme`) — no `tailwind.config.mjs`
+- Archia `@font-face` declarations already live in `global.css`
+- `public/` has `favicon.svg` and `favicon.ico`
+- No `src/layouts/`, `src/components/`, or `src/content/` directories yet
+
+## Goals / Non-Goals
+
+**Goals:**
+- Single `BaseLayout.astro` that every page wraps its content in
+- Correct SEO ``: charset, viewport, favicon, font preloads, canonical, hreflang, OG, Twitter card
+- Body defaults applied once (Midnight bg, Snow text, Archia font)
+- JSON-LD injection mechanism (both prop and named slot)
+- Stub `Nav.astro` and `Footer.astro` so BaseLayout can import them (filled in steps 003+)
+- `en.json` / `nl.json` content files + `i18n.ts` loader for global meta fields
+- `index.astro` updated to use `BaseLayout`
+
+**Non-Goals:**
+- Actual nav or footer UI (step 003)
+- Page-specific JSON-LD schemas (each page step handles its own)
+- OG image file creation (deferred — `ogImage` prop will be empty string initially)
+- Any client-side JavaScript
+- `@astrojs/image` or picture optimisation (images not needed in this step)
+
+## Decisions
+
+### 1. hreflang: explicit props, not derived
+
+**Decision**: `BaseLayout` accepts two explicit props — `canonicalUrl: string` and `alternateUrl: string`. The component does not compute the alternate URL.
+
+**Rationale**: EN routes are `/about`, NL routes are `/nl/about` — a simple `/nl/` prefix works for most paths, but `/contact` vs `/nl/contact` or future edge cases (slugs, catch-alls) could diverge. Explicit props make each page's intent clear and avoid regex surprises. Callers always know their own routes.
+
+**Alternative considered**: Auto-derive by prepending/stripping `/nl/` based on `locale` prop. Rejected: fragile for edge cases, magic at a distance.
+
+### 2. Font preloads: critical weights only
+
+**Decision**: Preload only Archia Regular (400), SemiBold (600), and Bold (700). Thin (100) and Light (300) load on demand.
+
+**Rationale**: Each `` is an unconditional network request. Regular is needed for all body copy; SemiBold and Bold are used for headings and CTAs — the elements visible above the fold. Thin and Light appear only in specific decorative contexts (if at all) and are not worth the preload cost.
+
+### 3. JSON-LD: prop for common case + named slot for extras
+
+**Decision**: BaseLayout accepts an optional `jsonLd?: Record` prop. If provided, it is serialized with `JSON.stringify` and injected as ``
+
+#### Scenario: No JSON-LD script when prop omitted
+- **WHEN** `jsonLd` prop is not provided
+- **THEN** no ``
+- **THEN** that script tag SHALL appear in the rendered ``
+
+### Requirement: BaseLayout includes Nav and Footer stub components
+`BaseLayout.astro` SHALL import `src/components/Nav.astro` and `src/components/Footer.astro` and render them at the top and bottom of `` respectively. Both components are stubs that render nothing in this step.
+
+#### Scenario: Nav and Footer positions in body
+- **WHEN** any page uses BaseLayout
+- **THEN** the `` structure SHALL be: Nav stub output → `` (page content) → Footer stub output
+
+### Requirement: BaseLayout content slot renders page content
+A default `` SHALL be provided between Nav and Footer for page-specific content.
+
+#### Scenario: Page content appears in slot
+- **WHEN** a page places markup inside `...`
+- **THEN** that markup SHALL appear in the rendered body between Nav and Footer
diff --git a/openspec/changes/archive/2026-04-10-step-002-base-layout/specs/content-i18n/spec.md b/openspec/changes/archive/2026-04-10-step-002-base-layout/specs/content-i18n/spec.md
new file mode 100644
index 0000000..f698ff9
--- /dev/null
+++ b/openspec/changes/archive/2026-04-10-step-002-base-layout/specs/content-i18n/spec.md
@@ -0,0 +1,38 @@
+## ADDED Requirements
+
+### Requirement: Locale content JSON files contain global meta fields
+`src/content/en.json` and `src/content/nl.json` SHALL each contain a top-level `"meta"` key with the following fields:
+- `siteName: string` — the site name (e.g., `"Qumo"`)
+- `defaultTitle: string` — default page title (used as fallback)
+- `defaultDescription: string` — default meta description (used as fallback)
+- `defaultOgImage: string` — default OG image path; may be empty string initially
+
+#### Scenario: en.json has correct meta structure
+- **WHEN** `src/content/en.json` is parsed as JSON
+- **THEN** it SHALL have a `meta` object with string values for `siteName`, `defaultTitle`, `defaultDescription`, and `defaultOgImage`
+
+#### Scenario: nl.json has correct meta structure
+- **WHEN** `src/content/nl.json` is parsed as JSON
+- **THEN** it SHALL have the same `meta` object shape as `en.json`, with Dutch-language values for `defaultTitle` and `defaultDescription`
+
+### Requirement: i18n helper returns correct content for locale
+`src/content/i18n.ts` SHALL export a function `getContent(locale: string)` that returns the parsed content object for the given locale. It SHALL return the EN content object for any unrecognized locale string.
+
+#### Scenario: Returns EN content for "en" locale
+- **WHEN** `getContent("en")` is called
+- **THEN** the function SHALL return the parsed contents of `src/content/en.json`
+
+#### Scenario: Returns NL content for "nl" locale
+- **WHEN** `getContent("nl")` is called
+- **THEN** the function SHALL return the parsed contents of `src/content/nl.json`
+
+#### Scenario: Falls back to EN for unknown locale
+- **WHEN** `getContent("fr")` or any unrecognized locale string is called
+- **THEN** the function SHALL return the parsed contents of `src/content/en.json`
+
+### Requirement: Content files use static imports (no runtime fetch)
+The `i18n.ts` helper SHALL use static ES module imports (`import enContent from './en.json'`) rather than dynamic `fetch` or `fs.readFile`. This ensures type safety and tree-shaking at build time.
+
+#### Scenario: Build succeeds with static imports
+- **WHEN** `npm run build` is executed in the `website/` directory
+- **THEN** the build SHALL complete without errors, with locale content bundled statically
diff --git a/openspec/changes/archive/2026-04-10-step-002-base-layout/tasks.md b/openspec/changes/archive/2026-04-10-step-002-base-layout/tasks.md
new file mode 100644
index 0000000..61e728b
--- /dev/null
+++ b/openspec/changes/archive/2026-04-10-step-002-base-layout/tasks.md
@@ -0,0 +1,33 @@
+## 1. Content Files
+
+- [x] 1.1 Create `src/content/en.json` with top-level `meta` key: `siteName`, `defaultTitle`, `defaultDescription`, `defaultOgImage` (empty string)
+- [x] 1.2 Create `src/content/nl.json` with same `meta` shape, Dutch values for `defaultTitle` and `defaultDescription`
+- [x] 1.3 Create `src/content/i18n.ts` exporting `getContent(locale: string)` using static imports of both JSON files; fall back to EN for unknown locales
+
+## 2. Stub Components
+
+- [x] 2.1 Create `src/components/Nav.astro` as an empty stub (renders nothing — filled in step 003)
+- [x] 2.2 Create `src/components/Footer.astro` as an empty stub (renders nothing — filled in a later step)
+
+## 3. BaseLayout Component
+
+- [x] 3.1 Create `src/layouts/BaseLayout.astro` with props: `title`, `description`, `locale` (default `"en"`), `canonicalUrl`, `alternateUrl`, `ogImage` (optional), `jsonLd` (optional `Record`)
+- [x] 3.2 Add `` content: ``, ``, ``, `` for both SVG and ICO favicons
+- [x] 3.3 Add three Archia font preload tags in ``: Regular (400), SemiBold (600), Bold (700) woff2 files only
+- [x] 3.4 Add `` and three hreflang `` tags (`en`, `nl`, `x-default`) using `canonicalUrl` and `alternateUrl` props
+- [x] 3.5 Add OG meta tags (`og:type`, `og:url`, `og:title`, `og:description`, `og:site_name`); add `og:image` only when `ogImage` is truthy
+- [x] 3.6 Add Twitter card meta tags (`twitter:card`, `twitter:title`, `twitter:description`); add `twitter:image` only when `ogImage` is truthy
+- [x] 3.7 Add JSON-LD script tag in `` rendered from `jsonLd` prop when provided (`set:html={JSON.stringify(jsonLd)}`)
+- [x] 3.8 Add `` inside `` for additional JSON-LD blocks
+- [x] 3.9 Add `` with ``, default ``, and `` in order
+
+## 4. Update Index Page
+
+- [x] 4.1 Update `src/pages/index.astro` to import and use `BaseLayout`, passing `title`, `description`, `canonicalUrl="https://qumo.io/"`, `alternateUrl="https://qumo.io/nl"`, and `locale="en"`; remove manual `//` shell
+
+## 5. Verification
+
+- [x] 5.1 Run `cd website && npm run build` — build must succeed with zero errors
+- [x] 5.2 View page source in browser (`npm run dev`): confirm `` contains charset, viewport, title, favicon links, three font preload tags, canonical, three hreflang links, OG tags, Twitter card tags
+- [x] 5.3 Confirm body has `bg-midnight text-snow font-archia` classes and smoke-test content still renders correctly
+- [x] 5.4 Confirm no `og:image` or `twitter:image` tag appears (since `ogImage` is not passed)
diff --git a/openspec/specs/base-layout/spec.md b/openspec/specs/base-layout/spec.md
new file mode 100644
index 0000000..9a197fc
--- /dev/null
+++ b/openspec/specs/base-layout/spec.md
@@ -0,0 +1,80 @@
+## Purpose
+
+Defines the `BaseLayout.astro` component that provides the complete HTML document shell for every page of the Qumo website, including all `` meta tags, font preloading, hreflang alternates, JSON-LD support, and the Nav/Footer stub components.
+
+## Requirements
+
+### Requirement: BaseLayout provides complete HTML document shell
+`src/layouts/BaseLayout.astro` SHALL render a complete HTML document (``, ``, ``, ``) that every page can wrap its content in. It SHALL accept the following props:
+- `title: string` — page-specific `` and OG title
+- `description: string` — page-specific meta description and OG description
+- `locale?: string` — BCP 47 language tag, default `"en"`
+- `canonicalUrl: string` — absolute canonical URL for this page
+- `alternateUrl: string` — absolute URL of the alternate-locale version of this page
+- `ogImage?: string` — absolute URL for `og:image`; tag is omitted when falsy
+- `jsonLd?: Record` — structured data object to serialize as JSON-LD
+
+#### Scenario: Page renders with all head meta tags
+- **WHEN** a page wraps its content in `` with all props provided
+- **THEN** the rendered HTML `` SHALL contain: ``, ``, `` for both SVG and ICO favicons, ``, `` for both locales, `` tags, `` tags, and ``
+
+#### Scenario: OG image tag omitted when ogImage is falsy
+- **WHEN** `ogImage` prop is an empty string or not provided
+- **THEN** no `` tag SHALL appear in the rendered HTML
+
+#### Scenario: Body has brand defaults
+- **WHEN** any page uses BaseLayout
+- **THEN** the `` element SHALL have Tailwind classes `bg-midnight text-snow font-archia` applied
+
+### Requirement: BaseLayout preloads critical Archia font weights
+The `` SHALL contain `` for Archia Regular (400), SemiBold (600), and Bold (700) woff2 files. Thin (100) and Light (300) SHALL NOT be preloaded.
+
+#### Scenario: Correct preload tags rendered
+- **WHEN** the page HTML is rendered
+- **THEN** exactly three font preload links SHALL appear in ``: one each for `archia-regular-webfont.woff2`, `archia-semibold-webfont.woff2`, and `archia-bold-webfont.woff2`
+
+### Requirement: BaseLayout renders hreflang alternates
+The `` SHALL contain `` tags for both `en` and `nl` locales, plus an `x-default` pointing to the EN URL.
+
+#### Scenario: EN page hreflang output
+- **WHEN** a page passes `locale="en"`, `canonicalUrl="https://qumo.io/about"`, `alternateUrl="https://qumo.io/nl/about"`
+- **THEN** the head SHALL contain:
+ - ``
+ - ``
+ - ``
+
+#### Scenario: NL page hreflang output
+- **WHEN** a page passes `locale="nl"`, `canonicalUrl="https://qumo.io/nl/about"`, `alternateUrl="https://qumo.io/about"`
+- **THEN** the head SHALL contain the same three hreflang tags with EN/NL values swapped appropriately, and `x-default` SHALL always point to the EN URL (the `alternateUrl` on NL pages)
+
+### Requirement: BaseLayout supports JSON-LD injection via prop
+When the `jsonLd` prop is provided, BaseLayout SHALL render a ``
+
+#### Scenario: No JSON-LD script when prop omitted
+- **WHEN** `jsonLd` prop is not provided
+- **THEN** no ``
+- **THEN** that script tag SHALL appear in the rendered ``
+
+### Requirement: BaseLayout includes Nav and Footer stub components
+`BaseLayout.astro` SHALL import `src/components/Nav.astro` and `src/components/Footer.astro` and render them at the top and bottom of `` respectively. Both components are stubs that render nothing in this step.
+
+#### Scenario: Nav and Footer positions in body
+- **WHEN** any page uses BaseLayout
+- **THEN** the `` structure SHALL be: Nav stub output → `` (page content) → Footer stub output
+
+### Requirement: BaseLayout content slot renders page content
+A default `` SHALL be provided between Nav and Footer for page-specific content.
+
+#### Scenario: Page content appears in slot
+- **WHEN** a page places markup inside `...`
+- **THEN** that markup SHALL appear in the rendered body between Nav and Footer
diff --git a/openspec/specs/brand-tokens/spec.md b/openspec/specs/brand-tokens/spec.md
new file mode 100644
index 0000000..2179591
--- /dev/null
+++ b/openspec/specs/brand-tokens/spec.md
@@ -0,0 +1,87 @@
+# Spec: Brand Tokens
+
+## Purpose
+
+Defines the Qumo brand design tokens (colors, typography, fonts) exposed as Tailwind CSS utilities and loaded globally across all pages. Covers color token configuration, Archia font-face declarations, global CSS import strategy, sitemap integration, and the initial brand smoke test page.
+
+## Requirements
+
+### Requirement: Brand color tokens available as Tailwind utilities
+The build system SHALL expose Qumo brand colors as Tailwind utility classes via the `@theme` block in `global.css`. The following tokens SHALL be defined:
+- `--color-midnight: #102022` → `bg-midnight`, `text-midnight`, `border-midnight`
+- `--color-snow: #F3F3F3` → `bg-snow`, `text-snow`, `border-snow`
+- `--color-brand-blue: #5257E4` → `bg-brand-blue`, `text-brand-blue`
+- `--color-brand-red: #F71E3E` → `bg-brand-red`, `text-brand-red`
+
+#### Scenario: Color utilities compile correctly
+- **WHEN** a component uses `bg-midnight text-snow`
+- **THEN** the compiled CSS contains the exact hex values `#102022` and `#F3F3F3`
+
+#### Scenario: Gradient is available as a CSS variable
+- **WHEN** a component applies `style="background: var(--gradient-brand)"`
+- **THEN** the element renders a linear gradient from `#5257E4` to `#F71E3E`
+
+---
+
+### Requirement: Archia font available as a Tailwind utility
+The build system SHALL expose `font-archia` as a Tailwind font-family utility via `--font-archia` in the `@theme` block. The font stack SHALL be `"Archia", ui-sans-serif, system-ui, sans-serif`.
+
+#### Scenario: Font utility applies correct stack
+- **WHEN** a component uses `font-archia`
+- **THEN** the compiled CSS sets `font-family: "Archia", ui-sans-serif, system-ui, sans-serif`
+
+---
+
+### Requirement: All 6 Archia weights loaded via @font-face
+`global.css` SHALL declare `@font-face` rules for all 6 Archia weights using the woff2 files in `src/assets/fonts/archia/`. Each declaration SHALL use `font-display: swap`.
+
+| Weight name | CSS font-weight | File |
+|-------------|-----------------|-------------------------------|
+| Thin | 100 | archia-thin-webfont.woff2 |
+| Light | 300 | archia-light-webfont.woff2 |
+| Regular | 400 | archia-regular-webfont.woff2 |
+| Medium | 500 | archia-medium-webfont.woff2 |
+| SemiBold | 600 | archia-semibold-webfont.woff2 |
+| Bold | 700 | archia-bold-webfont.woff2 |
+
+#### Scenario: Font renders with correct weight
+- **WHEN** a component uses `font-archia font-bold`
+- **THEN** the browser loads `archia-bold-webfont.woff2` and renders text at weight 700
+
+#### Scenario: Fallback renders while font loads
+- **WHEN** the woff2 file has not yet loaded
+- **THEN** the browser renders text using the system fallback font (`ui-sans-serif`) due to `font-display: swap`
+
+---
+
+### Requirement: global.css imported globally by Astro
+`src/styles/global.css` SHALL be imported in `astro.config.mjs` or in the root layout so that brand tokens and font-face declarations apply to every page.
+
+#### Scenario: Tokens available without per-page import
+- **WHEN** any `.astro` page component uses `bg-midnight`
+- **THEN** the class applies without that page importing `global.css` directly
+
+---
+
+### Requirement: Sitemap integration configured
+`astro.config.mjs` SHALL include `@astrojs/sitemap` with `site: 'https://qumo.io'` so that `sitemap-index.xml` is generated on every build.
+
+#### Scenario: Sitemap generated on build
+- **WHEN** `npm run build` is executed
+- **THEN** `dist/sitemap-index.xml` and `dist/sitemap-0.xml` are present in the output
+
+---
+
+### Requirement: Brand smoke test page
+`src/pages/index.astro` SHALL be a temporary visual smoke test page (not production content) that allows a developer to verify all brand tokens render correctly. It SHALL show:
+- A color swatch for each brand color token (Midnight, Snow, Brand Blue, Brand Red)
+- A gradient bar using `--gradient-brand`
+- A font weight sample row for each of the 6 Archia weights (showing uppercase and sentence-case text)
+
+#### Scenario: Smoke test builds without errors
+- **WHEN** `npm run build` is run after setup
+- **THEN** the build succeeds with zero errors
+
+#### Scenario: All font weights visible in dev
+- **WHEN** `npm run dev` is run and the index page is opened
+- **THEN** 6 distinct font weights are visible and the gradient bar shows the blue-to-red gradient
diff --git a/openspec/specs/content-i18n/spec.md b/openspec/specs/content-i18n/spec.md
new file mode 100644
index 0000000..a89e2ab
--- /dev/null
+++ b/openspec/specs/content-i18n/spec.md
@@ -0,0 +1,42 @@
+## Purpose
+
+Defines the content localisation system for the Qumo website, including the JSON content files structure and the `i18n.ts` helper that provides locale-appropriate content to pages and components.
+
+## Requirements
+
+### Requirement: Locale content JSON files contain global meta fields
+`src/content/en.json` and `src/content/nl.json` SHALL each contain a top-level `"meta"` key with the following fields:
+- `siteName: string` — the site name (e.g., `"Qumo"`)
+- `defaultTitle: string` — default page title (used as fallback)
+- `defaultDescription: string` — default meta description (used as fallback)
+- `defaultOgImage: string` — default OG image path; may be empty string initially
+
+#### Scenario: en.json has correct meta structure
+- **WHEN** `src/content/en.json` is parsed as JSON
+- **THEN** it SHALL have a `meta` object with string values for `siteName`, `defaultTitle`, `defaultDescription`, and `defaultOgImage`
+
+#### Scenario: nl.json has correct meta structure
+- **WHEN** `src/content/nl.json` is parsed as JSON
+- **THEN** it SHALL have the same `meta` object shape as `en.json`, with Dutch-language values for `defaultTitle` and `defaultDescription`
+
+### Requirement: i18n helper returns correct content for locale
+`src/content/i18n.ts` SHALL export a function `getContent(locale: string)` that returns the parsed content object for the given locale. It SHALL return the EN content object for any unrecognized locale string.
+
+#### Scenario: Returns EN content for "en" locale
+- **WHEN** `getContent("en")` is called
+- **THEN** the function SHALL return the parsed contents of `src/content/en.json`
+
+#### Scenario: Returns NL content for "nl" locale
+- **WHEN** `getContent("nl")` is called
+- **THEN** the function SHALL return the parsed contents of `src/content/nl.json`
+
+#### Scenario: Falls back to EN for unknown locale
+- **WHEN** `getContent("fr")` or any unrecognized locale string is called
+- **THEN** the function SHALL return the parsed contents of `src/content/en.json`
+
+### Requirement: Content files use static imports (no runtime fetch)
+The `i18n.ts` helper SHALL use static ES module imports (`import enContent from './en.json'`) rather than dynamic `fetch` or `fs.readFile`. This ensures type safety and tree-shaking at build time.
+
+#### Scenario: Build succeeds with static imports
+- **WHEN** `npm run build` is executed in the `website/` directory
+- **THEN** the build SHALL complete without errors, with locale content bundled statically
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..0da99c8
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1354 @@
+{
+ "name": "qumo-website",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "devDependencies": {
+ "@astrojs/sitemap": "^3.7.2",
+ "@tailwindcss/vite": "^4.2.2",
+ "tailwindcss": "^4.2.2"
+ }
+ },
+ "node_modules/@astrojs/sitemap": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.7.2.tgz",
+ "integrity": "sha512-PqkzkcZTb5ICiyIR8VoKbIAP/laNRXi5tw616N1Ckk+40oNB8Can1AzVV56lrbC5GKSZFCyJYUVYqVivMisvpA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sitemap": "^9.0.0",
+ "stream-replace-string": "^2.0.0",
+ "zod": "^4.3.6"
+ }
+ },
+ "node_modules/@emnapi/core": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz",
+ "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.2.1",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz",
+ "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
+ "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/remapping": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz",
+ "integrity": "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@tybys/wasm-util": "^0.10.1"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ },
+ "peerDependencies": {
+ "@emnapi/core": "^1.7.1",
+ "@emnapi/runtime": "^1.7.1"
+ }
+ },
+ "node_modules/@oxc-project/types": {
+ "version": "0.124.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.124.0.tgz",
+ "integrity": "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
+ }
+ },
+ "node_modules/@rolldown/binding-android-arm64": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.15.tgz",
+ "integrity": "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-arm64": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.15.tgz",
+ "integrity": "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-x64": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.15.tgz",
+ "integrity": "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-freebsd-x64": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.15.tgz",
+ "integrity": "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.15.tgz",
+ "integrity": "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-gnu": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.15.tgz",
+ "integrity": "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-musl": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.15.tgz",
+ "integrity": "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-ppc64-gnu": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.15.tgz",
+ "integrity": "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-s390x-gnu": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.15.tgz",
+ "integrity": "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-x64-gnu": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.15.tgz",
+ "integrity": "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-x64-musl": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.15.tgz",
+ "integrity": "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-openharmony-arm64": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.15.tgz",
+ "integrity": "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-wasm32-wasi": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.15.tgz",
+ "integrity": "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "1.9.2",
+ "@emnapi/runtime": "1.9.2",
+ "@napi-rs/wasm-runtime": "^1.1.3"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-arm64-msvc": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.15.tgz",
+ "integrity": "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-x64-msvc": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.15.tgz",
+ "integrity": "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.15.tgz",
+ "integrity": "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tailwindcss/node": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.2.tgz",
+ "integrity": "sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/remapping": "^2.3.5",
+ "enhanced-resolve": "^5.19.0",
+ "jiti": "^2.6.1",
+ "lightningcss": "1.32.0",
+ "magic-string": "^0.30.21",
+ "source-map-js": "^1.2.1",
+ "tailwindcss": "4.2.2"
+ }
+ },
+ "node_modules/@tailwindcss/oxide": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.2.tgz",
+ "integrity": "sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 20"
+ },
+ "optionalDependencies": {
+ "@tailwindcss/oxide-android-arm64": "4.2.2",
+ "@tailwindcss/oxide-darwin-arm64": "4.2.2",
+ "@tailwindcss/oxide-darwin-x64": "4.2.2",
+ "@tailwindcss/oxide-freebsd-x64": "4.2.2",
+ "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.2",
+ "@tailwindcss/oxide-linux-arm64-gnu": "4.2.2",
+ "@tailwindcss/oxide-linux-arm64-musl": "4.2.2",
+ "@tailwindcss/oxide-linux-x64-gnu": "4.2.2",
+ "@tailwindcss/oxide-linux-x64-musl": "4.2.2",
+ "@tailwindcss/oxide-wasm32-wasi": "4.2.2",
+ "@tailwindcss/oxide-win32-arm64-msvc": "4.2.2",
+ "@tailwindcss/oxide-win32-x64-msvc": "4.2.2"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-android-arm64": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.2.tgz",
+ "integrity": "sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-arm64": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.2.tgz",
+ "integrity": "sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-x64": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.2.tgz",
+ "integrity": "sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-freebsd-x64": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.2.tgz",
+ "integrity": "sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.2.tgz",
+ "integrity": "sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.2.tgz",
+ "integrity": "sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.2.tgz",
+ "integrity": "sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.2.tgz",
+ "integrity": "sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-musl": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.2.tgz",
+ "integrity": "sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.2.tgz",
+ "integrity": "sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==",
+ "bundleDependencies": [
+ "@napi-rs/wasm-runtime",
+ "@emnapi/core",
+ "@emnapi/runtime",
+ "@tybys/wasm-util",
+ "@emnapi/wasi-threads",
+ "tslib"
+ ],
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "^1.8.1",
+ "@emnapi/runtime": "^1.8.1",
+ "@emnapi/wasi-threads": "^1.1.0",
+ "@napi-rs/wasm-runtime": "^1.1.1",
+ "@tybys/wasm-util": "^0.10.1",
+ "tslib": "^2.8.1"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.2.tgz",
+ "integrity": "sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.2.tgz",
+ "integrity": "sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@tailwindcss/vite": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.2.tgz",
+ "integrity": "sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@tailwindcss/node": "4.2.2",
+ "@tailwindcss/oxide": "4.2.2",
+ "tailwindcss": "4.2.2"
+ },
+ "peerDependencies": {
+ "vite": "^5.2.0 || ^6 || ^7 || ^8"
+ }
+ },
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
+ "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "24.12.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.2.tgz",
+ "integrity": "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "undici-types": "~7.16.0"
+ }
+ },
+ "node_modules/@types/sax": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz",
+ "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/arg": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
+ "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.20.1",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz",
+ "integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.3.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/jiti": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
+ "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "jiti": "lib/jiti-cli.mjs"
+ }
+ },
+ "node_modules/lightningcss": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
+ "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
+ "dev": true,
+ "license": "MPL-2.0",
+ "dependencies": {
+ "detect-libc": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-android-arm64": "1.32.0",
+ "lightningcss-darwin-arm64": "1.32.0",
+ "lightningcss-darwin-x64": "1.32.0",
+ "lightningcss-freebsd-x64": "1.32.0",
+ "lightningcss-linux-arm-gnueabihf": "1.32.0",
+ "lightningcss-linux-arm64-gnu": "1.32.0",
+ "lightningcss-linux-arm64-musl": "1.32.0",
+ "lightningcss-linux-x64-gnu": "1.32.0",
+ "lightningcss-linux-x64-musl": "1.32.0",
+ "lightningcss-win32-arm64-msvc": "1.32.0",
+ "lightningcss-win32-x64-msvc": "1.32.0"
+ }
+ },
+ "node_modules/lightningcss-android-arm64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
+ "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
+ "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
+ "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
+ "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
+ "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
+ "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
+ "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
+ "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
+ "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
+ "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.32.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
+ "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.9",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz",
+ "integrity": "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/rolldown": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.15.tgz",
+ "integrity": "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@oxc-project/types": "=0.124.0",
+ "@rolldown/pluginutils": "1.0.0-rc.15"
+ },
+ "bin": {
+ "rolldown": "bin/cli.mjs"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "optionalDependencies": {
+ "@rolldown/binding-android-arm64": "1.0.0-rc.15",
+ "@rolldown/binding-darwin-arm64": "1.0.0-rc.15",
+ "@rolldown/binding-darwin-x64": "1.0.0-rc.15",
+ "@rolldown/binding-freebsd-x64": "1.0.0-rc.15",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15",
+ "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15",
+ "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15",
+ "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15",
+ "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15",
+ "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15",
+ "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15",
+ "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15",
+ "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15",
+ "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15",
+ "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15"
+ }
+ },
+ "node_modules/sax": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz",
+ "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=11.0.0"
+ }
+ },
+ "node_modules/sitemap": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-9.0.1.tgz",
+ "integrity": "sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "^24.9.2",
+ "@types/sax": "^1.2.1",
+ "arg": "^5.0.0",
+ "sax": "^1.4.1"
+ },
+ "bin": {
+ "sitemap": "dist/esm/cli.js"
+ },
+ "engines": {
+ "node": ">=20.19.5",
+ "npm": ">=10.8.2"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stream-replace-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/stream-replace-string/-/stream-replace-string-2.0.0.tgz",
+ "integrity": "sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tailwindcss": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz",
+ "integrity": "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tapable": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz",
+ "integrity": "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.16",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
+ "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "dev": true,
+ "license": "0BSD",
+ "optional": true
+ },
+ "node_modules/undici-types": {
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
+ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vite": {
+ "version": "8.0.8",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.8.tgz",
+ "integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "lightningcss": "^1.32.0",
+ "picomatch": "^4.0.4",
+ "postcss": "^8.5.8",
+ "rolldown": "1.0.0-rc.15",
+ "tinyglobby": "^0.2.15"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "@vitejs/devtools": "^0.1.0",
+ "esbuild": "^0.27.0 || ^0.28.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "@vitejs/devtools": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/zod": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
+ "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..a08dbc4
--- /dev/null
+++ b/package.json
@@ -0,0 +1,7 @@
+{
+ "devDependencies": {
+ "@astrojs/sitemap": "^3.7.2",
+ "@tailwindcss/vite": "^4.2.2",
+ "tailwindcss": "^4.2.2"
+ }
+}
diff --git a/tmp/page-source.html b/tmp/page-source.html
new file mode 100644
index 0000000..a878a4d
--- /dev/null
+++ b/tmp/page-source.html
@@ -0,0 +1,410 @@
+
+ Qumo — Brand Smoke Test
+
+
+
Brand Smoke Test
Brand Colors
Midnight #102022
Snow #F3F3F3
Brand Blue #5257E4
Brand Red #F71E3E
Gradient Blue → Red
Archia Weights
Weight
Uppercase
Sentence case
Thin 100
QUMO DATA
Qumo data analytics
Light 300
QUMO DATA
Qumo data analytics
Regular 400
QUMO DATA
Qumo data analytics
Medium 500
QUMO DATA
Qumo data analytics
SemiBold 600
QUMO DATA
Qumo data analytics
Bold 700
QUMO DATA
Qumo data analytics
Dev artifact — will be replaced by the homepage
\ No newline at end of file
diff --git a/website/astro.config.mjs b/website/astro.config.mjs
index e762ba5..4384eae 100644
--- a/website/astro.config.mjs
+++ b/website/astro.config.mjs
@@ -1,5 +1,13 @@
// @ts-check
import { defineConfig } from 'astro/config';
+import sitemap from '@astrojs/sitemap';
+import tailwindcss from '@tailwindcss/vite';
// https://astro.build/config
-export default defineConfig({});
+export default defineConfig({
+ site: 'https://qumo.io',
+ integrations: [sitemap()],
+ vite: {
+ plugins: [tailwindcss()],
+ },
+});
diff --git a/website/src/components/Footer.astro b/website/src/components/Footer.astro
new file mode 100644
index 0000000..c2359cf
--- /dev/null
+++ b/website/src/components/Footer.astro
@@ -0,0 +1,3 @@
+---
+// A later step will implement this component
+---
diff --git a/website/src/components/Nav.astro b/website/src/components/Nav.astro
new file mode 100644
index 0000000..c3abbe8
--- /dev/null
+++ b/website/src/components/Nav.astro
@@ -0,0 +1,3 @@
+---
+// Step 003 will implement this component
+---
diff --git a/website/src/content/en.json b/website/src/content/en.json
new file mode 100644
index 0000000..8b8160a
--- /dev/null
+++ b/website/src/content/en.json
@@ -0,0 +1,8 @@
+{
+ "meta": {
+ "siteName": "Qumo",
+ "defaultTitle": "Qumo — Data & AI for Dutch MKB",
+ "defaultDescription": "Qumo helps Dutch mid-market companies turn data into decisions. From BI dashboards to AI-powered workflows, we make data work for your business.",
+ "defaultOgImage": ""
+ }
+}
diff --git a/website/src/content/i18n.ts b/website/src/content/i18n.ts
new file mode 100644
index 0000000..7639706
--- /dev/null
+++ b/website/src/content/i18n.ts
@@ -0,0 +1,9 @@
+import enContent from './en.json';
+import nlContent from './nl.json';
+
+type Content = typeof enContent;
+
+export function getContent(locale: string): Content {
+ if (locale === 'nl') return nlContent as Content;
+ return enContent;
+}
diff --git a/website/src/content/nl.json b/website/src/content/nl.json
new file mode 100644
index 0000000..4f0b32b
--- /dev/null
+++ b/website/src/content/nl.json
@@ -0,0 +1,8 @@
+{
+ "meta": {
+ "siteName": "Qumo",
+ "defaultTitle": "Qumo — Data & AI voor Nederlands MKB",
+ "defaultDescription": "Qumo helpt Nederlandse middelgrote bedrijven data omzetten in beslissingen. Van BI-dashboards tot AI-gedreven workflows — wij laten data werken voor uw bedrijf.",
+ "defaultOgImage": ""
+ }
+}
diff --git a/website/src/layouts/BaseLayout.astro b/website/src/layouts/BaseLayout.astro
new file mode 100644
index 0000000..89ef403
--- /dev/null
+++ b/website/src/layouts/BaseLayout.astro
@@ -0,0 +1,80 @@
+---
+import '../styles/global.css';
+import Nav from '../components/Nav.astro';
+import Footer from '../components/Footer.astro';
+
+// Import critical font weights with ?url so preload hrefs match Vite-processed URLs
+import archiaRegularUrl from '../assets/fonts/archia/archia-regular-webfont.woff2?url';
+import archiaSemiBoldUrl from '../assets/fonts/archia/archia-semibold-webfont.woff2?url';
+import archiaBoldUrl from '../assets/fonts/archia/archia-bold-webfont.woff2?url';
+
+interface Props {
+ title: string;
+ description: string;
+ locale?: string;
+ canonicalUrl: string;
+ alternateUrl: string;
+ ogImage?: string;
+ jsonLd?: Record;
+}
+
+const {
+ title,
+ description,
+ locale = 'en',
+ canonicalUrl,
+ alternateUrl,
+ ogImage,
+ jsonLd,
+} = Astro.props;
+
+const enUrl = locale === 'en' ? canonicalUrl : alternateUrl;
+const nlUrl = locale === 'nl' ? canonicalUrl : alternateUrl;
+---
+
+
+
+
+
+
+ {title}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {ogImage && }
+
+
+
+
+
+ {ogImage && }
+
+
+ {jsonLd && }
+
+
+
+
+
+
+
+
diff --git a/website/src/pages/index.astro b/website/src/pages/index.astro
index 561196b..a8fa96b 100644
--- a/website/src/pages/index.astro
+++ b/website/src/pages/index.astro
@@ -1,17 +1,93 @@
---
+import BaseLayout from '../layouts/BaseLayout.astro';
+
+const title = 'Qumo — Brand Smoke Test';
+const description = 'Brand token and font weight smoke test — dev artifact.';
+---
----
+
+
+