diff --git a/assets/i18n/de.json b/assets/i18n/de.json
index 4f985ff..1c895fd 100644
--- a/assets/i18n/de.json
+++ b/assets/i18n/de.json
@@ -224,7 +224,13 @@
"documentation": "Dokumentation",
"api_reference": "API-Referenz",
"support": "Support",
- "copyright": "2026 CERTifAI. Alle Rechte vorbehalten."
+ "copyright": "2026 CERTifAI. Alle Rechte vorbehalten.",
+ "pill_gdpr": "DSGVO-Nativ",
+ "pill_self_hosted": "Selbst gehostet",
+ "pill_eu": "EU-Souveraen",
+ "preview_models": "Aktive Modelle",
+ "preview_tokens": "Tokens / Monat",
+ "preview_spend": "Gesamtausgaben"
},
"article": {
"read_original": "Originalartikel lesen",
diff --git a/assets/i18n/en.json b/assets/i18n/en.json
index 038ca71..7334837 100644
--- a/assets/i18n/en.json
+++ b/assets/i18n/en.json
@@ -224,7 +224,13 @@
"documentation": "Documentation",
"api_reference": "API Reference",
"support": "Support",
- "copyright": "2026 CERTifAI. All rights reserved."
+ "copyright": "2026 CERTifAI. All rights reserved.",
+ "pill_gdpr": "GDPR Native",
+ "pill_self_hosted": "Self-Hosted",
+ "pill_eu": "EU Sovereign",
+ "preview_models": "Active Models",
+ "preview_tokens": "Tokens / Month",
+ "preview_spend": "Total Spend"
},
"article": {
"read_original": "Read original article",
diff --git a/assets/i18n/es.json b/assets/i18n/es.json
index 07187e1..8ebe514 100644
--- a/assets/i18n/es.json
+++ b/assets/i18n/es.json
@@ -224,7 +224,13 @@
"documentation": "Documentacion",
"api_reference": "Referencia API",
"support": "Soporte",
- "copyright": "2026 CERTifAI. Todos los derechos reservados."
+ "copyright": "2026 CERTifAI. Todos los derechos reservados.",
+ "pill_gdpr": "RGPD Nativo",
+ "pill_self_hosted": "Autoalojado",
+ "pill_eu": "Soberania UE",
+ "preview_models": "Modelos Activos",
+ "preview_tokens": "Tokens / Mes",
+ "preview_spend": "Gasto Total"
},
"article": {
"read_original": "Leer articulo original",
diff --git a/assets/i18n/fr.json b/assets/i18n/fr.json
index f58f9db..1cd640a 100644
--- a/assets/i18n/fr.json
+++ b/assets/i18n/fr.json
@@ -224,7 +224,13 @@
"documentation": "Documentation",
"api_reference": "Reference API",
"support": "Support",
- "copyright": "2026 CERTifAI. Tous droits reserves."
+ "copyright": "2026 CERTifAI. Tous droits reserves.",
+ "pill_gdpr": "RGPD Natif",
+ "pill_self_hosted": "Auto-heberge",
+ "pill_eu": "Souverainete UE",
+ "preview_models": "Modeles Actifs",
+ "preview_tokens": "Tokens / Mois",
+ "preview_spend": "Depenses Totales"
},
"article": {
"read_original": "Lire l'article original",
diff --git a/assets/i18n/pt.json b/assets/i18n/pt.json
index d930bf9..b3db706 100644
--- a/assets/i18n/pt.json
+++ b/assets/i18n/pt.json
@@ -224,7 +224,13 @@
"documentation": "Documentacao",
"api_reference": "Referencia API",
"support": "Suporte",
- "copyright": "2026 CERTifAI. Todos os direitos reservados."
+ "copyright": "2026 CERTifAI. Todos os direitos reservados.",
+ "pill_gdpr": "RGPD Nativo",
+ "pill_self_hosted": "Auto-Alojado",
+ "pill_eu": "Soberania UE",
+ "preview_models": "Modelos Ativos",
+ "preview_tokens": "Tokens / Mes",
+ "preview_spend": "Gasto Total"
},
"article": {
"read_original": "Ler artigo original",
diff --git a/assets/main.css b/assets/main.css
index b421414..c4c5d94 100644
--- a/assets/main.css
+++ b/assets/main.css
@@ -1,45 +1,85 @@
-/* ===== Theme Variables ===== */
+/* ========================================================================
+ GLASS AURORA THEME
+ ========================================================================
+ Mood: Vibrant, modern, glassmorphic, bold gradients
+ Palette: Deep navy/purple base, aurora gradient accents, glass effects
+ Fonts: Sora (headings) + Literata (body)
+ ======================================================================== */
+
+/* ===== Theme Variables (Dark - Default) ===== */
:root {
- --bg-body: #0f1116;
- --bg-sidebar: #0a0c10;
- --bg-card: #1a1d26;
- --bg-surface: #1e222d;
- --text-primary: #e2e8f0;
- --text-heading: #f1f5f9;
- --text-muted: #8892a8;
- --text-faint: #5a6478;
- --text-dimmest: #3d4556;
- --border-primary: #1e222d;
- --border-secondary: #2a2f3d;
- --accent: #91a4d2;
- --accent-secondary: #6d85c6;
- --avatar-text: #0a0c10;
+ --bg-body: #0c0a1d;
+ --bg-sidebar: rgba(16, 14, 36, 0.8);
+ --bg-card: rgba(22, 19, 48, 0.7);
+ --bg-surface: #100e24;
+ --bg-glass: rgba(255, 255, 255, 0.04);
+ --bg-glass-hover: rgba(255, 255, 255, 0.07);
+ --text-primary: #cfc8e8;
+ --text-heading: #f4f0ff;
+ --text-muted: #8b82aa;
+ --text-faint: #5a5280;
+ --text-dimmest: #3d3560;
+ --text-secondary: #8b82aa;
+ --border-primary: rgba(255, 255, 255, 0.08);
+ --border-secondary: rgba(255, 255, 255, 0.08);
+ --accent: #8b5cf6;
+ --accent-secondary: #6366f1;
+ --avatar-text: #ffffff;
+ --aurora: linear-gradient(135deg, #6366f1, #8b5cf6, #a855f7, #ec4899);
+ --aurora-muted: linear-gradient(135deg, rgba(99, 102, 241, 0.12), rgba(168, 85, 247, 0.12));
+ --glass-border: rgba(255, 255, 255, 0.08);
+ --glass-border-bright: rgba(255, 255, 255, 0.12);
+ --green: #34d399;
+ --green-dim: rgba(52, 211, 153, 0.15);
+ --shadow-glow: 0 0 60px rgba(139, 92, 246, 0.08);
+ --radius: 16px;
+ --radius-sm: 10px;
+ --radius-xl: 24px;
+ --gradient-start: #6366f1;
+ --gradient-mid: #a855f7;
+ --gradient-end: #ec4899;
}
+/* ===== Light Theme ===== */
[data-theme="certifai-light"] {
- --bg-body: #f4f6f9;
- --bg-sidebar: #ffffff;
- --bg-card: #ffffff;
- --bg-surface: #e9ecf2;
- --text-primary: #1e293b;
- --text-heading: #0f172a;
- --text-muted: #64748b;
- --text-faint: #94a3b8;
- --text-dimmest: #cbd5e1;
- --border-primary: #e2e8f0;
- --border-secondary: #cbd5e1;
- --accent: #5570b8;
- --accent-secondary: #3d5aaf;
+ --bg-body: #f8f6ff;
+ --bg-sidebar: rgba(255, 255, 255, 0.85);
+ --bg-card: rgba(255, 255, 255, 0.85);
+ --bg-surface: #ede8fa;
+ --bg-glass: rgba(124, 58, 237, 0.04);
+ --bg-glass-hover: rgba(124, 58, 237, 0.07);
+ --text-primary: #1e1640;
+ --text-heading: #0d0828;
+ --text-muted: #7b6fa0;
+ --text-faint: #a599c4;
+ --text-dimmest: #c4b8de;
+ --text-secondary: #7b6fa0;
+ --border-primary: #e0d8f0;
+ --border-secondary: #cec3e6;
+ --accent: #7c3aed;
+ --accent-secondary: #6d28d9;
--avatar-text: #ffffff;
+ --aurora: linear-gradient(135deg, #6366f1, #8b5cf6, #a855f7, #ec4899);
+ --aurora-muted: linear-gradient(135deg, rgba(99, 102, 241, 0.08), rgba(168, 85, 247, 0.08));
+ --glass-border: #e0d8f0;
+ --glass-border-bright: #cec3e6;
+ --green: #059669;
+ --green-dim: rgba(5, 150, 105, 0.1);
+ --shadow-glow: 0 0 60px rgba(139, 92, 246, 0.06);
+ --gradient-start: #6366f1;
+ --gradient-mid: #a855f7;
+ --gradient-end: #ec4899;
}
/* ===== Fonts ===== */
body {
- font-family: 'Inter', sans-serif;
+ font-family: 'Literata', serif;
background-color: var(--bg-body);
color: var(--text-primary);
margin: 0;
padding: 0;
+ line-height: 1.7;
+ -webkit-font-smoothing: antialiased;
}
h1,
@@ -48,7 +88,10 @@ h3,
h4,
h5,
h6 {
- font-family: 'Space Grotesk', sans-serif;
+ font-family: 'Sora', sans-serif;
+ font-weight: 700;
+ line-height: 1.15;
+ color: var(--text-heading);
}
/* ===== App Shell ===== */
@@ -72,7 +115,8 @@ h6 {
width: 260px;
min-width: 260px;
background-color: var(--bg-sidebar);
- border-right: 1px solid var(--border-primary);
+ backdrop-filter: blur(20px);
+ border-right: 1px solid var(--glass-border);
display: flex;
flex-direction: column;
height: 100vh;
@@ -86,7 +130,7 @@ h6 {
align-items: flex-start;
justify-content: space-between;
padding: 20px 14px 16px 20px;
- border-bottom: 1px solid var(--border-primary);
+ border-bottom: 1px solid var(--glass-border);
}
.sidebar-header {
@@ -110,21 +154,21 @@ h6 {
gap: 4px;
padding: 4px 8px;
border-radius: 6px;
- border: 1px solid var(--border-primary);
+ border: 1px solid var(--glass-border);
background: transparent;
color: var(--text-muted);
font-size: 11px;
font-weight: 600;
- font-family: 'Space Grotesk', sans-serif;
+ font-family: 'Sora', sans-serif;
cursor: pointer;
transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
letter-spacing: 0.5px;
}
.locale-picker-btn:hover {
- background-color: var(--bg-surface);
+ background-color: var(--bg-glass-hover);
color: var(--text-primary);
- border-color: var(--text-muted);
+ border-color: var(--glass-border-bright);
}
.locale-picker-code {
@@ -143,11 +187,12 @@ h6 {
right: 0;
z-index: 50;
min-width: 140px;
- background-color: var(--bg-sidebar);
- border: 1px solid var(--border-primary);
- border-radius: 8px;
+ background-color: var(--bg-surface);
+ backdrop-filter: blur(20px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius-sm);
padding: 4px;
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
.locale-picker-item {
@@ -167,17 +212,17 @@ h6 {
}
.locale-picker-item:hover {
- background-color: var(--bg-surface);
+ background-color: var(--bg-glass-hover);
color: var(--text-primary);
}
.locale-picker-item--active {
color: var(--accent);
- background-color: rgba(145, 164, 210, 0.1);
+ background-color: rgba(139, 92, 246, 0.1);
}
.locale-picker-item-code {
- font-family: 'Space Grotesk', sans-serif;
+ font-family: 'Sora', sans-serif;
font-weight: 600;
font-size: 11px;
letter-spacing: 0.5px;
@@ -193,15 +238,15 @@ h6 {
width: 38px;
height: 38px;
min-width: 38px;
- border-radius: 50%;
- background: linear-gradient(135deg, var(--accent), var(--accent-secondary));
+ border-radius: var(--radius-sm);
+ background: var(--aurora);
display: flex;
align-items: center;
justify-content: center;
}
.avatar-initials {
- font-family: 'Space Grotesk', sans-serif;
+ font-family: 'Sora', sans-serif;
font-size: 14px;
font-weight: 600;
color: var(--avatar-text);
@@ -245,7 +290,7 @@ h6 {
align-items: center;
gap: 12px;
padding: 10px 14px;
- border-radius: 8px;
+ border-radius: var(--radius-sm);
color: var(--text-muted);
text-decoration: none;
font-size: 14px;
@@ -254,13 +299,14 @@ h6 {
}
.sidebar-link:hover {
- background-color: var(--bg-surface);
+ background-color: var(--bg-glass-hover);
color: var(--text-primary);
}
.sidebar-link.active {
- background-color: rgba(145, 164, 210, 0.12);
- color: var(--accent);
+ background-color: rgba(99, 102, 241, 0.12);
+ color: #a5b4fc;
+ font-weight: 600;
}
/* -- Sidebar Bottom Actions (Logout + Theme Toggle) -- */
@@ -269,7 +315,7 @@ h6 {
align-items: center;
justify-content: space-between;
padding: 4px 10px;
- border-top: 1px solid var(--border-primary);
+ border-top: 1px solid var(--glass-border);
}
.logout-btn {
@@ -297,13 +343,13 @@ h6 {
.theme-toggle-btn:hover {
color: var(--accent);
- background-color: var(--bg-surface);
+ background-color: var(--bg-glass-hover);
}
/* -- Sidebar Footer -- */
.sidebar-footer {
padding: 16px 20px;
- border-top: 1px solid var(--border-primary);
+ border-top: 1px solid var(--glass-border);
display: flex;
flex-direction: column;
align-items: center;
@@ -353,7 +399,7 @@ h6 {
.sidebar-version {
font-size: 11px;
color: var(--text-dimmest);
- font-family: 'Inter', monospace;
+ font-family: 'Literata', monospace;
}
/* ===== Main Content ===== */
@@ -395,17 +441,19 @@ h6 {
flex-direction: column;
gap: 12px;
padding: 24px;
- background-color: var(--bg-surface);
- border: 1px solid var(--border-secondary);
- border-radius: 12px;
+ background-color: var(--bg-card);
+ backdrop-filter: blur(12px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
text-decoration: none;
color: var(--text-primary);
- transition: border-color 0.2s ease, box-shadow 0.2s ease;
+ transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
.dashboard-card:hover {
- border-color: var(--accent);
- box-shadow: 0 0 20px rgba(145, 164, 210, 0.10);
+ border-color: var(--glass-border-bright);
+ box-shadow: var(--shadow-glow);
+ transform: translateY(-2px);
}
.card-icon {
@@ -430,6 +478,31 @@ h6 {
min-height: 100vh;
display: flex;
flex-direction: column;
+ position: relative;
+ overflow: hidden;
+}
+
+/* Aurora background atmosphere */
+.landing::before {
+ content: '';
+ position: fixed;
+ top: -40%;
+ left: -20%;
+ width: 80%;
+ height: 80%;
+ background: radial-gradient(ellipse, rgba(99, 102, 241, 0.12) 0%, transparent 60%);
+ pointer-events: none;
+}
+
+.landing::after {
+ content: '';
+ position: fixed;
+ bottom: -30%;
+ right: -20%;
+ width: 70%;
+ height: 70%;
+ background: radial-gradient(ellipse, rgba(236, 72, 153, 0.08) 0%, transparent 60%);
+ pointer-events: none;
}
/* -- Landing Nav -- */
@@ -437,15 +510,19 @@ h6 {
position: sticky;
top: 0;
z-index: 100;
- background-color: color-mix(in srgb, var(--bg-body) 85%, transparent);
- backdrop-filter: blur(12px);
- border-bottom: 1px solid var(--border-primary);
+ background: rgba(16, 14, 36, 0.6);
+ backdrop-filter: blur(24px);
+ border-bottom: 1px solid var(--glass-border);
+}
+
+[data-theme="certifai-light"] .landing-nav {
+ background: rgba(248, 246, 255, 0.7);
}
.landing-nav-inner {
max-width: 1200px;
margin: 0 auto;
- padding: 16px 32px;
+ padding: 18px 56px;
display: flex;
align-items: center;
gap: 32px;
@@ -455,10 +532,13 @@ h6 {
display: flex;
align-items: center;
gap: 10px;
- font-family: 'Space Grotesk', sans-serif;
- font-size: 20px;
- font-weight: 700;
- color: var(--text-heading);
+ font-family: 'Sora', sans-serif;
+ font-size: 22px;
+ font-weight: 800;
+ background: var(--aurora);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
text-decoration: none;
}
@@ -466,29 +546,32 @@ h6 {
color: var(--accent);
display: flex;
align-items: center;
+ /* Override the gradient text fill for the icon */
+ -webkit-text-fill-color: initial;
}
.landing-nav-links {
display: flex;
- gap: 28px;
+ gap: 32px;
flex: 1;
}
.landing-nav-links a {
- color: var(--text-muted);
+ color: var(--text-secondary);
text-decoration: none;
- font-size: 14px;
+ font-family: 'Sora', sans-serif;
+ font-size: 13px;
font-weight: 500;
- transition: color 0.15s ease;
+ transition: color 0.2s ease;
}
.landing-nav-links a:hover {
- color: var(--text-primary);
+ color: var(--text-heading);
}
.landing-nav-actions {
display: flex;
- gap: 12px;
+ gap: 10px;
align-items: center;
}
@@ -496,170 +579,207 @@ h6 {
.hero-section {
max-width: 1200px;
margin: 0 auto;
- padding: 80px 32px 60px;
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 64px;
- align-items: center;
+ padding: 120px 56px 100px;
+ text-align: center;
+ position: relative;
width: 100%;
}
.hero-content {
display: flex;
flex-direction: column;
- align-items: flex-start;
+ align-items: center;
}
-.hero-badge {
- font-size: 13px;
+/* -- Hero Pills -- */
+.hero-pills {
+ display: flex;
+ gap: 8px;
+ justify-content: center;
+ margin-bottom: 32px;
+ animation: fadeUp 0.6s ease;
+}
+
+.pill {
+ font-family: 'Sora', sans-serif;
+ font-size: 12px;
font-weight: 500;
- color: var(--accent);
- border-color: rgba(145, 164, 210, 0.3);
- margin-bottom: 24px;
+ padding: 6px 16px;
+ background: var(--bg-glass);
+ border: 1px solid var(--glass-border);
+ border-radius: 100px;
+ color: var(--text-secondary);
+ backdrop-filter: blur(8px);
+}
+
+.pill.accent {
+ background: rgba(99, 102, 241, 0.15);
+ border-color: rgba(99, 102, 241, 0.3);
+ color: #a5b4fc;
+}
+
+[data-theme="certifai-light"] .pill.accent {
+ color: #6366f1;
}
.hero-title {
- font-size: 52px;
+ font-size: 68px;
font-weight: 700;
line-height: 1.1;
+ letter-spacing: -2px;
color: var(--text-heading);
- margin: 0 0 24px;
- width: 100%;
+ margin: 0 0 20px;
+ animation: fadeUp 0.6s ease 0.1s both;
}
.hero-title-accent {
- background: linear-gradient(135deg, var(--accent), var(--accent-secondary));
+ background: var(--aurora);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hero-subtitle {
- font-size: 18px;
+ font-size: 17px;
line-height: 1.7;
- color: var(--text-muted);
- margin: 0 0 36px;
- max-width: 520px;
- width: 100%;
+ color: var(--text-secondary);
+ margin: 0 auto 40px;
+ max-width: 540px;
+ animation: fadeUp 0.6s ease 0.2s both;
}
.hero-actions {
display: flex;
- gap: 16px;
- align-items: center;
-}
-
-.hero-graphic {
- display: flex;
+ gap: 14px;
justify-content: center;
- align-items: center;
- width: 100%;
- min-height: 350px;
+ animation: fadeUp 0.6s ease 0.3s both;
}
-/* -- Social Proof -- */
-.social-proof {
- border-top: 1px solid var(--border-primary);
- border-bottom: 1px solid var(--border-primary);
- padding: 40px 32px;
+/* -- Glass Preview -- */
+.preview-container {
+ max-width: 900px;
+ margin: 64px auto 0;
+ animation: fadeUp 0.8s ease 0.4s both;
+ width: 100%;
+}
+
+.glass-preview {
+ background: var(--bg-card);
+ backdrop-filter: blur(20px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius-xl);
+ padding: 32px;
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 16px;
+}
+
+.preview-stat {
+ padding: 20px;
+ background: var(--bg-glass);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
text-align: center;
}
-.social-proof-text {
- font-size: 16px;
+.preview-stat-value {
+ font-family: 'Sora', sans-serif;
+ font-size: 28px;
+ font-weight: 700;
+ color: var(--text-heading);
+ margin-bottom: 4px;
+}
+
+.preview-stat-label {
+ font-family: 'Sora', sans-serif;
+ font-size: 12px;
color: var(--text-muted);
- margin: 0 0 28px;
}
-.social-proof-highlight {
- color: var(--accent);
- font-weight: 600;
-}
-
-.social-proof-stats {
+/* -- Trust Bar -- */
+.trust-bar {
display: flex;
justify-content: center;
gap: 40px;
- align-items: center;
- flex-wrap: wrap;
+ padding: 48px 56px;
+ border-top: 1px solid var(--glass-border);
}
-.proof-stat {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 4px;
-}
-
-.proof-stat-value {
- font-family: 'Space Grotesk', sans-serif;
- font-size: 24px;
- font-weight: 700;
- color: var(--text-heading);
-}
-
-.proof-stat-label {
+.trust-item {
+ font-family: 'Sora', sans-serif;
font-size: 13px;
- color: var(--text-faint);
- text-transform: uppercase;
- letter-spacing: 0.05em;
+ font-weight: 500;
+ color: var(--text-muted);
+ display: flex;
+ align-items: center;
+ gap: 8px;
}
-.proof-divider {
- width: 1px;
- height: 40px;
- background-color: var(--bg-surface);
+.trust-dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background: var(--aurora);
}
/* -- Section Titles -- */
.section-title {
- font-size: 36px;
+ font-size: 40px;
font-weight: 700;
color: var(--text-heading);
text-align: center;
margin: 0 0 12px;
+ letter-spacing: -1px;
}
.section-subtitle {
- font-size: 18px;
- color: var(--text-muted);
+ font-size: 16px;
+ color: var(--text-secondary);
text-align: center;
- margin: 0 0 48px;
+ margin: 0 auto 60px;
+ max-width: 450px;
}
/* -- Features Section -- */
.features-section {
max-width: 1200px;
margin: 0 auto;
- padding: 80px 32px;
+ padding: 100px 56px;
}
.features-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
- gap: 24px;
+ gap: 16px;
}
.feature-card {
+ padding: 28px;
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
- border-radius: 12px;
- padding: 32px 28px;
- transition: border-color 0.2s ease, transform 0.2s ease;
+ backdrop-filter: blur(12px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
+ transition: all 0.3s ease;
+ position: relative;
+ overflow: hidden;
}
.feature-card:hover {
- border-color: var(--accent);
+ border-color: var(--glass-border-bright);
+ box-shadow: var(--shadow-glow);
transform: translateY(-2px);
}
-.feature-card-icon {
- color: var(--accent);
- margin-bottom: 16px;
+.feature-icon-bar {
+ width: 40px;
+ height: 4px;
+ border-radius: 2px;
+ background: var(--aurora);
+ margin-bottom: 18px;
}
.feature-card-title {
- font-size: 18px;
+ font-size: 16px;
font-weight: 600;
color: var(--text-heading);
margin: 0 0 8px;
@@ -667,8 +787,8 @@ h6 {
.feature-card-desc {
font-size: 14px;
- line-height: 1.6;
- color: var(--text-muted);
+ line-height: 1.7;
+ color: var(--text-secondary);
margin: 0;
}
@@ -676,7 +796,7 @@ h6 {
.how-it-works-section {
max-width: 1200px;
margin: 0 auto;
- padding: 80px 32px;
+ padding: 80px 56px;
}
.steps-grid {
@@ -691,10 +811,10 @@ h6 {
}
.step-number {
- font-family: 'Space Grotesk', sans-serif;
+ font-family: 'Sora', sans-serif;
font-size: 48px;
font-weight: 700;
- background: linear-gradient(135deg, var(--accent), var(--accent-secondary));
+ background: var(--aurora);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
@@ -716,17 +836,32 @@ h6 {
margin: 0;
}
-/* -- CTA Banner -- */
-.cta-banner {
- max-width: 900px;
- margin: 0 auto 80px;
- padding: 64px 48px;
+/* -- CTA Section -- */
+.cta-section {
+ padding: 80px 56px;
text-align: center;
- background: linear-gradient(135deg,
- rgba(145, 164, 210, 0.08),
- rgba(109, 133, 198, 0.04));
- border: 1px solid rgba(145, 164, 210, 0.15);
- border-radius: 20px;
+}
+
+.cta-box {
+ max-width: 700px;
+ margin: 0 auto;
+ padding: 60px;
+ background: var(--bg-card);
+ backdrop-filter: blur(20px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius-xl);
+ position: relative;
+ overflow: hidden;
+}
+
+.cta-box::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 2px;
+ background: var(--aurora);
}
.cta-title {
@@ -737,9 +872,9 @@ h6 {
}
.cta-subtitle {
- font-size: 18px;
- color: var(--text-muted);
- margin: 0 0 32px;
+ font-size: 15px;
+ color: var(--text-secondary);
+ margin: 0 0 28px;
}
.cta-actions {
@@ -750,8 +885,8 @@ h6 {
/* -- Landing Footer -- */
.landing-footer {
- border-top: 1px solid var(--border-primary);
- padding: 60px 32px 0;
+ border-top: 1px solid var(--glass-border);
+ padding: 60px 56px 0;
margin-top: auto;
}
@@ -783,6 +918,7 @@ h6 {
}
.footer-links-heading {
+ font-family: 'Sora', sans-serif;
font-size: 13px;
font-weight: 600;
color: var(--text-muted);
@@ -799,20 +935,21 @@ h6 {
}
.footer-links-group a:hover {
- color: var(--accent);
+ color: var(--text-heading);
}
.footer-bottom {
max-width: 1200px;
margin: 48px auto 0;
padding: 20px 0;
- border-top: 1px solid var(--border-primary);
+ border-top: 1px solid var(--glass-border);
text-align: center;
}
.footer-bottom p {
- font-size: 13px;
- color: var(--text-dimmest);
+ font-family: 'Sora', sans-serif;
+ font-size: 12px;
+ color: var(--text-muted);
margin: 0;
}
@@ -825,7 +962,7 @@ h6 {
.legal-nav {
padding: 20px 32px;
- border-bottom: 1px solid var(--border-primary);
+ border-bottom: 1px solid var(--glass-border);
}
.legal-content {
@@ -876,7 +1013,7 @@ h6 {
.legal-footer {
padding: 20px 32px;
- border-top: 1px solid var(--border-primary);
+ border-top: 1px solid var(--glass-border);
display: flex;
gap: 24px;
justify-content: center;
@@ -896,16 +1033,12 @@ h6 {
/* ===== Responsive: Landing Page ===== */
@media (max-width: 1024px) {
.hero-section {
- grid-template-columns: 1fr;
- padding: 60px 24px 40px;
- gap: 40px;
+ padding: 80px 24px 60px;
}
- .hero-graphic {
- max-width: 320px;
- margin: 0 auto;
- order: -1;
- min-height: auto;
+ .hero-title {
+ font-size: 48px;
+ letter-spacing: -1px;
}
.features-grid {
@@ -916,6 +1049,29 @@ h6 {
grid-template-columns: 1fr 1fr;
gap: 32px;
}
+
+ .landing-nav-inner {
+ padding: 16px 24px;
+ }
+
+ .features-section,
+ .how-it-works-section {
+ padding: 80px 24px;
+ }
+
+ .cta-section {
+ padding: 60px 24px;
+ }
+
+ .trust-bar {
+ padding: 40px 24px;
+ gap: 24px;
+ flex-wrap: wrap;
+ }
+
+ .landing-footer {
+ padding: 48px 24px 0;
+ }
}
@media (max-width: 768px) {
@@ -923,6 +1079,10 @@ h6 {
display: none;
}
+ .hero-section {
+ padding: 60px 16px 40px;
+ }
+
.hero-title {
font-size: 36px;
}
@@ -936,21 +1096,26 @@ h6 {
align-items: stretch;
}
+ .hero-pills {
+ flex-wrap: wrap;
+ }
+
.features-grid,
.steps-grid {
grid-template-columns: 1fr;
}
- .social-proof-stats {
- gap: 24px;
+ .glass-preview {
+ grid-template-columns: 1fr;
}
- .proof-divider {
- display: none;
+ .trust-bar {
+ flex-direction: column;
+ align-items: center;
+ gap: 16px;
}
- .cta-banner {
- margin: 0 16px 60px;
+ .cta-box {
padding: 40px 24px;
}
@@ -973,30 +1138,68 @@ h6 {
}
}
+@media (max-width: 480px) {
+ .hero-title {
+ font-size: 28px;
+ }
+
+ .hero-subtitle {
+ font-size: 15px;
+ }
+
+ .section-title {
+ font-size: 24px;
+ }
+
+ .landing-nav-inner {
+ padding: 12px 16px;
+ }
+
+ .features-section,
+ .how-it-works-section {
+ padding: 48px 16px;
+ }
+
+ .step-card {
+ padding: 24px 16px;
+ }
+
+ .feature-card {
+ padding: 20px 16px;
+ }
+}
+
/* ===== Shared UI Elements ===== */
.btn-primary {
display: inline-flex;
align-items: center;
justify-content: center;
- padding: 10px 20px;
- background: linear-gradient(135deg, var(--accent), var(--accent-secondary));
- color: var(--avatar-text);
+ gap: 8px;
+ padding: 10px 24px;
+ background: var(--aurora);
+ background-size: 200% 200%;
+ color: #fff;
border: none;
- border-radius: 8px;
+ border-radius: var(--radius-sm);
font-size: 14px;
font-weight: 600;
cursor: pointer;
- transition: opacity 0.15s ease;
- font-family: 'Inter', sans-serif;
+ transition: all 0.3s ease;
+ font-family: 'Sora', sans-serif;
+ text-decoration: none;
}
.btn-primary:hover {
- opacity: 0.9;
+ background-position: 100% 0;
+ transform: translateY(-1px);
+ box-shadow: 0 4px 24px rgba(139, 92, 246, 0.3);
}
.btn-primary:disabled {
opacity: 0.4;
cursor: not-allowed;
+ transform: none;
+ box-shadow: none;
}
.btn-secondary {
@@ -1004,19 +1207,66 @@ h6 {
align-items: center;
justify-content: center;
padding: 10px 20px;
- background-color: var(--bg-surface);
+ background-color: var(--bg-glass);
color: var(--text-primary);
- border: 1px solid var(--border-secondary);
- border-radius: 8px;
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius-sm);
font-size: 14px;
font-weight: 500;
cursor: pointer;
- transition: border-color 0.15s ease;
- font-family: 'Inter', sans-serif;
+ transition: all 0.2s ease;
+ font-family: 'Sora', sans-serif;
+ text-decoration: none;
}
.btn-secondary:hover {
- border-color: var(--accent);
+ background-color: var(--bg-glass-hover);
+ border-color: var(--glass-border-bright);
+}
+
+.btn-ghost {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 10px 22px;
+ background: transparent;
+ color: var(--text-secondary);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius-sm);
+ font-size: 13px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ font-family: 'Sora', sans-serif;
+ text-decoration: none;
+}
+
+.btn-ghost:hover {
+ border-color: var(--glass-border-bright);
+ color: var(--text-heading);
+}
+
+.btn-outline {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 10px 22px;
+ background: var(--bg-glass);
+ backdrop-filter: blur(8px);
+ color: var(--text-primary);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius-sm);
+ font-size: 14px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: all 0.25s ease;
+ font-family: 'Sora', sans-serif;
+ text-decoration: none;
+}
+
+.btn-outline:hover {
+ background: var(--bg-glass-hover);
+ border-color: var(--glass-border-bright);
}
.btn-icon {
@@ -1027,7 +1277,7 @@ h6 {
height: 36px;
background-color: transparent;
color: var(--text-muted);
- border: 1px solid var(--border-secondary);
+ border: 1px solid var(--glass-border);
border-radius: 8px;
cursor: pointer;
font-size: 16px;
@@ -1054,6 +1304,29 @@ h6 {
color: #f87171;
}
+.btn-sm {
+ padding: 8px 18px;
+ font-size: 13px;
+}
+
+.btn-lg {
+ padding: 14px 36px;
+ font-size: 14px;
+}
+
+.badge {
+ font-family: 'Sora', sans-serif;
+ font-size: 12px;
+ font-weight: 500;
+ padding: 4px 12px;
+ border-radius: 100px;
+}
+
+.badge-outline {
+ border: 1px solid var(--glass-border);
+ color: var(--accent);
+}
+
/* ===== Form Elements ===== */
.form-group {
display: flex;
@@ -1072,11 +1345,11 @@ h6 {
.form-input {
padding: 10px 14px;
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
- border-radius: 8px;
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius-sm);
color: var(--text-primary);
font-size: 14px;
- font-family: 'Inter', sans-serif;
+ font-family: 'Literata', serif;
outline: none;
transition: border-color 0.15s ease;
}
@@ -1088,7 +1361,7 @@ h6 {
.form-success {
font-size: 13px;
- color: #4ade80;
+ color: var(--green);
margin-top: 8px;
}
@@ -1106,14 +1379,16 @@ h6 {
}
.page-title {
- font-size: 28px;
+ font-size: 26px;
font-weight: 700;
+ letter-spacing: -0.5px;
color: var(--text-heading);
margin: 0 0 4px;
}
.page-subtitle {
- font-size: 15px;
+ font-family: 'Sora', sans-serif;
+ font-size: 13px;
color: var(--text-muted);
margin: 0;
}
@@ -1123,13 +1398,13 @@ h6 {
display: flex;
gap: 4px;
padding: 0 0 20px;
- border-bottom: 1px solid var(--border-primary);
+ border-bottom: 1px solid var(--glass-border);
margin-bottom: 24px;
}
.sub-nav-item {
padding: 8px 16px;
- border-radius: 8px;
+ border-radius: var(--radius-sm);
font-size: 14px;
font-weight: 500;
color: var(--text-muted);
@@ -1138,12 +1413,16 @@ h6 {
}
.sub-nav-item:hover {
- background-color: var(--bg-surface);
+ background-color: var(--bg-glass-hover);
color: var(--text-primary);
}
.sub-nav-item--active {
- background-color: rgba(145, 164, 210, 0.12);
+ background-color: rgba(99, 102, 241, 0.12);
+ color: #a5b4fc;
+}
+
+[data-theme="certifai-light"] .sub-nav-item--active {
color: var(--accent);
}
@@ -1172,23 +1451,23 @@ h6 {
.filter-tab {
padding: 6px 16px;
border-radius: 20px;
- border: 1px solid var(--border-secondary);
+ border: 1px solid var(--glass-border);
background-color: transparent;
color: var(--text-muted);
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: all 0.15s ease;
- font-family: 'Inter', sans-serif;
+ font-family: 'Sora', sans-serif;
}
.filter-tab:hover {
- border-color: var(--accent);
+ border-color: var(--glass-border-bright);
color: var(--text-primary);
}
.filter-tab--active {
- background-color: rgba(145, 164, 210, 0.12);
+ background-color: rgba(99, 102, 241, 0.12);
border-color: var(--accent);
color: var(--accent);
}
@@ -1202,17 +1481,20 @@ h6 {
.news-card {
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
- border-radius: 12px;
+ backdrop-filter: blur(12px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
overflow: hidden;
- transition: border-color 0.2s ease, transform 0.2s ease;
+ transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
display: flex;
flex-direction: column;
+ cursor: pointer;
}
.news-card:hover {
- border-color: var(--accent);
+ border-color: var(--glass-border-bright);
transform: translateY(-2px);
+ box-shadow: var(--shadow-glow);
}
.news-card-thumb {
@@ -1225,7 +1507,6 @@ h6 {
width: 100%;
height: 100%;
object-fit: cover;
- /* Hide alt text on broken images */
color: transparent;
font-size: 0;
}
@@ -1246,13 +1527,13 @@ h6 {
}
.news-badge {
+ font-family: 'Sora', sans-serif;
font-size: 11px;
font-weight: 600;
padding: 2px 8px;
border-radius: 4px;
text-transform: uppercase;
letter-spacing: 0.05em;
- /* Default badge color for any topic */
background-color: rgba(99, 132, 210, 0.15);
color: var(--accent);
}
@@ -1268,8 +1549,8 @@ h6 {
}
.news-badge--privacy {
- background-color: rgba(34, 197, 94, 0.15);
- color: #4ade80;
+ background-color: rgba(52, 211, 153, 0.15);
+ color: #34d399;
}
.news-badge--infrastructure {
@@ -1318,7 +1599,7 @@ h6 {
.news-card--selected {
border-color: var(--accent);
- background-color: rgba(145, 164, 210, 0.08);
+ background-color: rgba(139, 92, 246, 0.08);
}
.news-card--no-thumb {
@@ -1334,10 +1615,6 @@ h6 {
justify-content: center;
}
-.news-card {
- cursor: pointer;
-}
-
/* ===== Dashboard Split View ===== */
.dashboard-split {
display: flex;
@@ -1415,13 +1692,13 @@ h6 {
.topic-add-btn {
padding: 6px 14px;
border-radius: 20px;
- border: 1px dashed var(--border-secondary);
+ border: 1px dashed var(--glass-border);
background-color: transparent;
color: var(--text-faint);
font-size: 16px;
cursor: pointer;
transition: all 0.15s ease;
- font-family: 'Inter', sans-serif;
+ font-family: 'Sora', sans-serif;
line-height: 1;
}
@@ -1439,11 +1716,11 @@ h6 {
.topic-input {
padding: 5px 12px;
border-radius: 20px;
- border: 1px solid var(--border-secondary);
+ border: 1px solid var(--glass-border);
background-color: var(--bg-card);
color: var(--text-primary);
font-size: 13px;
- font-family: 'Inter', sans-serif;
+ font-family: 'Literata', serif;
outline: none;
width: 140px;
}
@@ -1471,8 +1748,9 @@ h6 {
.settings-panel {
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
- border-radius: 12px;
+ backdrop-filter: blur(12px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
padding: 20px;
margin-bottom: 24px;
}
@@ -1500,12 +1778,12 @@ h6 {
width: 100%;
max-width: 400px;
padding: 8px 12px;
- border-radius: 8px;
- border: 1px solid var(--border-secondary);
+ border-radius: var(--radius-sm);
+ border: 1px solid var(--glass-border);
background-color: var(--bg-body);
color: var(--text-primary);
font-size: 13px;
- font-family: 'Inter', sans-serif;
+ font-family: 'Literata', serif;
outline: none;
}
@@ -1516,7 +1794,7 @@ h6 {
.settings-hint {
background-color: rgba(234, 179, 8, 0.1);
border: 1px solid rgba(234, 179, 8, 0.3);
- border-radius: 8px;
+ border-radius: var(--radius-sm);
padding: 12px 16px;
margin-bottom: 16px;
font-size: 13px;
@@ -1526,8 +1804,9 @@ h6 {
/* ===== Article Detail Panel ===== */
.article-detail-panel {
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
- border-radius: 12px;
+ backdrop-filter: blur(12px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
padding: 24px;
position: relative;
}
@@ -1537,7 +1816,7 @@ h6 {
top: 16px;
right: 16px;
background: none;
- border: 1px solid var(--border-secondary);
+ border: 1px solid var(--glass-border);
color: var(--text-muted);
width: 32px;
height: 32px;
@@ -1623,9 +1902,9 @@ h6 {
/* ---- AI Summary Bubble ---- */
.ai-summary-bubble {
margin-top: 20px;
- background-color: rgba(145, 164, 210, 0.08);
- border: 1px solid rgba(145, 164, 210, 0.18);
- border-radius: 12px;
+ background-color: rgba(139, 92, 246, 0.08);
+ border: 1px solid rgba(139, 92, 246, 0.18);
+ border-radius: var(--radius);
padding: 16px 18px;
position: relative;
}
@@ -1703,7 +1982,7 @@ h6 {
/* ---- Follow-up Chat ---- */
.article-chat {
margin-top: 16px;
- border-top: 1px solid var(--border-secondary);
+ border-top: 1px solid var(--glass-border);
padding-top: 16px;
}
@@ -1720,7 +1999,7 @@ h6 {
.chat-msg {
max-width: 85%;
padding: 10px 14px;
- border-radius: 12px;
+ border-radius: var(--radius);
font-size: 14px;
line-height: 1.55;
}
@@ -1732,16 +2011,16 @@ h6 {
.chat-msg--user {
align-self: flex-end;
- background: rgba(99, 132, 210, 0.2);
- border: 1px solid rgba(99, 132, 210, 0.3);
+ background: rgba(99, 102, 241, 0.2);
+ border: 1px solid rgba(99, 102, 241, 0.3);
color: var(--text-primary);
border-bottom-right-radius: 4px;
}
.chat-msg--assistant {
align-self: flex-start;
- background: rgba(145, 164, 210, 0.08);
- border: 1px solid rgba(145, 164, 210, 0.15);
+ background: rgba(139, 92, 246, 0.08);
+ border: 1px solid rgba(139, 92, 246, 0.15);
color: var(--text-primary);
border-bottom-left-radius: 4px;
}
@@ -1758,8 +2037,8 @@ h6 {
.article-chat-textbox {
flex: 1;
background: var(--bg-card);
- border: 1px solid var(--border-secondary);
- border-radius: 8px;
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius-sm);
padding: 10px 14px;
font-size: 14px;
color: var(--text-primary);
@@ -1768,7 +2047,7 @@ h6 {
}
.article-chat-textbox:focus {
- border-color: var(--accent-secondary);
+ border-color: var(--accent);
}
.article-chat-textbox:disabled {
@@ -1776,20 +2055,21 @@ h6 {
}
.article-chat-send {
- background: var(--accent-secondary);
- color: var(--avatar-text);
+ background: var(--aurora);
+ background-size: 200% 200%;
+ color: #fff;
border: none;
- border-radius: 8px;
+ border-radius: var(--radius-sm);
padding: 10px 18px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
- transition: background 0.2s;
+ transition: all 0.3s;
white-space: nowrap;
}
.article-chat-send:hover:not(:disabled) {
- background: var(--accent);
+ background-position: 100% 0;
}
.article-chat-send:disabled {
@@ -1810,8 +2090,9 @@ h6 {
.providers-form {
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
- border-radius: 12px;
+ backdrop-filter: blur(12px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
padding: 28px;
}
@@ -1830,8 +2111,9 @@ h6 {
.status-card {
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
- border-radius: 12px;
+ backdrop-filter: blur(12px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
padding: 20px;
}
@@ -1839,7 +2121,7 @@ h6 {
display: flex;
justify-content: space-between;
padding: 10px 0;
- border-bottom: 1px solid var(--border-primary);
+ border-bottom: 1px solid var(--glass-border);
}
.status-row:last-child {
@@ -1868,10 +2150,11 @@ h6 {
.chat-sidebar-panel {
width: 260px;
min-width: 260px;
- border-right: 1px solid var(--border-primary);
+ border-right: 1px solid var(--glass-border);
display: flex;
flex-direction: column;
background-color: var(--bg-sidebar);
+ backdrop-filter: blur(20px);
}
.chat-sidebar-header {
@@ -1879,7 +2162,7 @@ h6 {
align-items: center;
justify-content: space-between;
padding: 20px;
- border-bottom: 1px solid var(--border-primary);
+ border-bottom: 1px solid var(--glass-border);
}
.chat-sidebar-header h3 {
@@ -1899,20 +2182,24 @@ h6 {
width: 100%;
text-align: left;
padding: 12px;
- border-radius: 8px;
+ border-radius: var(--radius-sm);
border: none;
background-color: transparent;
cursor: pointer;
transition: background-color 0.15s ease;
- font-family: 'Inter', sans-serif;
+ font-family: 'Literata', serif;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ position: relative;
}
.chat-session-item:hover {
- background-color: var(--bg-surface);
+ background-color: var(--bg-glass-hover);
}
.chat-session-item--active {
- background-color: rgba(145, 164, 210, 0.12);
+ background-color: rgba(99, 102, 241, 0.12);
}
.chat-session-title {
@@ -1920,6 +2207,9 @@ h6 {
font-weight: 500;
color: var(--text-primary);
margin-bottom: 4px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
}
.chat-session-date {
@@ -1927,6 +2217,23 @@ h6 {
color: var(--text-faint);
}
+.chat-session-info {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ flex-direction: column;
+}
+
+.chat-session-actions {
+ display: none;
+ gap: 4px;
+ flex-shrink: 0;
+}
+
+.chat-session-item:hover .chat-session-actions {
+ display: flex;
+}
+
.chat-main-panel {
flex: 1;
display: flex;
@@ -1954,14 +2261,14 @@ h6 {
.chat-bubble {
max-width: 72%;
padding: 14px 18px;
- border-radius: 12px;
+ border-radius: var(--radius);
font-size: 14px;
line-height: 1.6;
}
.chat-bubble--user {
align-self: flex-end;
- background-color: rgba(145, 164, 210, 0.15);
+ background-color: rgba(99, 102, 241, 0.15);
color: var(--text-primary);
border-bottom-right-radius: 4px;
}
@@ -1969,7 +2276,7 @@ h6 {
.chat-bubble--assistant {
align-self: flex-start;
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
+ border: 1px solid var(--glass-border);
color: var(--text-primary);
border-bottom-left-radius: 4px;
}
@@ -2014,7 +2321,7 @@ h6 {
.chat-attachment {
font-size: 12px;
padding: 4px 10px;
- background-color: rgba(145, 164, 210, 0.1);
+ background-color: rgba(139, 92, 246, 0.1);
border-radius: 4px;
color: var(--accent);
}
@@ -2044,8 +2351,8 @@ h6 {
.chat-action-btn:hover:not(:disabled) {
color: var(--text-primary);
- background-color: var(--bg-card);
- border-color: var(--border-secondary);
+ background-color: var(--bg-glass-hover);
+ border-color: var(--glass-border);
}
.chat-action-btn:disabled {
@@ -2054,7 +2361,7 @@ h6 {
}
.chat-action-label {
- font-family: 'Inter', sans-serif;
+ font-family: 'Sora', sans-serif;
}
/* -- Chat Input Bar -- */
@@ -2063,7 +2370,7 @@ h6 {
align-items: center;
gap: 8px;
padding: 16px 24px;
- border-top: 1px solid var(--border-primary);
+ border-top: 1px solid var(--glass-border);
background-color: var(--bg-sidebar);
}
@@ -2071,11 +2378,11 @@ h6 {
flex: 1;
padding: 10px 14px;
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
- border-radius: 8px;
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius-sm);
color: var(--text-primary);
font-size: 14px;
- font-family: 'Inter', sans-serif;
+ font-family: 'Literata', serif;
outline: none;
}
@@ -2097,7 +2404,7 @@ h6 {
align-items: center;
gap: 10px;
padding: 10px 24px;
- border-bottom: 1px solid var(--border-primary);
+ border-bottom: 1px solid var(--glass-border);
background-color: var(--bg-sidebar);
}
@@ -2110,11 +2417,11 @@ h6 {
.chat-model-select {
padding: 6px 12px;
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
+ border: 1px solid var(--glass-border);
border-radius: 6px;
color: var(--text-primary);
font-size: 13px;
- font-family: 'Inter', sans-serif;
+ font-family: 'Literata', serif;
outline: none;
cursor: pointer;
min-width: 160px;
@@ -2126,6 +2433,7 @@ h6 {
/* -- Chat Namespace Headers -- */
.chat-namespace-header {
+ font-family: 'Sora', sans-serif;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
@@ -2134,37 +2442,6 @@ h6 {
padding: 12px 12px 4px;
}
-/* -- Chat Session Item Layout -- */
-.chat-session-item {
- display: flex;
- align-items: center;
- justify-content: space-between;
- position: relative;
-}
-
-.chat-session-info {
- flex: 1;
- min-width: 0;
- display: flex;
- flex-direction: column;
-}
-
-.chat-session-title {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.chat-session-actions {
- display: none;
- gap: 4px;
- flex-shrink: 0;
-}
-
-.chat-session-item:hover .chat-session-actions {
- display: flex;
-}
-
.btn-icon-sm {
width: 24px;
height: 24px;
@@ -2181,7 +2458,7 @@ h6 {
}
.btn-icon-sm:hover {
- background-color: var(--bg-surface);
+ background-color: var(--bg-glass-hover);
color: var(--text-primary);
}
@@ -2198,7 +2475,7 @@ h6 {
border-radius: 6px;
color: var(--text-primary);
font-size: 13px;
- font-family: 'Inter', sans-serif;
+ font-family: 'Literata', serif;
outline: none;
}
@@ -2300,7 +2577,7 @@ h6 {
.chat-prose pre {
background-color: rgba(0, 0, 0, 0.3);
- border-radius: 8px;
+ border-radius: var(--radius-sm);
padding: 12px 16px;
overflow-x: auto;
margin: 8px 0;
@@ -2314,7 +2591,7 @@ h6 {
}
.chat-prose :not(pre) > code {
- background-color: rgba(145, 164, 210, 0.15);
+ background-color: rgba(139, 92, 246, 0.15);
padding: 2px 6px;
border-radius: 4px;
font-size: 12px;
@@ -2347,13 +2624,13 @@ h6 {
.chat-prose th,
.chat-prose td {
- border: 1px solid var(--border-secondary);
+ border: 1px solid var(--glass-border);
padding: 8px;
text-align: left;
}
.chat-prose th {
- background-color: rgba(145, 164, 210, 0.1);
+ background-color: rgba(139, 92, 246, 0.1);
font-weight: 600;
}
@@ -2365,7 +2642,7 @@ h6 {
.chat-prose h1,
.chat-prose h2,
.chat-prose h3 {
- font-family: 'Space Grotesk', sans-serif;
+ font-family: 'Sora', sans-serif;
margin: 16px 0 8px;
color: var(--text-heading);
}
@@ -2388,14 +2665,16 @@ h6 {
/* ===== Tool Card ===== */
.tool-card {
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
- border-radius: 12px;
+ backdrop-filter: blur(12px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
padding: 24px;
- transition: border-color 0.2s ease;
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.tool-card:hover {
- border-color: var(--accent);
+ border-color: var(--glass-border-bright);
+ box-shadow: var(--shadow-glow);
}
.tool-card-header {
@@ -2417,7 +2696,8 @@ h6 {
}
.tool-status--active {
- background-color: #4ade80;
+ background-color: var(--green);
+ box-shadow: 0 0 6px rgba(52, 211, 153, 0.4);
}
.tool-status--inactive {
@@ -2449,6 +2729,7 @@ h6 {
}
.tool-card-category {
+ font-family: 'Sora', sans-serif;
font-size: 11px;
font-weight: 500;
color: var(--text-faint);
@@ -2463,17 +2744,17 @@ h6 {
font-weight: 600;
border: none;
cursor: pointer;
- font-family: 'Inter', sans-serif;
+ font-family: 'Sora', sans-serif;
transition: all 0.15s ease;
}
.tool-toggle--on {
- background-color: rgba(74, 222, 128, 0.15);
- color: #4ade80;
+ background-color: var(--green-dim);
+ color: var(--green);
}
.tool-toggle--off {
- background-color: var(--bg-surface);
+ background-color: var(--bg-glass);
color: var(--text-faint);
}
@@ -2500,6 +2781,7 @@ h6 {
}
.knowledge-table thead th {
+ font-family: 'Sora', sans-serif;
font-size: 12px;
font-weight: 600;
color: var(--text-faint);
@@ -2507,18 +2789,18 @@ h6 {
letter-spacing: 0.05em;
padding: 12px 16px;
text-align: left;
- border-bottom: 1px solid var(--border-primary);
+ border-bottom: 1px solid var(--glass-border);
}
.knowledge-table tbody td {
font-size: 14px;
color: var(--text-primary);
padding: 14px 16px;
- border-bottom: 1px solid var(--border-primary);
+ border-bottom: 1px solid var(--glass-border);
}
.file-row:hover {
- background-color: rgba(145, 164, 210, 0.04);
+ background-color: rgba(139, 92, 246, 0.04);
}
.file-row-name {
@@ -2547,20 +2829,21 @@ h6 {
max-width: 480px;
padding: 48px 40px;
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
- border-radius: 16px;
+ backdrop-filter: blur(12px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
}
.placeholder-icon {
width: 64px;
height: 64px;
- border-radius: 16px;
- background: linear-gradient(135deg, rgba(145, 164, 210, 0.15), rgba(109, 133, 198, 0.08));
+ border-radius: var(--radius);
+ background: var(--aurora-muted);
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 20px;
- font-family: 'Space Grotesk', sans-serif;
+ font-family: 'Sora', sans-serif;
font-size: 28px;
font-weight: 700;
color: var(--accent);
@@ -2583,11 +2866,12 @@ h6 {
.placeholder-badge {
display: inline-block;
margin-top: 12px;
+ font-family: 'Sora', sans-serif;
font-size: 12px;
font-weight: 600;
color: var(--accent);
padding: 4px 12px;
- border: 1px solid rgba(145, 164, 210, 0.3);
+ border: 1px solid rgba(139, 92, 246, 0.3);
border-radius: 20px;
}
@@ -2606,11 +2890,11 @@ h6 {
justify-content: space-between;
padding: 12px 20px;
background-color: var(--bg-card);
- border-bottom: 1px solid var(--border-primary);
+ border-bottom: 1px solid var(--glass-border);
}
.tool-embed-title {
- font-family: 'Space Grotesk', sans-serif;
+ font-family: 'Sora', sans-serif;
font-size: 16px;
font-weight: 600;
color: var(--text-heading);
@@ -2634,7 +2918,7 @@ h6 {
.tool-embed-popout-btn:hover {
background-color: var(--accent);
- color: var(--bg-body);
+ color: #fff;
}
.tool-embed-iframe {
@@ -2659,12 +2943,13 @@ h6 {
gap: 2px;
padding: 16px;
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
- border-radius: 12px;
+ backdrop-filter: blur(12px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
}
.analytics-stat-value {
- font-family: 'Space Grotesk', sans-serif;
+ font-family: 'Sora', sans-serif;
font-size: 22px;
font-weight: 700;
color: var(--text-heading);
@@ -2681,7 +2966,7 @@ h6 {
}
.analytics-stat-change--up {
- color: #4ade80;
+ color: var(--green);
}
.analytics-stat-change--down {
@@ -2703,20 +2988,22 @@ h6 {
/* ===== Pricing Card ===== */
.pricing-card {
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
- border-radius: 16px;
+ backdrop-filter: blur(12px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
padding: 32px 28px;
text-align: center;
- transition: border-color 0.2s ease, transform 0.2s ease;
+ transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
.pricing-card:hover {
transform: translateY(-2px);
+ box-shadow: var(--shadow-glow);
}
.pricing-card--highlighted {
border-color: var(--accent);
- box-shadow: 0 0 30px rgba(145, 164, 210, 0.1);
+ box-shadow: 0 0 30px rgba(139, 92, 246, 0.1);
position: relative;
}
@@ -2732,7 +3019,7 @@ h6 {
}
.pricing-card-amount {
- font-family: 'Space Grotesk', sans-serif;
+ font-family: 'Sora', sans-serif;
font-size: 40px;
font-weight: 700;
color: var(--text-heading);
@@ -2760,7 +3047,7 @@ h6 {
font-size: 14px;
color: var(--text-muted);
padding: 6px 0;
- border-bottom: 1px solid var(--border-primary);
+ border-bottom: 1px solid var(--glass-border);
}
.pricing-card-features li:last-child {
@@ -2770,19 +3057,21 @@ h6 {
.pricing-card-cta {
width: 100%;
padding: 12px;
- background: linear-gradient(135deg, var(--accent), var(--accent-secondary));
- color: var(--avatar-text);
+ background: var(--aurora);
+ background-size: 200% 200%;
+ color: #fff;
border: none;
- border-radius: 8px;
+ border-radius: var(--radius-sm);
font-size: 14px;
font-weight: 600;
cursor: pointer;
- font-family: 'Inter', sans-serif;
- transition: opacity 0.15s ease;
+ font-family: 'Sora', sans-serif;
+ transition: all 0.3s ease;
}
.pricing-card-cta:hover {
- opacity: 0.9;
+ background-position: 100% 0;
+ box-shadow: 0 4px 24px rgba(139, 92, 246, 0.3);
}
/* ===== Organization Dashboard ===== */
@@ -2804,12 +3093,13 @@ h6 {
gap: 4px;
padding: 20px;
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
- border-radius: 12px;
+ backdrop-filter: blur(12px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
}
.org-stat-value {
- font-family: 'Space Grotesk', sans-serif;
+ font-family: 'Sora', sans-serif;
font-size: 24px;
font-weight: 700;
color: var(--text-heading);
@@ -2820,6 +3110,38 @@ h6 {
color: var(--text-faint);
}
+/* ===== Organization Usage Section ===== */
+.org-section-title {
+ font-size: 18px;
+ font-weight: 700;
+ color: var(--text-heading);
+ margin: 0 0 16px;
+}
+
+.org-usage-loading,
+.org-usage-unavailable {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 24px;
+ margin-bottom: 32px;
+ background-color: var(--bg-card);
+ backdrop-filter: blur(12px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
+ font-size: 14px;
+ color: var(--text-muted);
+}
+
+.org-usage-loading {
+ animation: pulse-fade 1.5s ease-in-out infinite;
+}
+
+@keyframes pulse-fade {
+ 0%, 100% { opacity: 0.6; }
+ 50% { opacity: 1; }
+}
+
/* ===== Organization Table ===== */
.org-table-wrapper {
overflow-x: auto;
@@ -2831,6 +3153,7 @@ h6 {
}
.org-table thead th {
+ font-family: 'Sora', sans-serif;
font-size: 12px;
font-weight: 600;
color: var(--text-faint);
@@ -2838,28 +3161,28 @@ h6 {
letter-spacing: 0.05em;
padding: 12px 16px;
text-align: left;
- border-bottom: 1px solid var(--border-primary);
+ border-bottom: 1px solid var(--glass-border);
}
.org-table tbody td {
font-size: 14px;
color: var(--text-primary);
padding: 14px 16px;
- border-bottom: 1px solid var(--border-primary);
+ border-bottom: 1px solid var(--glass-border);
}
.member-row:hover {
- background-color: rgba(145, 164, 210, 0.04);
+ background-color: rgba(139, 92, 246, 0.04);
}
.member-role-select {
padding: 6px 10px;
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
+ border: 1px solid var(--glass-border);
border-radius: 6px;
color: var(--text-primary);
font-size: 13px;
- font-family: 'Inter', sans-serif;
+ font-family: 'Literata', serif;
outline: none;
}
@@ -2883,8 +3206,9 @@ h6 {
.modal-content {
background-color: var(--bg-card);
- border: 1px solid var(--border-secondary);
- border-radius: 16px;
+ backdrop-filter: blur(20px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
padding: 32px;
min-width: 400px;
max-width: 500px;
@@ -2914,7 +3238,7 @@ h6 {
align-self: flex-start;
max-height: 80vh;
overflow-y: auto;
- border-left: 1px solid var(--border-primary);
+ border-left: 1px solid var(--glass-border);
padding-left: 24px;
display: flex;
flex-direction: column;
@@ -2928,6 +3252,7 @@ h6 {
}
.sidebar-section-title {
+ font-family: 'Sora', sans-serif;
font-size: 12px;
font-weight: 600;
color: var(--text-faint);
@@ -2950,8 +3275,8 @@ h6 {
}
.sidebar-status-dot--online {
- background-color: #4ade80;
- box-shadow: 0 0 6px rgba(74, 222, 128, 0.4);
+ background-color: var(--green);
+ box-shadow: 0 0 6px rgba(52, 211, 153, 0.4);
}
.sidebar-status-dot--offline {
@@ -2973,13 +3298,14 @@ h6 {
.sidebar-model-tag {
display: inline-block;
+ font-family: 'Sora', sans-serif;
font-size: 11px;
font-weight: 500;
padding: 3px 10px;
border-radius: 12px;
- background-color: rgba(145, 164, 210, 0.1);
+ background-color: rgba(139, 92, 246, 0.1);
color: var(--accent);
- border: 1px solid rgba(145, 164, 210, 0.2);
+ border: 1px solid rgba(139, 92, 246, 0.2);
}
.sidebar-topic-link {
@@ -2991,14 +3317,14 @@ h6 {
padding: 6px 10px;
border-radius: 6px;
font-size: 13px;
- font-family: 'Inter', sans-serif;
+ font-family: 'Literata', serif;
color: var(--text-muted);
cursor: pointer;
transition: background-color 0.15s ease, color 0.15s ease;
}
.sidebar-topic-link:hover {
- background-color: rgba(145, 164, 210, 0.08);
+ background-color: rgba(139, 92, 246, 0.08);
color: var(--text-primary);
}
@@ -3077,7 +3403,8 @@ h6 {
height: 56px;
padding: 0 16px;
background-color: var(--bg-sidebar);
- border-bottom: 1px solid var(--border-primary);
+ backdrop-filter: blur(20px);
+ border-bottom: 1px solid var(--glass-border);
}
.mobile-menu-btn {
@@ -3095,14 +3422,17 @@ h6 {
}
.mobile-menu-btn:hover {
- background-color: var(--bg-surface);
+ background-color: var(--bg-glass-hover);
}
.mobile-header-title {
- font-family: 'Space Grotesk', sans-serif;
+ font-family: 'Sora', sans-serif;
font-size: 18px;
font-weight: 700;
- color: var(--text-heading);
+ background: var(--aurora);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
}
/* -- Sidebar: hidden off-screen, slides in as overlay -- */
@@ -3168,7 +3498,7 @@ h6 {
min-width: unset;
max-height: 200px;
border-right: none;
- border-bottom: 1px solid var(--border-primary);
+ border-bottom: 1px solid var(--glass-border);
}
.chat-messages,
@@ -3269,20 +3599,6 @@ h6 {
padding-right: 32px;
}
- /* -- CTA banner -- */
- .cta-banner {
- padding: 32px 20px;
- }
-
- .cta-title {
- font-size: 22px;
- }
-
- .cta-actions {
- flex-direction: column;
- align-items: stretch;
- }
-
/* -- Pricing cards -- */
.pricing-card {
padding: 24px 20px;
@@ -3300,18 +3616,6 @@ h6 {
margin: -64px -12px -16px;
}
- .hero-title {
- font-size: 28px;
- }
-
- .hero-subtitle {
- font-size: 15px;
- }
-
- .section-title {
- font-size: 24px;
- }
-
.page-title {
font-size: 20px;
}
@@ -3332,18 +3636,6 @@ h6 {
padding: 14px;
}
- .social-proof-stats {
- gap: 16px;
- }
-
- .proof-divider {
- display: none;
- }
-
- .proof-stat-value {
- font-size: 20px;
- }
-
.sidebar {
width: 260px;
min-width: 260px;
@@ -3357,23 +3649,6 @@ h6 {
.modal-content {
padding: 20px;
}
-
- .landing-nav-inner {
- padding: 12px 16px;
- }
-
- .features-section,
- .how-it-works-section {
- padding: 48px 16px;
- }
-
- .step-card {
- padding: 24px 16px;
- }
-
- .feature-card {
- padding: 20px 16px;
- }
}
/* ===== Agents Page ===== */
@@ -3402,9 +3677,9 @@ h6 {
width: 48px;
height: 48px;
min-width: 48px;
- background: linear-gradient(135deg, var(--accent), var(--accent-secondary));
- color: var(--avatar-text);
- border-radius: 12px;
+ background: var(--aurora);
+ color: #fff;
+ border-radius: var(--radius);
font-size: 24px;
display: flex;
align-items: center;
@@ -3413,7 +3688,7 @@ h6 {
}
.agents-hero-title {
- font-family: 'Space Grotesk', sans-serif;
+ font-family: 'Sora', sans-serif;
font-size: 28px;
font-weight: 700;
color: var(--text-heading);
@@ -3444,7 +3719,8 @@ h6 {
}
.agents-status-dot--on {
- background-color: #22c55e;
+ background-color: var(--green);
+ box-shadow: 0 0 6px rgba(52, 211, 153, 0.4);
}
.agents-status-dot--off {
@@ -3480,25 +3756,27 @@ h6 {
display: block;
text-decoration: none;
background-color: var(--bg-card);
- border: 1px solid var(--border-primary);
- border-radius: 12px;
+ backdrop-filter: blur(12px);
+ border: 1px solid var(--glass-border);
+ border-radius: var(--radius);
padding: 24px;
- transition: border-color 0.2s, transform 0.2s;
+ transition: border-color 0.2s, transform 0.2s, box-shadow 0.2s;
cursor: pointer;
}
.agents-card:hover {
- border-color: var(--accent);
+ border-color: var(--glass-border-bright);
transform: translateY(-2px);
+ box-shadow: var(--shadow-glow);
}
.agents-card-icon {
width: 36px;
height: 36px;
min-width: 36px;
- background: linear-gradient(135deg, var(--accent), var(--accent-secondary));
- color: var(--avatar-text);
- border-radius: 8px;
+ background: var(--aurora);
+ color: #fff;
+ border-radius: var(--radius-sm);
font-size: 18px;
display: flex;
align-items: center;
@@ -3541,6 +3819,7 @@ h6 {
}
.agents-table thead th {
+ font-family: 'Sora', sans-serif;
text-align: left;
font-size: 12px;
font-weight: 600;
@@ -3548,18 +3827,18 @@ h6 {
text-transform: uppercase;
letter-spacing: 0.04em;
padding: 8px 12px;
- border-bottom: 1px solid var(--border-secondary);
+ border-bottom: 1px solid var(--glass-border);
}
.agents-table tbody td {
padding: 10px 12px;
- border-bottom: 1px solid var(--border-primary);
+ border-bottom: 1px solid var(--glass-border);
color: var(--text-primary);
vertical-align: middle;
}
.agents-table tbody tr:hover {
- background-color: var(--bg-surface);
+ background-color: var(--bg-glass-hover);
}
.agents-cell-name {
@@ -3588,6 +3867,7 @@ h6 {
.agents-badge {
display: inline-block;
+ font-family: 'Sora', sans-serif;
font-size: 12px;
font-weight: 600;
padding: 2px 10px;
@@ -3595,8 +3875,8 @@ h6 {
}
.agents-badge--active {
- background-color: rgba(34, 197, 94, 0.15);
- color: #22c55e;
+ background-color: var(--green-dim);
+ color: var(--green);
}
.agents-table-loading,
@@ -3650,9 +3930,9 @@ h6 {
width: 48px;
height: 48px;
min-width: 48px;
- background: linear-gradient(135deg, var(--accent), var(--accent-secondary));
- color: var(--avatar-text);
- border-radius: 12px;
+ background: var(--aurora);
+ color: #fff;
+ border-radius: var(--radius);
font-size: 24px;
display: flex;
align-items: center;
@@ -3660,7 +3940,7 @@ h6 {
}
.analytics-hero-title {
- font-family: 'Space Grotesk', sans-serif;
+ font-family: 'Sora', sans-serif;
font-size: 28px;
font-weight: 700;
color: var(--text-heading);
@@ -3687,19 +3967,21 @@ h6 {
align-items: center;
gap: 8px;
padding: 10px 20px;
- background: linear-gradient(135deg, var(--accent), var(--accent-secondary));
- color: var(--avatar-text);
+ background: var(--aurora);
+ background-size: 200% 200%;
+ color: #fff;
font-size: 14px;
font-weight: 600;
- border-radius: 8px;
+ border-radius: var(--radius-sm);
text-decoration: none;
- transition: opacity 0.2s, transform 0.2s;
+ transition: all 0.3s;
width: fit-content;
}
.analytics-launch-btn:hover {
- opacity: 0.9;
+ background-position: 100% 0;
transform: translateY(-1px);
+ box-shadow: 0 4px 24px rgba(139, 92, 246, 0.3);
}
.analytics-stats-bar {
@@ -3712,4 +3994,10 @@ h6 {
.analytics-stats-bar {
flex-direction: column;
}
-}
\ No newline at end of file
+}
+
+/* ===== Animations ===== */
+@keyframes fadeUp {
+ from { opacity: 0; transform: translateY(20px); }
+ to { opacity: 1; transform: translateY(0); }
+}
diff --git a/assets/tailwind.css b/assets/tailwind.css
index 89ec9cf..f196a26 100644
--- a/assets/tailwind.css
+++ b/assets/tailwind.css
@@ -9,6 +9,15 @@
"Courier New", monospace;
--color-black: #000;
--spacing: 0.25rem;
+ --radius-sm: 0.25rem;
+ --radius-md: 0.375rem;
+ --radius-lg: 0.5rem;
+ --radius-xl: 0.75rem;
+ --shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
+ --default-transition-duration: 150ms;
+ --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
--default-font-family: var(--font-sans);
--default-mono-font-family: var(--font-mono);
}
@@ -1633,6 +1642,14 @@
}
}
}
+ .stat-value {
+ @layer daisyui.l1.l2.l3 {
+ grid-column-start: 1;
+ white-space: nowrap;
+ font-size: 2rem;
+ font-weight: 800;
+ }
+ }
.container {
width: 100%;
@media (width >= 40rem) {
@@ -1818,6 +1835,23 @@
}
}
}
+ .stat {
+ @layer daisyui.l1.l2.l3 {
+ display: inline-grid;
+ width: 100%;
+ column-gap: calc(0.25rem * 4);
+ padding-inline: calc(0.25rem * 6);
+ padding-block: calc(0.25rem * 4);
+ grid-template-columns: repeat(1, 1fr);
+ &:not(:last-child) {
+ border-inline-end: var(--border) dashed currentColor;
+ @supports (color: color-mix(in lab, red, red)) {
+ border-inline-end: var(--border) dashed color-mix(in oklab, currentColor 10%, #0000);
+ }
+ border-block-end: none;
+ }
+ }
+ }
.chat {
@layer daisyui.l1.l2.l3 {
display: grid;
@@ -1836,6 +1870,9 @@
font-weight: 600;
}
}
+ .flex {
+ display: flex;
+ }
.grid {
display: grid;
}
@@ -1848,6 +1885,9 @@
.table {
display: table;
}
+ .border-collapse {
+ border-collapse: collapse;
+ }
.transform {
transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);
}
@@ -1869,13 +1909,12 @@
}
}
}
- .badge-outline {
- @layer daisyui.l1.l2 {
- color: var(--badge-color);
- --badge-bg: #0000;
- background-image: none;
- border-color: currentColor;
- }
+ .flex-wrap {
+ flex-wrap: wrap;
+ }
+ .border {
+ border-style: var(--tw-border-style);
+ border-width: 1px;
}
.glass {
border: none;
@@ -1894,10 +1933,6 @@
.lowercase {
text-transform: lowercase;
}
- .outline {
- outline-style: var(--tw-outline-style);
- outline-width: 1px;
- }
.btn-ghost {
@layer daisyui.l1 {
&:not(.btn-active, :hover, :active:focus, :focus-visible, input:checked:not(.filter .btn)) {
@@ -1925,6 +1960,15 @@
.filter {
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
}
+ .backdrop-filter {
+ -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
+ backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
+ }
+ .transition {
+ transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;
+ transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
+ transition-duration: var(--tw-duration, var(--default-transition-duration));
+ }
.btn-outline {
@layer daisyui.l1 {
&:not( .btn-active, :hover, :active:focus, :focus-visible, input:checked:not(.filter .btn), :disabled, [disabled], .btn-disabled ) {
@@ -2339,7 +2383,7 @@
syntax: "*";
inherits: false;
}
-@property --tw-outline-style {
+@property --tw-border-style {
syntax: "*";
inherits: false;
initial-value: solid;
@@ -2397,6 +2441,42 @@
syntax: "*";
inherits: false;
}
+@property --tw-backdrop-blur {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-brightness {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-contrast {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-grayscale {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-hue-rotate {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-invert {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-opacity {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-saturate {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-backdrop-sepia {
+ syntax: "*";
+ inherits: false;
+}
@layer properties {
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
*, ::before, ::after, ::backdrop {
@@ -2405,7 +2485,7 @@
--tw-rotate-z: initial;
--tw-skew-x: initial;
--tw-skew-y: initial;
- --tw-outline-style: solid;
+ --tw-border-style: solid;
--tw-blur: initial;
--tw-brightness: initial;
--tw-contrast: initial;
@@ -2419,6 +2499,15 @@
--tw-drop-shadow-color: initial;
--tw-drop-shadow-alpha: 100%;
--tw-drop-shadow-size: initial;
+ --tw-backdrop-blur: initial;
+ --tw-backdrop-brightness: initial;
+ --tw-backdrop-contrast: initial;
+ --tw-backdrop-grayscale: initial;
+ --tw-backdrop-hue-rotate: initial;
+ --tw-backdrop-invert: initial;
+ --tw-backdrop-opacity: initial;
+ --tw-backdrop-saturate: initial;
+ --tw-backdrop-sepia: initial;
}
}
}
diff --git a/design-templates/01-nordic-frost.html b/design-templates/01-nordic-frost.html
new file mode 100644
index 0000000..2405370
--- /dev/null
+++ b/design-templates/01-nordic-frost.html
@@ -0,0 +1,907 @@
+
+
+
+
+
+CERTifAI - Template 1: Nordic Frost
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ● GDPR-Compliant · 100% On-Premise
+ Your AI infrastructure,
your rules.
+ Self-hosted generative AI for companies that refuse to compromise on data sovereignty. Deploy, configure, and scale without leaving the EU.
+
+
+
+
+
+
+
+
+
+
+
⚑
+ EU Data Residency
+
+
+
∅
+ Zero Third-Party Access
+
+
+
+
+
+
+
+
⚙
+
Self-Hosted Infrastructure
+
Deploy on your hardware or private cloud. No data ever leaves your perimeter.
+
+
+
☍
+
Multi-LLM Gateway
+
Route between providers through a single API. LiteLLM proxy with full observability.
+
+
+
❖
+
Agent Orchestration
+
Build and manage LangGraph agents with visual workflows and real-time monitoring.
+
+
+
⏻
+
SSO & Identity
+
Keycloak-powered authentication. Connect your existing LDAP or SAML provider.
+
+
+
☰
+
Full Observability
+
Langfuse integration for traces, cost tracking, and prompt engineering analytics.
+
+
+
➔
+
API-First Design
+
RESTful endpoints, API key management, and MCP server support built in.
+
+
+
+
+
+
+
Ready to take control?
+
Deploy your private AI infrastructure in under 30 minutes. No credit card required.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Total Spend
+
$47.82
+
+12% this month
+
+
+
Total Tokens
+
847K
+
of 1M limit
+
+
+
Active Models
+
5
+
LiteLLM Online
+
+
+
Team Members
+
4/25
+
Seats used
+
+
+
+
+
+
+ Usage by Model
+ This Month
+
+
+
+
+ | Model |
+ Tokens |
+ Spend |
+ Status |
+
+
+
+
+ | Qwen3-Coder-30B |
+ 342K |
+ $18.40 |
+ Active |
+
+
+ | Llama-3.1-70B |
+ 285K |
+ $15.20 |
+ Active |
+
+
+ | Mistral-7B |
+ 120K |
+ $8.42 |
+ Active |
+
+
+ | Gemma-2-9B |
+ 65K |
+ $3.80 |
+ Active |
+
+
+ | Phi-3-mini |
+ 35K |
+ $2.00 |
+ Idle |
+
+
+
+
+
+
+
Team
+
+
MM
+
+
Max Mustermann
+
max@company.de
+
+
Admin
+
+
+
EM
+
+
Erika Musterfrau
+
erika@company.de
+
+
Member
+
+
+
JS
+
+
Johann Schmidt
+
johann@company.de
+
+
Member
+
+
+
AW
+
+
Anna Weber
+
anna@company.de
+
+
Viewer
+
+
+
+
+
+
+
+
+
+
diff --git a/design-templates/02-cyber-command.html b/design-templates/02-cyber-command.html
new file mode 100644
index 0000000..5100a1b
--- /dev/null
+++ b/design-templates/02-cyber-command.html
@@ -0,0 +1,942 @@
+
+
+
+
+
+CERTifAI - Template 2: Cyber Command
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ // SELF-HOSTED · GDPR NATIVE · ZERO TRUST
+ Private AI
Command Center
+ Deploy sovereign AI infrastructure that never phones home. Route LLMs, orchestrate agents, track every token—all inside your perimeter.
+
+
+
+
+
+
+
+
+
+
+
certifai-cli — deploy
+
+
+
+ $ certifai deploy --region eu-west-1 --gpu a100
+ ✓ Keycloak SSO configured
+ ✓ LiteLLM proxy ready (5 models loaded)
+ ✓ LangGraph agents online
+ ✓ Langfuse observability active
+
+ $ certifai status
+ All systems operational. Uptime: 99.97%
+
+
+
+
+
+
+
+
+
+
+
01
+
LLM Gateway
+
LiteLLM proxy routes requests across providers. One API, full model flexibility, zero vendor lock-in.
+
+
+
02
+
Agent Orchestration
+
LangGraph + LangFlow for building, deploying, and monitoring autonomous agent workflows.
+
+
+
03
+
Full Observability
+
Langfuse tracing, cost attribution, prompt versioning. Know exactly what your AI is doing.
+
+
+
04
+
Identity & Access
+
Keycloak SSO with SAML, OIDC, LDAP. Fine-grained RBAC across all services.
+
+
+
05
+
MCP Servers
+
Model Context Protocol support for tool-augmented AI with secure function calling.
+
+
+
06
+
API-First
+
REST endpoints, API key rotation, webhook events. Integrate CERTifAI into your existing stack.
+
+
+
+
+
+
+
Your cluster. Your models. Your rules.
+
Spin up a fully operational AI stack in under 30 minutes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Total Spend
+
$47.82
+
+12.4% vs last month
+
+
+
Tokens Processed
+
847K
+
of 1M monthly cap
+
+
+
Active Models
+
5
+
LiteLLM proxy online
+
+
+
Team Seats
+
4/25
+
21 available
+
+
+
+
+
+
+ Model Usage
+ LIVE
+
+
+
+ | Model | Tokens | Spend | Status |
+
+
+ | Qwen3-Coder-30B | 342K | $18.40 | Active |
+ | Llama-3.1-70B | 285K | $15.20 | Active |
+ | Mistral-7B | 120K | $8.42 | Active |
+ | Gemma-2-9B | 65K | $3.80 | Active |
+ | Phi-3-mini | 35K | $2.00 | Idle |
+
+
+
+
+
+
Activity Log
+
+ 2m ago
+ Erika M. queried Qwen3-Coder
+
+
+ 8m ago
+ Johann S. deployed agent doc-parser
+
+
+ 14m ago
+ Anna W. viewed analytics trace
+
+
+ 31m ago
+ Max M. rotated API key for LiteLLM
+
+
+ 1h ago
+ System: Llama-3.1-70B model health check passed
+
+
+
+
+
+
+
+
+
+
diff --git a/design-templates/03-warm-studio.html b/design-templates/03-warm-studio.html
new file mode 100644
index 0000000..e722f89
--- /dev/null
+++ b/design-templates/03-warm-studio.html
@@ -0,0 +1,963 @@
+
+
+
+
+
+CERTifAI - Template 3: Warm Studio
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Private AI Infrastructure
+
AI that stays in-house
+
A friendly, powerful dashboard for managing your self-hosted GenAI tools. No data leaves your servers. No compromises on capability.
+
+
+
+
+
+
+
5 models live
+
+
+
+
Token usage this month
+
847,000
+
+
+
+ Qwen3-Coder
+ Llama 3.1
+ Mistral
+ Gemma 2
+
+
+
+
+
+
+
+
+
+
+
+
⚙
+
Self-Hosted Infrastructure
+
Your hardware, your cloud, your rules. Deploy with a single command.
+
+
+
☍
+
Multi-Model Gateway
+
One API for all your models. Switch providers without changing a line of code.
+
+
+
❖
+
Visual Agent Builder
+
Drag-and-drop workflows for building AI agents that actually work.
+
+
+
⏻
+
Single Sign-On
+
Connect your existing identity provider. One login for everything.
+
+
+
☰
+
Usage Analytics
+
Track every token, every dollar, every model. Full transparency.
+
+
+
➔
+
API & Integrations
+
REST APIs, webhooks, and MCP server support out of the box.
+
+
+
+
+
+
+
Let's get you set up
+
No credit card. No sales call. Just your AI infrastructure, ready in minutes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
February Overview
+
Your team used 847K tokens across 5 models this month.
+
+
+
+
+
+
+
Active Models
+
5
+
All healthy
+
+
+
Agents Running
+
3
+
2 idle
+
+
+
Billing Cycle Ends
+
Mar 1
+
3 days left
+
+
+
+
+
+
Usage by Model
+
+
+ | Model | Tokens | Spend |
+
+
+ | Qwen3-Coder-30B | 342K | $18.40 |
+ | Llama-3.1-70B | 285K | $15.20 |
+ | Mistral-7B | 120K | $8.42 |
+ | Gemma-2-9B | 65K | $3.80 |
+ | Phi-3-mini | 35K | $2.00 |
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/design-templates/04-glass-aurora.html b/design-templates/04-glass-aurora.html
new file mode 100644
index 0000000..7321423
--- /dev/null
+++ b/design-templates/04-glass-aurora.html
@@ -0,0 +1,963 @@
+
+
+
+
+
+CERTifAI - Template 4: Glass Aurora
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GDPR Native
+ Self-Hosted
+ EU Sovereign
+
+ Sovereign AI
infrastructure
+ The complete platform for deploying, managing, and scaling private generative AI. Your data never leaves your perimeter.
+
+
+
+
+
+
+
+
+
+
847K
+
Tokens / Month
+
+
+
+
+
+
+
+
+
+
+
+
+
+
LLM Gateway
+
Route between any model through a unified API. LiteLLM proxy with full cost tracking.
+
+
+
+
Agent Platform
+
Build and deploy LangGraph agents with visual workflows and real-time monitoring.
+
+
+
+
Observability
+
Langfuse integration for traces, prompt engineering, and cost attribution.
+
+
+
+
Identity & SSO
+
Keycloak-powered auth with SAML, OIDC, and LDAP. One login across services.
+
+
+
+
MCP Servers
+
Model Context Protocol for secure, tool-augmented AI with function calling.
+
+
+
+
API-First
+
REST endpoints, API keys, webhooks. Plug CERTifAI into your existing stack.
+
+
+
+
+
+
+
Deploy in 30 minutes
+
No credit card required. Full access to every feature.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
February 2026
+
Your infrastructure is healthy. All models are responding.
+
+
+
+
+
+
+
Active Models
+
5
+
All responding
+
+
+
Team Seats
+
4/25
+
21 available
+
+
+
Running Agents
+
3
+
via LangGraph
+
+
+
Cycle Ends
+
Mar 1
+
3 days left
+
+
+
+
+
+
+
+
+ | Model | Tokens | Spend | Status |
+
+
+ | Qwen3-Coder-30B | 342K | $18.40 | Active |
+ | Llama-3.1-70B | 285K | $15.20 | Active |
+ | Mistral-7B | 120K | $8.42 | Active |
+ | Gemma-2-9B | 65K | $3.80 | Active |
+ | Phi-3-mini | 35K | $2.00 | Idle |
+
+
+
+
+
+
+
+
+
LiteLLM Proxy
+
llm-dev.meghsakha.com
+
+
Online
+
+
+
+
LangGraph
+
agents.internal
+
+
Online
+
+
+
+
Langfuse
+
analytics.internal
+
+
Online
+
+
+
+
+
+
+
+
+
+
+
diff --git a/design-templates/05-swiss-grid.html b/design-templates/05-swiss-grid.html
new file mode 100644
index 0000000..5d60840
--- /dev/null
+++ b/design-templates/05-swiss-grid.html
@@ -0,0 +1,928 @@
+
+
+
+
+
+CERTifAI - Template 5: Swiss Grid
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Private AI Infrastructure
+
AI that answers
only to you.
+
Sovereign generative AI infrastructure for organizations that treat data protection as non-negotiable. Deploy on your terms, inside your perimeter.
+
+
+
+
+
+
+
+
100%
+
On-premise deployment. No data egress.
+
+
+
GDPR
+
Article 28 compliant by architecture.
+
+
+
<30min
+
Full deployment including SSO and models.
+
+
+
+
+
+
+
01
+
Data Sovereignty
+
Your data never leaves your infrastructure. No telemetry, no third-party calls.
+
+
+
02
+
Full Control
+
Choose your models, set your policies, define your access rules.
+
+
+
03
+
Transparency
+
Every token tracked, every cost attributed, every trace logged.
+
+
+
04
+
EU-Native
+
Designed in Germany for EU compliance. No US-dependent services.
+
+
+
+
+
+
+
+
ROUTING
+
LLM Gateway
+
LiteLLM proxy for unified multi-provider access through a single endpoint.
+
+
+
ORCHESTRATION
+
Agent Platform
+
LangGraph for autonomous agents. LangFlow for visual workflow design.
+
+
+
OBSERVABILITY
+
Analytics
+
Langfuse integration for tracing, cost tracking, and prompt versioning.
+
+
+
IDENTITY
+
SSO & RBAC
+
Keycloak with SAML, OIDC, LDAP. Fine-grained role-based access control.
+
+
+
INTEGRATION
+
MCP & APIs
+
Model Context Protocol servers and REST APIs for tool-augmented AI.
+
+
+
MANAGEMENT
+
Admin Dashboard
+
Billing, team management, usage monitoring, and system configuration.
+
+
+
+
+
+
+
+
Ready to deploy?
+
Full operational AI stack. Under 30 minutes. No external dependencies.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Total Spend
+
$47.82
+
+
+
+
+
+
+
+
+
+
+
+
+ | Model | Tokens | Spend | Status |
+
+
+
+ | Qwen3-Coder-30B |
+ 342,000 |
+ $18.40 |
+ Active |
+
+
+ | Llama-3.1-70B |
+ 285,000 |
+ $15.20 |
+ Active |
+
+
+ | Mistral-7B |
+ 120,000 |
+ $8.42 |
+ Active |
+
+
+ | Gemma-2-9B |
+ 65,000 |
+ $3.80 |
+ Active |
+
+
+ | Phi-3-mini |
+ 35,000 |
+ $2.00 |
+ Idle |
+
+
+
+
+
+
+
+
+
MM
+
+
Max Mustermann
+
max@company.de
+
+
Admin
+
+
+
EM
+
+
Erika Musterfrau
+
erika@company.de
+
+
Member
+
+
+
JS
+
+
Johann Schmidt
+
johann@company.de
+
+
Member
+
+
+
AW
+
+
Anna Weber
+
anna@company.de
+
+
Viewer
+
+
+
+
+
+
+
+
+
+
diff --git a/design-templates/screenshots/01-nordic-frost-dashboard.png b/design-templates/screenshots/01-nordic-frost-dashboard.png
new file mode 100644
index 0000000..5413c79
Binary files /dev/null and b/design-templates/screenshots/01-nordic-frost-dashboard.png differ
diff --git a/design-templates/screenshots/01-nordic-frost-landing.png b/design-templates/screenshots/01-nordic-frost-landing.png
new file mode 100644
index 0000000..fbb34b5
Binary files /dev/null and b/design-templates/screenshots/01-nordic-frost-landing.png differ
diff --git a/design-templates/screenshots/02-cyber-command-dashboard.png b/design-templates/screenshots/02-cyber-command-dashboard.png
new file mode 100644
index 0000000..80745eb
Binary files /dev/null and b/design-templates/screenshots/02-cyber-command-dashboard.png differ
diff --git a/design-templates/screenshots/02-cyber-command-landing.png b/design-templates/screenshots/02-cyber-command-landing.png
new file mode 100644
index 0000000..39c53b6
Binary files /dev/null and b/design-templates/screenshots/02-cyber-command-landing.png differ
diff --git a/design-templates/screenshots/03-warm-studio-dashboard.png b/design-templates/screenshots/03-warm-studio-dashboard.png
new file mode 100644
index 0000000..3afe1d5
Binary files /dev/null and b/design-templates/screenshots/03-warm-studio-dashboard.png differ
diff --git a/design-templates/screenshots/03-warm-studio-landing.png b/design-templates/screenshots/03-warm-studio-landing.png
new file mode 100644
index 0000000..735bf82
Binary files /dev/null and b/design-templates/screenshots/03-warm-studio-landing.png differ
diff --git a/design-templates/screenshots/04-glass-aurora-dashboard.png b/design-templates/screenshots/04-glass-aurora-dashboard.png
new file mode 100644
index 0000000..bf12cf9
Binary files /dev/null and b/design-templates/screenshots/04-glass-aurora-dashboard.png differ
diff --git a/design-templates/screenshots/04-glass-aurora-landing.png b/design-templates/screenshots/04-glass-aurora-landing.png
new file mode 100644
index 0000000..ae68f42
Binary files /dev/null and b/design-templates/screenshots/04-glass-aurora-landing.png differ
diff --git a/design-templates/screenshots/05-swiss-grid-dashboard.png b/design-templates/screenshots/05-swiss-grid-dashboard.png
new file mode 100644
index 0000000..93d6d76
Binary files /dev/null and b/design-templates/screenshots/05-swiss-grid-dashboard.png differ
diff --git a/design-templates/screenshots/05-swiss-grid-landing.png b/design-templates/screenshots/05-swiss-grid-landing.png
new file mode 100644
index 0000000..97b9741
Binary files /dev/null and b/design-templates/screenshots/05-swiss-grid-landing.png differ
diff --git a/src/app.rs b/src/app.rs
index 8bce752..601c3e2 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -49,10 +49,10 @@ const MAIN_CSS: Asset = asset!("/assets/main.css");
const TAILWIND_CSS: Asset = asset!("/assets/tailwind.css");
const MANIFEST: Asset = asset!("/assets/manifest.json");
-/// Google Fonts URL for Inter (body) and Space Grotesk (headings).
+/// Google Fonts URL for Literata (body) and Sora (headings).
const GOOGLE_FONTS: &str = "https://fonts.googleapis.com/css2?\
- family=Inter:wght@400;500;600&\
- family=Space+Grotesk:wght@500;600;700&\
+ family=Sora:wght@300;400;500;600;700;800&\
+ family=Literata:ital,opsz,wght@0,7..72,400;0,7..72,500;0,7..72,600;0,7..72,700;1,7..72,400&\
display=swap";
/// Root application component. Loads global assets and mounts the router.
@@ -85,14 +85,14 @@ pub fn App() -> Element {
src: "https://seggwat.com/static/widgets/v1/seggwat-feedback.js",
r#defer: true,
"data-project-key": "a04b8cf1-9177-42ce-8a7b-084f38b99799",
- "data-button-color": "#6d85c6",
+ "data-button-color": "#8b5cf6",
"data-button-position": "right-side",
"data-enable-screenshots": "true",
}
document::Link { rel: "icon", href: FAVICON }
document::Link { rel: "manifest", href: MANIFEST }
- document::Meta { name: "theme-color", content: "#4B3FE0" }
+ document::Meta { name: "theme-color", content: "#0c0a1d" }
document::Meta { name: "apple-mobile-web-app-capable", content: "yes" }
document::Meta {
name: "apple-mobile-web-app-status-bar-style",
diff --git a/src/pages/landing.rs b/src/pages/landing.rs
index fc56259..d9c0706 100644
--- a/src/pages/landing.rs
+++ b/src/pages/landing.rs
@@ -1,8 +1,5 @@
use dioxus::prelude::*;
-use dioxus_free_icons::icons::bs_icons::{
- BsArrowRight, BsGlobe2, BsKey, BsRobot, BsServer, BsShieldCheck,
-};
-use dioxus_free_icons::icons::fa_solid_icons::FaCubes;
+use dioxus_free_icons::icons::bs_icons::{BsArrowRight, BsShieldCheck};
use dioxus_free_icons::Icon;
use crate::i18n::{t, Locale};
@@ -12,14 +9,15 @@ use crate::Route;
///
/// Displays a marketing-oriented page with hero section, feature grid,
/// how-it-works steps, and call-to-action banners. This page is accessible
-/// without authentication.
+/// without authentication. Uses the Glass Aurora design with glassmorphic
+/// effects, aurora gradients, and centered hero layout.
#[component]
pub fn LandingPage() -> Element {
rsx! {
div { class: "landing",
LandingNav {}
HeroSection {}
- SocialProof {}
+ TrustBar {}
FeaturesGrid {}
HowItWorks {}
CtaBanner {}
@@ -29,6 +27,7 @@ pub fn LandingPage() -> Element {
}
/// Sticky top navigation bar with logo, nav links, and CTA buttons.
+/// Uses Glass Aurora glassmorphic nav with backdrop-filter blur.
#[component]
fn LandingNav() -> Element {
let locale = use_context::>();
@@ -69,7 +68,8 @@ fn LandingNav() -> Element {
}
}
-/// Hero section with headline, subtitle, and CTA buttons.
+/// Hero section with pill badges, headline, subtitle, CTA buttons, and
+/// a glass-preview stat panel. Centered layout per Glass Aurora design.
#[component]
fn HeroSection() -> Element {
let locale = use_context::>();
@@ -78,7 +78,11 @@ fn HeroSection() -> Element {
rsx! {
section { class: "hero-section",
div { class: "hero-content",
- div { class: "hero-badge badge badge-outline", {t(l, "landing.badge")} }
+ div { class: "hero-pills",
+ span { class: "pill accent", {t(l, "landing.pill_gdpr")} }
+ span { class: "pill", {t(l, "landing.pill_self_hosted")} }
+ span { class: "pill", {t(l, "landing.pill_eu")} }
+ }
h1 { class: "hero-title",
{t(l, "landing.hero_title_1")}
br {}
@@ -100,176 +104,26 @@ fn HeroSection() -> Element {
{t(l, "landing.learn_more")}
}
}
- }
- div { class: "hero-graphic",
- // Abstract shield/network SVG motif
- svg {
- view_box: "0 0 400 400",
- fill: "none",
- width: "100%",
- height: "100%",
- // Gradient definitions
- defs {
- linearGradient {
- id: "grad1",
- x1: "0%",
- y1: "0%",
- x2: "100%",
- y2: "100%",
- stop { offset: "0%", stop_color: "#91a4d2" }
- stop { offset: "100%", stop_color: "#6d85c6" }
- }
- linearGradient {
- id: "grad2",
- x1: "0%",
- y1: "100%",
- x2: "100%",
- y2: "0%",
- stop { offset: "0%", stop_color: "#f97066" }
- stop { offset: "100%", stop_color: "#f9a066" }
- }
- radialGradient {
- id: "glow",
- cx: "50%",
- cy: "50%",
- r: "50%",
- stop {
- offset: "0%",
- stop_color: "rgba(145,164,210,0.3)",
- }
- stop {
- offset: "100%",
- stop_color: "rgba(145,164,210,0)",
+ div { class: "preview-container",
+ div { class: "glass-preview",
+ div { class: "preview-stat",
+ div { class: "preview-stat-value", "5" }
+ div { class: "preview-stat-label",
+ {t(l, "landing.preview_models")}
+ }
+ }
+ div { class: "preview-stat",
+ div { class: "preview-stat-value", "847K" }
+ div { class: "preview-stat-label",
+ {t(l, "landing.preview_tokens")}
+ }
+ }
+ div { class: "preview-stat",
+ div { class: "preview-stat-value", "$47.82" }
+ div { class: "preview-stat-label",
+ {t(l, "landing.preview_spend")}
}
}
- }
- // Background glow
- circle {
- cx: "200",
- cy: "200",
- r: "180",
- fill: "url(#glow)",
- }
- // Shield outline
- path {
- d: "M200 40 L340 110 L340 230 C340 300 270 360 200 380 \
- C130 360 60 300 60 230 L60 110 Z",
- stroke: "url(#grad1)",
- stroke_width: "2",
- fill: "none",
- opacity: "0.6",
- }
- // Inner shield
- path {
- d: "M200 80 L310 135 L310 225 C310 280 255 330 200 345 \
- C145 330 90 280 90 225 L90 135 Z",
- stroke: "url(#grad1)",
- stroke_width: "1.5",
- fill: "rgba(145,164,210,0.05)",
- opacity: "0.8",
- }
- // Network nodes
- circle {
- cx: "200",
- cy: "180",
- r: "8",
- fill: "url(#grad1)",
- }
- circle {
- cx: "150",
- cy: "230",
- r: "6",
- fill: "url(#grad2)",
- }
- circle {
- cx: "250",
- cy: "230",
- r: "6",
- fill: "url(#grad2)",
- }
- circle {
- cx: "200",
- cy: "280",
- r: "6",
- fill: "url(#grad1)",
- }
- circle {
- cx: "130",
- cy: "170",
- r: "4",
- fill: "#91a4d2",
- opacity: "0.6",
- }
- circle {
- cx: "270",
- cy: "170",
- r: "4",
- fill: "#91a4d2",
- opacity: "0.6",
- }
- // Network connections
- line {
- x1: "200",
- y1: "180",
- x2: "150",
- y2: "230",
- stroke: "#91a4d2",
- stroke_width: "1",
- opacity: "0.4",
- }
- line {
- x1: "200",
- y1: "180",
- x2: "250",
- y2: "230",
- stroke: "#91a4d2",
- stroke_width: "1",
- opacity: "0.4",
- }
- line {
- x1: "150",
- y1: "230",
- x2: "200",
- y2: "280",
- stroke: "#91a4d2",
- stroke_width: "1",
- opacity: "0.4",
- }
- line {
- x1: "250",
- y1: "230",
- x2: "200",
- y2: "280",
- stroke: "#91a4d2",
- stroke_width: "1",
- opacity: "0.4",
- }
- line {
- x1: "200",
- y1: "180",
- x2: "130",
- y2: "170",
- stroke: "#91a4d2",
- stroke_width: "1",
- opacity: "0.3",
- }
- line {
- x1: "200",
- y1: "180",
- x2: "270",
- y2: "170",
- stroke: "#91a4d2",
- stroke_width: "1",
- opacity: "0.3",
- }
- // Checkmark inside shield center
- path {
- d: "M180 200 L195 215 L225 185",
- stroke: "url(#grad1)",
- stroke_width: "3",
- stroke_linecap: "round",
- stroke_linejoin: "round",
- fill: "none",
}
}
}
@@ -277,44 +131,36 @@ fn HeroSection() -> Element {
}
}
-/// Social proof / trust indicator strip.
+/// Trust bar with aurora dot indicators and stat labels.
+/// Replaces the previous text-based social proof section.
#[component]
-fn SocialProof() -> Element {
+fn TrustBar() -> Element {
let locale = use_context::>();
let l = *locale.read();
rsx! {
- section { class: "social-proof",
- p { class: "social-proof-text",
- {t(l, "landing.social_proof")}
- span { class: "social-proof-highlight", {t(l, "landing.data_sovereignty")} }
+ section { class: "trust-bar",
+ div { class: "trust-item",
+ div { class: "trust-dot" }
+ span { "100% " {t(l, "landing.on_premise")} }
}
- div { class: "social-proof-stats",
- div { class: "proof-stat",
- span { class: "proof-stat-value", "100%" }
- span { class: "proof-stat-label", {t(l, "landing.on_premise")} }
- }
- div { class: "proof-divider" }
- div { class: "proof-stat",
- span { class: "proof-stat-value", "GDPR" }
- span { class: "proof-stat-label", {t(l, "landing.compliant")} }
- }
- div { class: "proof-divider" }
- div { class: "proof-stat",
- span { class: "proof-stat-value", "EU" }
- span { class: "proof-stat-label", {t(l, "landing.data_residency")} }
- }
- div { class: "proof-divider" }
- div { class: "proof-stat",
- span { class: "proof-stat-value", "Zero" }
- span { class: "proof-stat-label", {t(l, "landing.third_party")} }
- }
+ div { class: "trust-item",
+ div { class: "trust-dot" }
+ span { "GDPR " {t(l, "landing.compliant")} }
+ }
+ div { class: "trust-item",
+ div { class: "trust-dot" }
+ span { "EU " {t(l, "landing.data_residency")} }
+ }
+ div { class: "trust-item",
+ div { class: "trust-dot" }
+ span { "Zero " {t(l, "landing.third_party")} }
}
}
}
}
-/// Feature cards grid section.
+/// Feature cards grid section. Uses gradient icon bars instead of SVG icons.
#[component]
fn FeaturesGrid() -> Element {
let locale = use_context::>();
@@ -328,44 +174,26 @@ fn FeaturesGrid() -> Element {
}
div { class: "features-grid",
FeatureCard {
- icon: rsx! {
- Icon { icon: BsServer, width: 28, height: 28 }
- },
title: t(l, "landing.feat_infra_title"),
description: t(l, "landing.feat_infra_desc"),
}
FeatureCard {
- icon: rsx! {
- Icon { icon: BsShieldCheck, width: 28, height: 28 }
- },
title: t(l, "landing.feat_gdpr_title"),
description: t(l, "landing.feat_gdpr_desc"),
}
FeatureCard {
- icon: rsx! {
- Icon { icon: FaCubes, width: 28, height: 28 }
- },
title: t(l, "landing.feat_llm_title"),
description: t(l, "landing.feat_llm_desc"),
}
FeatureCard {
- icon: rsx! {
- Icon { icon: BsRobot, width: 28, height: 28 }
- },
title: t(l, "landing.feat_agent_title"),
description: t(l, "landing.feat_agent_desc"),
}
FeatureCard {
- icon: rsx! {
- Icon { icon: BsGlobe2, width: 28, height: 28 }
- },
title: t(l, "landing.feat_mcp_title"),
description: t(l, "landing.feat_mcp_desc"),
}
FeatureCard {
- icon: rsx! {
- Icon { icon: BsKey, width: 28, height: 28 }
- },
title: t(l, "landing.feat_api_title"),
description: t(l, "landing.feat_api_desc"),
}
@@ -374,18 +202,17 @@ fn FeaturesGrid() -> Element {
}
}
-/// Individual feature card.
+/// Individual feature card with a gradient icon bar accent.
///
/// # Arguments
///
-/// * `icon` - The icon element to display
/// * `title` - Feature title (owned String from translation lookup)
/// * `description` - Feature description text (owned String from translation lookup)
#[component]
-fn FeatureCard(icon: Element, title: String, description: String) -> Element {
+fn FeatureCard(title: String, description: String) -> Element {
rsx! {
div { class: "card feature-card",
- div { class: "feature-card-icon", {icon} }
+ div { class: "feature-icon-bar" }
h3 { class: "feature-card-title", "{title}" }
p { class: "feature-card-desc", "{description}" }
}
@@ -441,33 +268,35 @@ fn StepCard(number: &'static str, title: String, description: String) -> Element
}
}
-/// Call-to-action banner before the footer.
+/// Call-to-action banner wrapped in a glass box with aurora top border.
#[component]
fn CtaBanner() -> Element {
let locale = use_context::>();
let l = *locale.read();
rsx! {
- section { class: "cta-banner",
- h2 { class: "cta-title", {t(l, "landing.cta_title")} }
- p { class: "cta-subtitle",
- {t(l, "landing.cta_subtitle")}
- }
- div { class: "cta-actions",
- Link {
- to: Route::Login {
- redirect_url: "/dashboard".into(),
- },
- class: "btn btn-primary btn-lg",
- {t(l, "landing.get_started_free")}
- Icon { icon: BsArrowRight, width: 18, height: 18 }
+ section { class: "cta-section",
+ div { class: "cta-box",
+ h2 { class: "cta-title", {t(l, "landing.cta_title")} }
+ p { class: "cta-subtitle",
+ {t(l, "landing.cta_subtitle")}
}
- Link {
- to: Route::Login {
- redirect_url: "/dashboard".into(),
- },
- class: "btn btn-outline btn-lg",
- {t(l, "common.log_in")}
+ div { class: "cta-actions",
+ Link {
+ to: Route::Login {
+ redirect_url: "/dashboard".into(),
+ },
+ class: "btn btn-primary btn-lg",
+ {t(l, "landing.get_started_free")}
+ Icon { icon: BsArrowRight, width: 18, height: 18 }
+ }
+ Link {
+ to: Route::Login {
+ redirect_url: "/dashboard".into(),
+ },
+ class: "btn btn-outline btn-lg",
+ {t(l, "common.log_in")}
+ }
}
}
}
@@ -475,6 +304,7 @@ fn CtaBanner() -> Element {
}
/// Landing page footer with links and copyright.
+/// Uses glass border-top styling per Glass Aurora design.
#[component]
fn LandingFooter() -> Element {
let locale = use_context::>();