diff --git a/.github/workflows/accessibility.yml b/.github/workflows/accessibility.yml
index 987625d..7d2941e 100644
--- a/.github/workflows/accessibility.yml
+++ b/.github/workflows/accessibility.yml
@@ -6,7 +6,7 @@ on:
- 'static/**'
- 'content/**'
workflow_dispatch:
-
+permissions: {}
jobs:
axe-core:
runs-on: ubuntu-latest
@@ -16,34 +16,29 @@ jobs:
- name: Install Zola
run: |
- wget -q https://github.com/getzola/zola/releases/download/v0.22.1/zola-v0.22.1-x86_64-unknown-linux-gnu.tar.gz
+ curl -LO https://github.com/getzola/zola/releases/download/v0.22.1/zola-v0.22.1-x86_64-unknown-linux-gnu.tar.gz
tar -xzf zola-v0.22.1-x86_64-unknown-linux-gnu.tar.gz
sudo mv zola /usr/local/bin/
- name: Build site
run: zola build
- - name: Set up Node.js
- uses: actions/setup-node@v4
+ - name: Set up bun
+ uses: oven-sh/setup-bun@v2
with:
- node-version: '20'
-
- - name: Install axe-core CLI
- run: npm install -g @axe-core/cli
+ bun-version: "latest"
- name: Install chrome with browser-driver-manager
- run: npx browser-driver-manager install chrome
+ run: bunx browser-driver-manager@2.0.1 install chrome
- name: Serve site and run axe-core
run: |
- cd public
- python3 -m http.server 8000 &
- sleep 3
-
+ zola serve --port 8000 &
# Test key pages
- axe http://localhost:8000/ --exit
- axe http://localhost:8000/providers/ --exit
- axe http://localhost:8000/providers/scaleway/ --exit
+ bunx @axe-core/cli@4.11.1 http://localhost:8000/ \
+ http://localhost:8000/providers/ \
+ http://localhost:8000/providers/scaleway/ \
+ http://localhost:8000/compare.html?providers=aws,google-cloud,microsoft-azure --exit
- name: Report results
if: always()
diff --git a/.gitignore b/.gitignore
index 1c7e181..32cc47a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,8 +3,13 @@ _bmad/*
# Generated static pages
public
-
# Build artifacts
artifacts/
*.tar.gz
zola
+
+# Nodes artifacts
+node_modules/
+package.json
+bun.lock
+
diff --git a/cloudlandscape-brand.html b/cloudlandscape-brand.html
new file mode 100644
index 0000000..548d4fb
--- /dev/null
+++ b/cloudlandscape-brand.html
@@ -0,0 +1,589 @@
+
+
+
+
+
+ Cloudlandscape — Identité visuelle
+
+
+
+
+
+
+
+
+
+
+
+ Aller au contenu principal
+
+
+
+
+
+
+
+ Brand Identity Kit
+ Cloudlandscape
+
+
+
+
+ Logo
+
+
+
+
+
+
Fond sombre — usage principal
+
+
+
+
+
+
Fond intermédiaire
+
+
+
+
+
+
Fond clair
+
+
+
+
+
+
+
+ Favicon
+
+
+
+
+
+
+
32×32 · dark
+
+
+
+
+
+
+
32×32 · light
+
+
+
+
+
+
+
16×16
+
+
+
+
+
+
+
+ Codes couleurs
+
+
+
+
+
+ Sky Deep
+ #0B1D2E
+ Fond principal
+
+
+
+
+
+
+ Sky Mid
+ #1A3A5C
+ Surfaces secondaires
+
+
+
+
+
+
+ Sky Pale
+ #4A7FA5
+ Éléments UI
+
+
+
+
+
+
+ Aurora
+ #7EC8C8
+ Accent / CTA — ratio 5.1:1
+
+
+
+
+
+
+ Horizon
+ #B8CDD8
+ Textes secondaires
+
+
+
+
+
+
+ Mist
+ #D9E8EF
+ Backgrounds clairs
+
+
+
+
+
+
+ Cloud White
+ #EEF4F9
+ Texte principal — ratio 15.3:1
+
+
+
+
+
+
+ Slate
+ #3D5A6E
+ Bordures / dividers
+
+
+
+
+
+
+
+
+ Typographie
+
+
+
+
Display — Cormorant Garamond 300
+
Horizons sans limites.
+
+
+
+
Heading — Cormorant Garamond 400
+
Paysages numériques, altitude infinie
+
+
+
+
Body — Cormorant Garamond 300
+
Cloudlandscape capture la poésie de l'invisible — ces espaces suspendus entre les données et l'horizon, où chaque altitude raconte une géographie.
+
+
+
+
Mono — DM Mono 400
+
--sky-deep: #0B1D2E; /* altitude max */
+
+
+
+
Caption — DM Mono 300
+
cloudlandscape.io · brand kit v1.0 · 2026
+
+
+
+
+
+
+
+ CSS Design Tokens
+
+
+/* Cloudlandscape — Design Tokens */
+:root {
+ /* Couleurs */
+ --sky-deep: #0B1D2E; /* fond principal */
+ --sky-mid: #1A3A5C; /* surfaces secondaires */
+ --sky-pale: #4A7FA5; /* éléments UI */
+ --aurora: #7EC8C8; /* accent principal */
+ --horizon: #B8CDD8; /* textes secondaires */
+ --mist: #D9E8EF; /* fonds clairs */
+ --cloud-white: #EEF4F9; /* texte principal */
+ --slate: #3D5A6E; /* bordures */
+
+ /* Typographie */
+ --font-display: 'Cormorant Garamond', Georgia, serif;
+ --font-mono: 'DM Mono', 'Courier New', monospace;
+
+ /* Espacements */
+ --space-xs: 0.5rem;
+ --space-sm: 1rem;
+ --space-md: 2rem;
+ --space-lg: 4rem;
+}
+
+
+
+
+
+ Accessibilité RGAA
+
+
+
+
Contrastes
+
Cloud White / Sky Deep
15.3:1 ✓
+
Aurora / Sky Deep
5.1:1 ✓
+
Critère 3.2 RGAA — min 4.5:1
+
+
+
+
Navigation clavier
+
Focus visible sur tous les éléments interactifs
+
Critère 12.1 RGAA
+
+
+
+
Textes alternatifs
+
Attribut aria-label sur chaque SVG. Éléments décoratifs en aria-hidden
+
Critère 1.1 RGAA
+
+
+
+
Animations
+
Animations désactivées via prefers-reduced-motion
+
Critère 13.8 RGAA
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mise.toml b/mise.toml
index d8ae355..92069da 100644
--- a/mise.toml
+++ b/mise.toml
@@ -1,8 +1,50 @@
[tools]
+bun = "latest"
zola = "latest"
+[vars]
+port = "1111"
+
[tasks]
check = "zola check"
build = "zola build"
validate = "uv run docs/validate_providers.py"
+[tasks.serve]
+depends = ["build"]
+run = """
+#!/usr/bin/env bash
+if nc -z localhost {{vars.port}}; then
+ echo "zola is already serving"
+else
+ zola serve --port {{vars.port}} &
+fi
+"""
+
+[tasks.stop]
+run = """
+#!/usr/bin/env bash
+if nc -z localhost {{vars.port}}; then
+ killall zola
+else
+ echo "zola is not running"
+fi
+"""
+
+[tasks.a11y]
+description = "Accessibility tests"
+depends = ["serve"]
+run = """
+bunx browser-driver-manager@2.0.1 install chrome
+bunx @axe-core/cli@4.11.1 http://localhost:{{vars.port}}/ \
+ http://localhost:{{vars.port}}/providers/ \
+ http://localhost:{{vars.port}}/providers/scaleway/ \
+ http://localhost:{{vars.port}}/compare.html?providers=aws,google-cloud,microsoft-azure --exit
+EXIT_CODE=$?
+exit $EXIT_CODE
+"""
+
+[tasks.test]
+description = "Run full tests"
+depends = ["validate", "check", "a11y"]
+
diff --git a/static/compare.html b/static/compare.html
index 9c11adc..fdfbd44 100644
--- a/static/compare.html
+++ b/static/compare.html
@@ -18,59 +18,63 @@
.comparison-table {
width: 100%;
border-collapse: collapse;
- background: white;
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+ background: var(--sky-mid);
+ box-shadow: 0 2px 4px rgba(0,0,0,0.3);
}
.comparison-table th,
.comparison-table td {
padding: 1rem;
- border: 1px solid #ddd;
+ border: 1px solid var(--slate);
text-align: left;
+ color: var(--cloud-white);
}
.comparison-table thead th {
- background: #2c3e50;
- color: white;
+ background: var(--sky-deep);
+ color: var(--cloud-white);
font-weight: 600;
position: sticky;
top: 0;
}
.comparison-table tbody th {
- background: #ecf0f1;
- font-weight: 600;
+ background: rgba(255,255,255,0.04);
+ color: var(--cloud-white);
+ font-weight: 400;
}
.comparison-table td {
text-align: center;
+ color: var(--cloud-white);
}
.has-feature {
- color: #27ae60;
+ color: #4ade80;
font-size: 1.5rem;
}
.no-feature {
- color: #e74c3c;
+ color: #f87171;
font-size: 1.5rem;
}
.cert-yes {
- background: #d5f4e6;
+ background: rgba(74,222,128,0.15);
}
.cert-no {
- background: #fadbd8;
+ background: rgba(248,113,113,0.15);
}
.provider-link {
- color: #3498db;
+ color: var(--aurora);
text-decoration: none;
- font-weight: 600;
+ font-weight: 400;
}
.provider-link:hover {
+ color: var(--cloud-white);
text-decoration: underline;
}
@@ -86,7 +90,7 @@
}
.empty-comparison h2 {
- color: #666;
+ color: var(--horizon);
}
@@ -208,7 +212,7 @@ No providers selected
html += '';
// Service rows
- html += '| Services |
';
+ html += '| Services |
';
services.forEach(service => {
html += `| ${service} | `;
providers.forEach(p => {
@@ -219,7 +223,7 @@ No providers selected
});
// Certification rows
- html += '
|---|
| Certifications |
';
+ html += '| Certifications |
';
certifications.forEach(cert => {
html += `| ${cert} | `;
providers.forEach(p => {
@@ -231,7 +235,7 @@ No providers selected
});
// Geographic coverage row
- html += '
|---|
| Geographic Coverage |
';
+ html += '| Geographic Coverage |
';
html += '| Datacenters | ';
providers.forEach(p => {
const locations = p.datacenters && p.datacenters.length > 0
diff --git a/static/style.css b/static/style.css
index 5c74bca..db727f1 100644
--- a/static/style.css
+++ b/static/style.css
@@ -1,3 +1,24 @@
+/* ─── DESIGN TOKENS ───────────────────────────────────────── */
+:root {
+ --sky-deep: #0B1D2E;
+ --sky-mid: #1A3A5C;
+ --sky-pale: #4A7FA5;
+ --cloud-white: #EEF4F9;
+ --horizon: #B8CDD8;
+ --aurora: #7EC8C8;
+ --mist: #D9E8EF;
+ --slate: #3D5A6E;
+ --contrast: #061420;
+
+ --font-display: 'Cormorant Garamond', Georgia, serif;
+ --font-mono: 'DM Mono', 'Courier New', monospace;
+
+ --space-xs: 0.5rem;
+ --space-sm: 1rem;
+ --space-md: 2rem;
+ --space-lg: 4rem;
+}
+
/* CSS Reset and Base Styles */
* {
margin: 0;
@@ -7,9 +28,11 @@
/* Prevent layout shift - reserve space for web fonts */
body {
- font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
- line-height: 1.6;
- color: #1a1a1a;
+ font-family: var(--font-display);
+ font-weight: 300;
+ line-height: 1.7;
+ color: var(--cloud-white);
+ background: var(--sky-deep);
max-width: 1200px;
margin: 0 auto;
padding: 1rem;
@@ -24,8 +47,9 @@ img {
/* Navigation */
nav {
- background: #2c3e50;
- padding: 1rem;
+ background: var(--sky-mid);
+ border-bottom: 1px solid var(--slate);
+ padding: 0.75rem 1.5rem;
margin: -1rem -1rem 2rem -1rem;
display: flex;
align-items: center;
@@ -33,27 +57,47 @@ nav {
gap: 0.5rem;
}
+.nav-logo {
+ display: flex;
+ align-items: center;
+ margin-right: 1rem;
+ text-decoration: none;
+}
+
nav a {
- color: white;
+ color: var(--horizon);
text-decoration: none;
margin-right: 1.5rem;
- font-weight: 500;
+ font-family: var(--font-mono);
+ font-size: 0.8rem;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ transition: color 0.2s;
}
nav a:hover {
- text-decoration: underline;
+ color: var(--aurora);
+ text-decoration: none;
}
/* Typography */
h1 {
- font-size: 2rem;
+ font-family: var(--font-display);
+ font-size: clamp(1.8rem, 4vw, 3rem);
+ font-weight: 300;
+ letter-spacing: 0.04em;
margin-bottom: 1rem;
- color: #2c3e50;
+ color: var(--cloud-white);
}
h2 {
- font-size: 1.5rem;
- margin-bottom: 0.5rem;
+ font-family: var(--font-mono);
+ font-size: 0.75rem;
+ font-weight: 400;
+ letter-spacing: 0.25em;
+ text-transform: uppercase;
+ color: var(--horizon);
+ margin-bottom: var(--space-sm);
}
/* Provider Grid */
@@ -65,105 +109,175 @@ h2 {
}
.provider-card {
- border: 1px solid #ddd;
- border-radius: 8px;
+ border: 1px solid var(--slate);
+ border-radius: 4px;
padding: 1.5rem;
- background: white;
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
- transition: transform 0.2s, box-shadow 0.2s;
+ background: var(--sky-mid);
+ transition: transform 0.25s ease, box-shadow 0.25s ease;
+}
+
+@media (prefers-reduced-motion: no-preference) {
+ .provider-card:hover {
+ transform: translateY(-3px);
+ box-shadow: 0 6px 20px rgba(0,0,0,0.3);
+ }
}
-.provider-card:hover {
- transform: translateY(-2px);
- box-shadow: 0 4px 8px rgba(0,0,0,0.15);
+.provider-card h2 {
+ font-family: var(--font-display);
+ font-size: 1.25rem;
+ font-weight: 400;
+ letter-spacing: 0.03em;
+ text-transform: none;
+ color: var(--cloud-white);
+ margin-bottom: 0.5rem;
}
.provider-card h2 a {
- color: #2c3e50;
+ color: var(--cloud-white);
text-decoration: none;
}
.provider-card h2 a:hover {
- color: #3498db;
+ color: var(--aurora);
}
.provider-description {
margin: 0.5rem 0 1rem 0;
- color: #4a4a4a;
+ color: var(--horizon);
+ font-size: 0.95rem;
}
.provider-meta {
- font-size: 0.9rem;
+ font-size: 0.88rem;
+ color: var(--horizon);
}
.provider-meta p {
margin: 0.5rem 0;
}
+.provider-meta strong {
+ color: var(--cloud-white);
+ font-weight: 400;
+}
+
.provider-card .provider-actions {
margin-top: 1rem;
padding-top: 1rem;
- border-top: 1px solid #ecf0f1;
+ border-top: 1px solid var(--slate);
}
.btn-compare-add {
width: 100%;
padding: 0.6rem 1rem;
- background: #3498db;
- color: white;
- border: none;
+ background: transparent;
+ color: var(--aurora);
+ border: 1px solid var(--aurora);
border-radius: 4px;
cursor: pointer;
- font-size: 0.9rem;
- font-weight: 600;
- transition: background 0.2s;
+ font-family: var(--font-mono);
+ font-size: 0.75rem;
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
+ font-weight: 400;
+ transition: background 0.2s, color 0.2s;
}
.btn-compare-add:hover {
- background: #2980b9;
+ background: var(--aurora);
+ color: var(--contrast);
}
.btn-compare-add.in-comparison {
- background: #27ae60;
+ background: var(--aurora);
+ color: var(--contrast);
+ border-color: var(--aurora);
}
.btn-compare-add.in-comparison:hover {
- background: #229954;
+ background: var(--sky-pale);
+ border-color: var(--sky-pale);
+ color: var(--cloud-white);
}
.btn-compare-add:disabled {
- background: #95a5a6;
+ background: transparent;
+ color: var(--slate);
+ border-color: var(--slate);
cursor: not-allowed;
}
/* Badges */
.badge {
display: inline-block;
- background: #ecf0f1;
- padding: 0.25rem 0.5rem;
+ background: rgba(255,255,255,0.06);
+ border: 1px solid var(--slate);
+ color: var(--horizon);
+ padding: 0.2rem 0.5rem;
border-radius: 4px;
- font-size: 0.85rem;
+ font-family: var(--font-mono);
+ font-size: 0.72rem;
margin-right: 0.25rem;
+ letter-spacing: 0.05em;
}
.cert-badge {
- background: #27ae60;
- color: white;
+ background: rgba(126,200,200,0.12);
+ border-color: var(--aurora);
+ color: var(--aurora);
}
/* Filters Container */
.filters-container {
- background: #f8f9fa;
+ background: rgba(255,255,255,0.04);
+ border: 1px solid var(--slate);
padding: 1.5rem;
- border-radius: 8px;
+ border-radius: 4px;
margin: 2rem 0;
}
.filters-container h2 {
- font-size: 1.3rem;
+ font-size: 0.7rem;
margin-bottom: 1rem;
}
+.search-container {
+ margin-bottom: 1.5rem;
+}
+
+.search-container label {
+ display: block;
+ font-family: var(--font-mono);
+ font-size: 0.7rem;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--horizon);
+ margin-bottom: 0.5rem;
+}
+
+.search-input {
+ width: 100%;
+ padding: 0.6rem 1rem;
+ background: var(--sky-deep);
+ border: 1px solid var(--slate);
+ border-radius: 4px;
+ color: var(--cloud-white);
+ font-family: var(--font-display);
+ font-size: 1rem;
+ font-weight: 300;
+ outline: none;
+ transition: border-color 0.2s;
+}
+
+.search-input:focus {
+ border-color: var(--aurora);
+}
+
+.search-input::placeholder {
+ color: var(--slate);
+}
+
.filter-group {
margin-bottom: 1.5rem;
border: none;
@@ -171,54 +285,66 @@ h2 {
}
.filter-group legend {
- font-size: 1.1rem;
- font-weight: 600;
+ font-family: var(--font-mono);
+ font-size: 0.68rem;
+ font-weight: 400;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
margin-bottom: 0.5rem;
- color: #2c3e50;
+ color: var(--horizon);
padding: 0;
}
- color: #2c3e50;
-}
.filter-group label {
display: block;
margin: 0.5rem 0;
cursor: pointer;
+ color: var(--cloud-white);
+ font-size: 0.95rem;
}
.filter-group label input[type="checkbox"] {
margin-right: 0.5rem;
+ accent-color: var(--aurora);
}
.filter-checkbox:checked + label,
.filter-group label:has(input:checked) {
- font-weight: 600;
+ font-weight: 400;
+ color: var(--aurora);
}
.filter-reset {
- background: #e74c3c;
- color: white;
- border: none;
- padding: 0.75rem 1.5rem;
+ background: transparent;
+ color: var(--aurora);
+ border: 1px solid var(--aurora);
+ padding: 0.6rem 1.5rem;
border-radius: 4px;
cursor: pointer;
- font-size: 1rem;
- font-weight: 600;
+ font-family: var(--font-mono);
+ font-size: 0.72rem;
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
+ transition: background 0.2s, color 0.2s;
}
.filter-reset:hover {
- background: #c0392b;
+ background: var(--aurora);
+ color: var(--contrast);
}
.filter-reset:focus {
- outline: 2px solid #3498db;
+ outline: 3px solid var(--aurora);
outline-offset: 2px;
}
/* Result Count */
.result-count {
- font-size: 1.1rem;
- color: #4a4a4a;
+ font-family: var(--font-mono);
+ font-size: 0.75rem;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ color: var(--horizon);
margin: 1rem 0;
}
@@ -240,15 +366,23 @@ h2 {
.filters-toggle {
display: block;
width: 100%;
- padding: 1rem;
- background: #3498db;
- color: white;
- border: none;
- border-radius: 6px;
- font-weight: 600;
- font-size: 1rem;
+ padding: 0.75rem 1rem;
+ background: transparent;
+ color: var(--aurora);
+ border: 1px solid var(--aurora);
+ border-radius: 4px;
+ font-family: var(--font-mono);
+ font-size: 0.72rem;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
cursor: pointer;
margin-bottom: 1rem;
+ transition: background 0.2s, color 0.2s;
+ }
+
+ .filters-toggle:hover {
+ background: var(--aurora);
+ color: var(--contrast);
}
.filters-content {
@@ -303,12 +437,13 @@ h2 {
.provider-header {
margin-bottom: 2rem;
padding-bottom: 1.5rem;
- border-bottom: 2px solid #ecf0f1;
+ border-bottom: 1px solid var(--slate);
}
.provider-tagline {
font-size: 1.2rem;
- color: #4a4a4a;
+ font-weight: 300;
+ color: var(--horizon);
margin-top: 0.5rem;
}
@@ -318,8 +453,9 @@ h2 {
gap: 1rem;
margin: 2rem 0;
padding: 1.5rem;
- background: #f8f9fa;
- border-radius: 8px;
+ background: rgba(255,255,255,0.04);
+ border: 1px solid var(--slate);
+ border-radius: 4px;
}
.meta-item {
@@ -328,16 +464,28 @@ h2 {
}
.meta-item strong {
- color: #2c3e50;
+ font-family: var(--font-mono);
+ font-size: 0.68rem;
+ letter-spacing: 0.15em;
+ text-transform: uppercase;
+ color: var(--horizon);
+ font-weight: 400;
margin-bottom: 0.25rem;
}
+.meta-item span {
+ color: var(--cloud-white);
+ font-size: 1rem;
+}
+
.external-link {
- color: #3498db;
+ color: var(--aurora);
text-decoration: none;
+ text-underline-offset: 3px;
}
.external-link:hover {
+ color: var(--cloud-white);
text-decoration: underline;
}
@@ -351,19 +499,22 @@ h2 {
}
.provider-detail h2 {
- color: #2c3e50;
- margin-bottom: 0.5rem;
+ color: var(--horizon);
+ margin-bottom: 0.75rem;
}
.section-intro {
- color: #4a4a4a;
- font-size: 0.95rem;
+ color: var(--horizon);
+ font-size: 0.9rem;
margin-bottom: 1.5rem;
+ font-family: var(--font-mono);
+ letter-spacing: 0.05em;
}
.provider-description .content {
- line-height: 1.8;
+ line-height: 1.9;
font-size: 1.05rem;
+ color: var(--cloud-white);
}
/* Services Grid */
@@ -374,16 +525,20 @@ h2 {
}
.service-card {
- background: #3498db;
- color: white;
- padding: 1rem;
- border-radius: 6px;
+ background: rgba(74,127,165,0.15);
+ border: 1px solid var(--sky-pale);
+ color: var(--cloud-white);
+ padding: 0.75rem 1rem;
+ border-radius: 4px;
text-align: center;
- font-weight: 600;
}
.service-name {
display: block;
+ font-family: var(--font-mono);
+ font-size: 0.75rem;
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
}
/* Certifications */
@@ -397,15 +552,15 @@ h2 {
display: flex;
align-items: center;
gap: 1rem;
- padding: 1.5rem;
- background: #d5f4e6;
- border-left: 4px solid #27ae60;
- border-radius: 6px;
+ padding: 1.25rem 1.5rem;
+ background: rgba(126,200,200,0.06);
+ border-left: 3px solid var(--aurora);
+ border-radius: 4px;
}
.cert-icon {
- font-size: 2rem;
- color: #27ae60;
+ font-size: 1.5rem;
+ color: var(--aurora);
}
.cert-info {
@@ -415,17 +570,22 @@ h2 {
}
.cert-name {
- font-size: 1.1rem;
- color: #2c3e50;
+ font-family: var(--font-mono);
+ font-size: 0.85rem;
+ letter-spacing: 0.1em;
+ color: var(--aurora);
}
.cert-link {
- color: #27ae60;
+ color: var(--horizon);
text-decoration: none;
- font-size: 0.9rem;
+ font-family: var(--font-mono);
+ font-size: 0.72rem;
+ letter-spacing: 0.05em;
}
.cert-link:hover {
+ color: var(--aurora);
text-decoration: underline;
}
@@ -438,16 +598,17 @@ h2 {
.datacenter-item {
padding: 1rem;
- background: white;
- border: 1px solid #ddd;
- border-radius: 6px;
+ background: rgba(255,255,255,0.04);
+ border: 1px solid var(--slate);
+ border-radius: 4px;
display: flex;
align-items: center;
gap: 0.5rem;
+ color: var(--cloud-white);
}
.location-icon {
- font-size: 1.5rem;
+ font-size: 1.25rem;
}
/* Provider Actions */
@@ -456,36 +617,44 @@ h2 {
gap: 1rem;
margin: 3rem 0;
padding-top: 2rem;
- border-top: 2px solid #ecf0f1;
+ border-top: 1px solid var(--slate);
}
.btn {
- padding: 0.75rem 1.5rem;
- border-radius: 6px;
+ padding: 0.7rem 1.5rem;
+ border-radius: 4px;
text-decoration: none;
- font-weight: 600;
- border: none;
+ font-family: var(--font-mono);
+ font-size: 0.75rem;
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
+ font-weight: 400;
+ border: 1px solid transparent;
cursor: pointer;
- font-size: 1rem;
- transition: background 0.2s;
+ transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.btn-primary {
- background: #1255b5;
- color: white;
+ background: var(--aurora);
+ color: var(--contrast);
+ border-color: var(--aurora);
}
.btn-primary:hover {
- background: #104989;
+ background: var(--sky-pale);
+ border-color: var(--sky-pale);
+ color: var(--cloud-white);
}
.btn-secondary {
- background: #95a5a6;
- color: white;
+ background: transparent;
+ color: var(--horizon);
+ border-color: var(--slate);
}
.btn-secondary:hover {
- background: #7f8c8d;
+ border-color: var(--horizon);
+ color: var(--cloud-white);
}
@media (max-width: 768px) {
@@ -511,8 +680,8 @@ h2 {
position: sticky;
left: 0;
z-index: 10;
- background: white;
- box-shadow: 2px 0 4px rgba(0,0,0,0.1);
+ background: var(--sky-mid);
+ box-shadow: 2px 0 4px rgba(0,0,0,0.3);
}
.comparison-table thead th {
@@ -532,9 +701,9 @@ h2 {
bottom: 0;
left: 0;
right: 0;
- background: white;
- border-top: 3px solid #3498db;
- box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
+ background: var(--sky-mid);
+ border-top: 2px solid var(--aurora);
+ box-shadow: 0 -4px 20px rgba(0,0,0,0.4);
padding: 1rem;
z-index: 1000;
display: none;
@@ -556,25 +725,32 @@ h2 {
}
.comparison-counter {
- background: #3498db;
- color: white;
+ background: var(--aurora);
+ color: var(--contrast);
padding: 0.25rem 0.6rem;
border-radius: 50%;
- font-size: 0.9rem;
+ font-family: var(--font-mono);
+ font-size: 0.8rem;
font-weight: bold;
}
.btn-clear-comparison {
background: transparent;
- border: 1px solid #ddd;
+ border: 1px solid var(--slate);
+ color: var(--horizon);
padding: 0.5rem 1rem;
border-radius: 4px;
cursor: pointer;
- font-size: 0.9rem;
+ font-family: var(--font-mono);
+ font-size: 0.72rem;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ transition: border-color 0.2s, color 0.2s;
}
.btn-clear-comparison:hover {
- background: #ecf0f1;
+ border-color: var(--horizon);
+ color: var(--cloud-white);
}
.comparison-list {
@@ -585,54 +761,67 @@ h2 {
}
.comparison-item {
- background: #ecf0f1;
- padding: 0.5rem 1rem;
+ background: rgba(255,255,255,0.06);
+ border: 1px solid var(--slate);
+ color: var(--cloud-white);
+ padding: 0.4rem 0.75rem;
border-radius: 4px;
display: flex;
align-items: center;
gap: 0.5rem;
+ font-family: var(--font-mono);
+ font-size: 0.75rem;
}
.remove-comparison {
- background: #e74c3c;
- color: white;
+ background: transparent;
+ color: var(--aurora);
border: none;
- width: 20px;
- height: 20px;
+ width: 18px;
+ height: 18px;
border-radius: 50%;
cursor: pointer;
- font-size: 1.2rem;
+ font-size: 1rem;
line-height: 1;
display: flex;
align-items: center;
justify-content: center;
+ transition: color 0.2s;
}
.remove-comparison:hover {
- background: #c0392b;
+ color: var(--cloud-white);
}
.btn-compare {
- background: #27ae60;
- color: white;
- padding: 0.75rem 1.5rem;
- border: none;
+ background: var(--aurora);
+ color: var(--contrast);
+ padding: 0.7rem 1.5rem;
+ border: 1px solid var(--aurora);
border-radius: 4px;
- font-weight: bold;
+ font-family: var(--font-mono);
+ font-size: 0.72rem;
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
+ font-weight: 400;
cursor: pointer;
white-space: nowrap;
+ transition: background 0.2s, color 0.2s;
}
.btn-compare:hover {
- background: #229954;
+ background: var(--sky-pale);
+ border-color: var(--sky-pale);
+ color: var(--cloud-white);
}
.in-comparison {
- background: #27ae60 !important;
+ background: var(--aurora) !important;
+ color: var(--contrast) !important;
}
.in-comparison:hover {
- background: #229954 !important;
+ background: var(--sky-pale) !important;
}
@media (max-width: 768px) {
@@ -652,39 +841,38 @@ h2 {
.lang-btn {
background: transparent;
- border: 2px solid rgba(255, 255, 255, 0.3);
- color: white;
- padding: 0.4rem 0.8rem;
+ border: 1px solid rgba(255,255,255,0.2);
+ color: var(--horizon);
+ padding: 0.35rem 0.75rem;
border-radius: 4px;
cursor: pointer;
- font-weight: 600;
- font-size: 0.9rem;
+ font-family: var(--font-mono);
+ font-size: 0.72rem;
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
transition: all 0.2s;
}
.lang-btn:hover {
- background: rgba(255, 255, 255, 0.1);
- border-color: rgba(255, 255, 255, 0.5);
+ border-color: var(--aurora);
+ color: var(--aurora);
}
.lang-btn:focus {
- outline: 2px solid white;
+ outline: 2px solid var(--aurora);
outline-offset: 2px;
}
.lang-btn.active {
- background: white;
- color: #2c3e50;
- border-color: white;
+ background: var(--aurora);
+ color: var(--contrast);
+ border-color: var(--aurora);
}
.lang-separator {
- color: rgba(255, 255, 255, 0.5);
-}
-
-nav {
- display: flex;
- align-items: center;
+ color: var(--slate);
+ font-family: var(--font-mono);
+ font-size: 0.7rem;
}
/* Skip Navigation Link */
@@ -692,11 +880,14 @@ nav {
position: absolute;
top: -40px;
left: 0;
- background: #2c3e50;
- color: white;
+ background: var(--aurora);
+ color: var(--contrast);
padding: 0.75rem 1.5rem;
text-decoration: none;
- font-weight: 600;
+ font-family: var(--font-mono);
+ font-size: 0.75rem;
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
z-index: 9999;
transition: top 0.2s;
}
@@ -706,18 +897,18 @@ nav {
}
/* Focus Indicators */
-a:focus,
-button:focus,
-input:focus,
-select:focus,
-textarea:focus {
- outline: 2px solid #3498db;
- outline-offset: 2px;
+:focus-visible {
+ outline: 3px solid var(--aurora);
+ outline-offset: 4px;
}
-.filter-checkbox:focus {
- outline: 2px solid #3498db;
- outline-offset: 2px;
+a {
+ color: var(--aurora);
+ text-underline-offset: 3px;
+}
+
+a:hover {
+ color: var(--cloud-white);
}
/* Home Page Styles */
@@ -728,19 +919,21 @@ textarea:focus {
}
.home-content .tagline {
- font-size: 1.2rem;
- color: #666;
+ font-size: 1.15rem;
+ color: var(--horizon);
margin-bottom: 2rem;
+ font-weight: 300;
}
.home-content .content {
text-align: left;
margin: 3rem auto;
+ color: var(--cloud-white);
}
.home-content h2 {
- color: #2c3e50;
margin-top: 2rem;
+ color: var(--horizon);
}
.home-content ul {
@@ -752,28 +945,38 @@ textarea:focus {
margin: 1rem 0;
padding-left: 1.5rem;
position: relative;
+ color: var(--cloud-white);
+ font-size: 1rem;
}
.home-content ul li::before {
content: "✓";
position: absolute;
left: 0;
- color: #27ae60;
- font-weight: bold;
+ color: var(--aurora);
+ font-family: var(--font-mono);
}
.home-content .btn {
display: inline-block;
margin-top: 2rem;
- padding: 1rem 2rem;
- background: #3498db;
- color: white;
+ padding: 0.85rem 2rem;
+ background: var(--aurora);
+ color: var(--contrast);
text-decoration: none;
- border-radius: 6px;
- font-weight: 600;
- transition: background 0.2s;
+ border-radius: 4px;
+ font-family: var(--font-mono);
+ font-size: 0.75rem;
+ letter-spacing: 0.12em;
+ text-transform: uppercase;
+ font-weight: 400;
+ border: 1px solid var(--aurora);
+ transition: background 0.2s, color 0.2s;
}
.home-content .btn:hover {
- background: #2980b9;
+ background: var(--sky-pale);
+ border-color: var(--sky-pale);
+ color: var(--cloud-white);
}
+
diff --git a/templates/base.html b/templates/base.html
index bf72883..3c7e42d 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -25,13 +25,29 @@
{% endif %}
+
+
+
+
+
+
Skip to main content
diff --git a/templates/page.html b/templates/page.html
index 5b6d7f3..2d701c6 100644
--- a/templates/page.html
+++ b/templates/page.html
@@ -59,11 +59,11 @@ Services Offered
Services are mapped to unified taxonomy categories for easy comparison across providers.
{% for service in page.taxonomies.services %}
-
+
-
{{ service | replace(from="-", to=" ") | title }}
-
+
{% endfor %}
-
+
{% endif %}
diff --git a/templates/section.html b/templates/section.html
index 12ef767..ec76194 100644
--- a/templates/section.html
+++ b/templates/section.html
@@ -84,9 +84,9 @@ {{ trans(key="filters_heading", lang=section.lang) }}
{% if section.pages %}
-
+
{% for page in section.pages %}
-
+ -
{{ page.description }}
@@ -130,9 +130,9 @@
{{ trans(key="add_to_comparison", lang=section.lang) }}
-
+
{% endfor %}
-
+
{% else %}
No providers found.
{% endif %}
|---|