Files
landing/docs/superpowers/specs/2026-08-02-ombrora-hub-landing-design.md
anthony 0496e1390b Add design spec for Ombrora hub landing page
Astro static site, FR/EN path-based i18n, light/dark theming, hub
linking to CVE Watch and Convert services.
2026-08-02 14:27:50 +02:00

132 lines
6.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Ombrora Hub Landing Page — Design
## Purpose
A landing page at `www.ombrora.com` acting as a hub linking to Ombrora's existing services:
- CVE Watch — a CVE-tracking blog, published in French (`cve-fr.ombrora.com`) and English (`cve-en.ombrora.com`) as two locale-specific deployments of the same underlying service.
- Convert (`convert.ombrora.com`) — a file conversion tool (documents, audio, images, video, archives).
More services will be added to the hub over time; the design must make that cheap.
## Requirements
- Built with Astro, static output only (no SSR/SSR adapter) — required for SEO and for hosting on static shared hosting.
- Multilingual: French and English, via path-based routing (`/en/`, `/fr/`), symmetric (no unprefixed default locale route).
- Deployed to o2switch shared hosting: plain HTML/CSS/JS output uploaded to the host, no server-side runtime, `.htaccess` available for Apache-level rules.
- SEO-optimized: prerendered HTML, meta tags, hreflang, sitemap, robots.txt.
- Supports light and dark mode.
- No existing brand assets — visual direction is proposed as part of this design.
- Scope is minimal: hero + service cards + footer. No About/Contact/legal pages, no analytics.
## Tech stack & project structure
- Astro (latest stable), `output: 'static'` (Astro's default — no adapter needed).
- No UI framework — plain Astro components and CSS are sufficient for this scope.
- npm as package manager.
```
src/
components/ Header.astro, Footer.astro, ServiceCard.astro, LanguageSwitcher.astro, ThemeToggle.astro
i18n/ en.ts, fr.ts (UI strings), services.ts (service list, per-locale copy)
layouts/ BaseLayout.astro (head/meta/hreflang/OG tags, theme init script)
pages/
en/index.astro
fr/index.astro
public/
.htaccess (root language redirect)
robots.txt
astro.config.mjs (i18n config, sitemap integration)
```
## Routing & i18n
`astro.config.mjs`:
```js
i18n: {
locales: ['en', 'fr'],
defaultLocale: 'en',
routing: { prefixDefaultLocale: true }
}
```
This produces symmetric `/en/` and `/fr/` routes (no bare unprefixed locale route). Astro's `astro:i18n` helpers (e.g. `getRelativeLocaleUrl`) generate cross-locale links for the language switcher and hreflang tags.
`public/.htaccess` handles the bare `www.ombrora.com/` root with a real server-side redirect based on the `Accept-Language` header:
```apache
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/$
RewriteCond %{HTTP:Accept-Language} fr [NC]
RewriteRule ^$ /fr/ [R=302,L]
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^$ /en/ [R=302,L]
```
French-preferring browsers land on `/fr/`; everything else defaults to `/en/`. No JavaScript redirect needed.
## Content model
`src/i18n/services.ts` is the single source of truth for the service cards. `url` may be a plain string (same URL regardless of locale) or a `{ en, fr }` object (locale-specific URL) — `ServiceCard.astro` resolves whichever shape is present against the current locale. Adding a future service, whether single-domain or per-locale-domain, means adding one entry here.
```ts
export const services = [
{
id: 'cve',
url: { en: 'https://cve-en.ombrora.com', fr: 'https://cve-fr.ombrora.com' },
name: { en: 'CVE Watch', fr: 'Veille CVE' },
description: { en: '...', fr: '...' },
},
{
id: 'convert',
url: 'https://convert.ombrora.com',
name: { en: 'Convert', fr: 'Convert' },
description: { en: '...', fr: '...' },
},
]
```
Note: CVE Watch is one logical service with two locale-specific deployments (matching the existing `cve-fr`/`cve-en` split), rendered as a single card whose link target depends on the hub's current locale — not two separate cards.
`src/i18n/en.ts` / `fr.ts` hold flat key-value UI strings (hero title/subtitle, nav labels, footer text), looked up directly in templates (e.g. `t.hero.title`) — no i18n library needed for this scope.
## Pages & components
- **BaseLayout.astro**: `<html lang>`, meta description, canonical URL, hreflang alternates (en, fr, x-default → en), Open Graph/Twitter card tags, favicon, global CSS, and the pre-paint theme-init script (see Theming).
- **Header.astro**: Ombrora wordmark, LanguageSwitcher (links to the equivalent page in the other locale, not just the other locale's root), ThemeToggle.
- **Hero**: short tagline introducing Ombrora as a hub for security and utility tools.
- **ServiceCard.astro × 2**: name, one-line description, a tag (e.g. "CVE Blog", "File Converter"), outbound link resolved per current locale.
- **Footer.astro**: copyright, optional contact mailto. No legal/About pages in this scope.
## Visual direction
Dark, technical aesthetic fitting a security/CVE tracker and dev utility tool: neutral dark/light backgrounds, one accent color (cool cyan or violet) for links and highlights, a clean sans-serif for body text with a monospace accent for tags/labels. No decorative gimmicks.
## Theming (light & dark mode)
Implemented via CSS custom properties (`--bg`, `--fg`, `--accent`, etc.) on `:root`, with `[data-theme="dark"]` / `[data-theme="light"]` overrides.
- **Default**: follows system preference (`prefers-color-scheme`), applied by an inline `<script>` in `BaseLayout` that runs before first paint (avoids flash of wrong theme) and sets `data-theme` on `<html>`.
- **Manual override**: a toggle button in the Header flips `data-theme` and persists the choice to `localStorage`; on later visits the stored preference takes precedence over system preference.
- No extra dependency — CSS variables plus a small vanilla script.
## SEO
- `@astrojs/sitemap` integration generating a sitemap covering both locale routes.
- Per-page `<title>`, meta description, canonical URL, and hreflang alternates in `BaseLayout`.
- `robots.txt` allowing all crawlers, referencing the sitemap.
- Semantic HTML (`<main>`, `<section>`, correct heading hierarchy), fully prerendered — no client-side rendering of critical content.
## Build & deploy
- `astro build` outputs static HTML/CSS/JS to `dist/`.
- Deployment to o2switch is a manual upload of `dist/` (including `.htaccess`, which Astro copies through from `public/` unchanged). No CI/CD pipeline in this scope.
## Out of scope
- About/Contact/legal pages.
- Analytics/tracking.
- Any service beyond CVE Watch and Convert (future services are added by extending `services.ts`, not by redesigning the page).
- CI/CD automation for deployment.