feat(ui): redesign landing page and update styling
Some checks failed
Overhaul landing page design with updated CSS, Tailwind config, and i18n translations across all supported languages. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
1228
assets/main.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
907
design-templates/01-nordic-frost.html
Normal file
@@ -0,0 +1,907 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CERTifAI - Template 1: Nordic Frost</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,wght@0,400;0,500;0,600;0,700&family=Playfair+Display:wght@500;600;700;800&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ========================================================================
|
||||
TEMPLATE 1: NORDIC FROST
|
||||
========================================================================
|
||||
Mood: Clean, minimal, premium, Scandinavian-inspired
|
||||
Audience: Enterprise, banking, legal, healthcare
|
||||
Palette: Cool whites, slate greys, muted teal accents
|
||||
Fonts: Playfair Display (headings) + DM Sans (body)
|
||||
Feel: Trustworthy, understated luxury, whisper-quiet confidence
|
||||
======================================================================== */
|
||||
|
||||
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
:root {
|
||||
--bg-primary: #f7f8fa;
|
||||
--bg-secondary: #ffffff;
|
||||
--bg-tertiary: #eef0f4;
|
||||
--bg-dark: #1a1e2e;
|
||||
--bg-dark-card: #232838;
|
||||
--text-primary: #1a1e2e;
|
||||
--text-secondary: #5a6178;
|
||||
--text-muted: #8b92a8;
|
||||
--text-inverse: #f0f1f5;
|
||||
--accent: #3a8f8b;
|
||||
--accent-light: #4aada8;
|
||||
--accent-muted: rgba(58, 143, 139, 0.08);
|
||||
--accent-border: rgba(58, 143, 139, 0.2);
|
||||
--border: #e4e7ee;
|
||||
--border-subtle: #eef0f4;
|
||||
--shadow-sm: 0 1px 3px rgba(26, 30, 46, 0.04);
|
||||
--shadow-md: 0 4px 16px rgba(26, 30, 46, 0.06);
|
||||
--shadow-lg: 0 8px 32px rgba(26, 30, 46, 0.08);
|
||||
--radius-sm: 6px;
|
||||
--radius-md: 10px;
|
||||
--radius-lg: 16px;
|
||||
--radius-xl: 24px;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
color: var(--text-primary);
|
||||
background: var(--bg-primary);
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
font-family: 'Playfair Display', serif;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* ===== View Switcher ===== */
|
||||
.view-switcher {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
background: var(--bg-dark);
|
||||
padding: 6px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 24px rgba(0,0,0,0.2);
|
||||
}
|
||||
.view-switcher button {
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
color: rgba(255,255,255,0.5);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.view-switcher button.active {
|
||||
background: var(--accent);
|
||||
color: #fff;
|
||||
}
|
||||
.view-switcher button:hover:not(.active) {
|
||||
color: rgba(255,255,255,0.8);
|
||||
}
|
||||
|
||||
.view { display: none; }
|
||||
.view.active { display: block; }
|
||||
|
||||
/* ===== LANDING PAGE ===== */
|
||||
|
||||
/* -- Navbar -- */
|
||||
.landing-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20px 64px;
|
||||
background: rgba(255,255,255,0.8);
|
||||
backdrop-filter: blur(20px);
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
.nav-logo {
|
||||
font-family: 'Playfair Display', serif;
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
letter-spacing: -0.3px;
|
||||
}
|
||||
.nav-logo span { color: var(--accent); }
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 36px;
|
||||
list-style: none;
|
||||
}
|
||||
.nav-links a {
|
||||
text-decoration: none;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.nav-links a:hover { color: var(--text-primary); }
|
||||
.nav-cta {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
.btn-ghost {
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius-md);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.btn-ghost:hover { color: var(--text-primary); background: var(--bg-tertiary); }
|
||||
.btn-primary {
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
padding: 10px 24px;
|
||||
border: none;
|
||||
background: var(--accent);
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius-md);
|
||||
transition: all 0.25s;
|
||||
}
|
||||
.btn-primary:hover { background: var(--accent-light); transform: translateY(-1px); box-shadow: var(--shadow-md); }
|
||||
|
||||
/* -- Hero -- */
|
||||
.hero {
|
||||
padding: 120px 64px 100px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.hero::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -200px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 800px;
|
||||
height: 800px;
|
||||
background: radial-gradient(circle, rgba(58,143,139,0.06) 0%, transparent 70%);
|
||||
pointer-events: none;
|
||||
}
|
||||
.hero-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 6px 16px;
|
||||
background: var(--accent-muted);
|
||||
border: 1px solid var(--accent-border);
|
||||
border-radius: 100px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: var(--accent);
|
||||
margin-bottom: 32px;
|
||||
animation: fadeUp 0.6s ease;
|
||||
}
|
||||
.hero h1 {
|
||||
font-size: 64px;
|
||||
letter-spacing: -1.5px;
|
||||
margin-bottom: 24px;
|
||||
animation: fadeUp 0.6s ease 0.1s both;
|
||||
}
|
||||
.hero h1 em {
|
||||
font-style: italic;
|
||||
color: var(--accent);
|
||||
}
|
||||
.hero p {
|
||||
font-size: 18px;
|
||||
color: var(--text-secondary);
|
||||
max-width: 560px;
|
||||
margin: 0 auto 40px;
|
||||
animation: fadeUp 0.6s ease 0.2s both;
|
||||
}
|
||||
.hero-actions {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
justify-content: center;
|
||||
animation: fadeUp 0.6s ease 0.3s both;
|
||||
}
|
||||
.btn-outline {
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
padding: 12px 28px;
|
||||
border: 1.5px solid var(--border);
|
||||
background: var(--bg-secondary);
|
||||
color: var(--text-primary);
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius-md);
|
||||
transition: all 0.25s;
|
||||
}
|
||||
.btn-outline:hover { border-color: var(--accent); color: var(--accent); }
|
||||
.btn-lg { padding: 14px 32px; font-size: 15px; }
|
||||
|
||||
/* -- Trust Bar -- */
|
||||
.trust-bar {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 48px;
|
||||
padding: 48px 64px;
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
}
|
||||
.trust-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
font-size: 14px;
|
||||
color: var(--text-muted);
|
||||
font-weight: 500;
|
||||
}
|
||||
.trust-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--accent-muted);
|
||||
border-radius: var(--radius-sm);
|
||||
color: var(--accent);
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* -- Features -- */
|
||||
.features {
|
||||
padding: 100px 64px;
|
||||
}
|
||||
.section-header {
|
||||
text-align: center;
|
||||
margin-bottom: 64px;
|
||||
}
|
||||
.section-header h2 {
|
||||
font-size: 40px;
|
||||
letter-spacing: -0.8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.section-header p {
|
||||
font-size: 16px;
|
||||
color: var(--text-secondary);
|
||||
max-width: 480px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 24px;
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.feature-card {
|
||||
padding: 32px;
|
||||
background: var(--bg-secondary);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-lg);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.feature-card:hover {
|
||||
border-color: var(--accent-border);
|
||||
box-shadow: var(--shadow-md);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.feature-icon {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--accent-muted);
|
||||
border-radius: var(--radius-md);
|
||||
color: var(--accent);
|
||||
font-size: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.feature-card h3 {
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.feature-card p {
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* -- CTA Section -- */
|
||||
.cta-section {
|
||||
padding: 80px 64px;
|
||||
text-align: center;
|
||||
}
|
||||
.cta-box {
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
padding: 64px;
|
||||
background: var(--bg-dark);
|
||||
border-radius: var(--radius-xl);
|
||||
color: var(--text-inverse);
|
||||
}
|
||||
.cta-box h2 {
|
||||
font-size: 36px;
|
||||
margin-bottom: 16px;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
.cta-box p {
|
||||
font-size: 16px;
|
||||
color: rgba(240,241,245,0.6);
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.btn-white {
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
padding: 14px 32px;
|
||||
border: none;
|
||||
background: #fff;
|
||||
color: var(--bg-dark);
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius-md);
|
||||
transition: all 0.25s;
|
||||
}
|
||||
.btn-white:hover { transform: translateY(-1px); box-shadow: 0 4px 20px rgba(255,255,255,0.15); }
|
||||
|
||||
/* -- Footer -- */
|
||||
.landing-footer {
|
||||
padding: 48px 64px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.footer-links { display: flex; gap: 24px; }
|
||||
.footer-links a { color: var(--text-muted); text-decoration: none; }
|
||||
.footer-links a:hover { color: var(--text-primary); }
|
||||
|
||||
/* ===== DASHBOARD PAGE ===== */
|
||||
|
||||
.dashboard-layout {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
background: var(--bg-primary);
|
||||
}
|
||||
|
||||
/* -- Sidebar -- */
|
||||
.sidebar {
|
||||
width: 260px;
|
||||
min-width: 260px;
|
||||
background: var(--bg-secondary);
|
||||
border-right: 1px solid var(--border);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
.sidebar-brand {
|
||||
padding: 24px 20px;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
}
|
||||
.sidebar-brand h2 {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.3px;
|
||||
}
|
||||
.sidebar-brand h2 span { color: var(--accent); }
|
||||
.sidebar-user {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 20px;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
}
|
||||
.user-avatar {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
background: var(--accent);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.user-info { min-width: 0; }
|
||||
.user-name { font-size: 14px; font-weight: 600; }
|
||||
.user-email { font-size: 12px; color: var(--text-muted); }
|
||||
.sidebar-nav {
|
||||
flex: 1;
|
||||
padding: 16px 12px;
|
||||
}
|
||||
.nav-section-label {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
color: var(--text-muted);
|
||||
padding: 12px 12px 8px;
|
||||
}
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 10px 12px;
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
text-decoration: none;
|
||||
}
|
||||
.nav-item:hover { background: var(--bg-tertiary); color: var(--text-primary); }
|
||||
.nav-item.active {
|
||||
background: var(--accent-muted);
|
||||
color: var(--accent);
|
||||
font-weight: 600;
|
||||
}
|
||||
.nav-item svg { width: 18px; height: 18px; opacity: 0.6; }
|
||||
.nav-item.active svg { opacity: 1; }
|
||||
.sidebar-footer {
|
||||
padding: 16px 20px;
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* -- Main Content -- */
|
||||
.main-content {
|
||||
flex: 1;
|
||||
padding: 40px 48px;
|
||||
min-width: 0;
|
||||
}
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
.page-title { font-size: 28px; letter-spacing: -0.5px; }
|
||||
.page-subtitle { font-size: 14px; color: var(--text-muted); margin-top: 4px; font-family: 'DM Sans', sans-serif; }
|
||||
|
||||
/* -- Stats Row -- */
|
||||
.stats-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 20px;
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
.stat-card {
|
||||
padding: 24px;
|
||||
background: var(--bg-secondary);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-lg);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.stat-card:hover { box-shadow: var(--shadow-sm); }
|
||||
.stat-label {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--text-muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.stat-value {
|
||||
font-family: 'Playfair Display', serif;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.stat-change {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
margin-top: 6px;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
/* -- Content Grid -- */
|
||||
.content-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
gap: 24px;
|
||||
}
|
||||
.card {
|
||||
background: var(--bg-secondary);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: 28px;
|
||||
}
|
||||
.card-title {
|
||||
font-family: 'DM Sans', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.card-title .badge {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
padding: 4px 10px;
|
||||
background: var(--accent-muted);
|
||||
color: var(--accent);
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
/* -- Table -- */
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.data-table th {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--text-muted);
|
||||
text-align: left;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.data-table td {
|
||||
font-size: 14px;
|
||||
padding: 14px 0;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.data-table tr:last-child td { border-bottom: none; }
|
||||
.model-tag {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
padding: 3px 10px;
|
||||
background: var(--bg-tertiary);
|
||||
border-radius: 100px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* -- Status Indicator -- */
|
||||
.status-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.status-dot.online { background: #3a8f8b; box-shadow: 0 0 6px rgba(58,143,139,0.4); }
|
||||
.status-dot.offline { background: #c4c4c4; }
|
||||
|
||||
/* -- Members List -- */
|
||||
.member-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
}
|
||||
.member-item:last-child { border-bottom: none; }
|
||||
.member-avatar {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
.member-name { font-size: 14px; font-weight: 500; }
|
||||
.member-role { font-size: 12px; color: var(--text-muted); }
|
||||
.member-role-badge {
|
||||
margin-left: auto;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
padding: 3px 10px;
|
||||
border-radius: 100px;
|
||||
background: var(--bg-tertiary);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* ===== ANIMATIONS ===== */
|
||||
@keyframes fadeUp {
|
||||
from { opacity: 0; transform: translateY(16px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
.fade-in { animation: fadeUp 0.5s ease both; }
|
||||
.fade-in-1 { animation-delay: 0.1s; }
|
||||
.fade-in-2 { animation-delay: 0.2s; }
|
||||
.fade-in-3 { animation-delay: 0.3s; }
|
||||
.fade-in-4 { animation-delay: 0.4s; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- View Switcher -->
|
||||
<div class="view-switcher">
|
||||
<button class="active" onclick="showView('landing')">Landing</button>
|
||||
<button onclick="showView('dashboard')">Dashboard</button>
|
||||
</div>
|
||||
|
||||
<!-- ===== LANDING PAGE ===== -->
|
||||
<div id="landing" class="view active">
|
||||
<nav class="landing-nav">
|
||||
<div class="nav-logo">CERT<span>if</span>AI</div>
|
||||
<ul class="nav-links">
|
||||
<li><a href="#">Features</a></li>
|
||||
<li><a href="#">How It Works</a></li>
|
||||
<li><a href="#">Pricing</a></li>
|
||||
<li><a href="#">Docs</a></li>
|
||||
</ul>
|
||||
<div class="nav-cta">
|
||||
<button class="btn-ghost">Sign In</button>
|
||||
<button class="btn-primary">Get Started</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section class="hero">
|
||||
<div class="hero-badge">● GDPR-Compliant · 100% On-Premise</div>
|
||||
<h1>Your AI infrastructure,<br><em>your rules.</em></h1>
|
||||
<p>Self-hosted generative AI for companies that refuse to compromise on data sovereignty. Deploy, configure, and scale without leaving the EU.</p>
|
||||
<div class="hero-actions">
|
||||
<button class="btn-primary btn-lg">Start Free Trial</button>
|
||||
<button class="btn-outline btn-lg">View Documentation</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="trust-bar">
|
||||
<div class="trust-item">
|
||||
<div class="trust-icon">☑</div>
|
||||
100% On-Premise
|
||||
</div>
|
||||
<div class="trust-item">
|
||||
<div class="trust-icon">⚖</div>
|
||||
GDPR Compliant
|
||||
</div>
|
||||
<div class="trust-item">
|
||||
<div class="trust-icon">⚑</div>
|
||||
EU Data Residency
|
||||
</div>
|
||||
<div class="trust-item">
|
||||
<div class="trust-icon">∅</div>
|
||||
Zero Third-Party Access
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="features">
|
||||
<div class="section-header">
|
||||
<h2>Built for sovereignty</h2>
|
||||
<p>Every component designed to keep your intellectual property exactly where it belongs.</p>
|
||||
</div>
|
||||
<div class="features-grid">
|
||||
<div class="feature-card fade-in fade-in-1">
|
||||
<div class="feature-icon">⚙</div>
|
||||
<h3>Self-Hosted Infrastructure</h3>
|
||||
<p>Deploy on your hardware or private cloud. No data ever leaves your perimeter.</p>
|
||||
</div>
|
||||
<div class="feature-card fade-in fade-in-2">
|
||||
<div class="feature-icon">☍</div>
|
||||
<h3>Multi-LLM Gateway</h3>
|
||||
<p>Route between providers through a single API. LiteLLM proxy with full observability.</p>
|
||||
</div>
|
||||
<div class="feature-card fade-in fade-in-3">
|
||||
<div class="feature-icon">❖</div>
|
||||
<h3>Agent Orchestration</h3>
|
||||
<p>Build and manage LangGraph agents with visual workflows and real-time monitoring.</p>
|
||||
</div>
|
||||
<div class="feature-card fade-in fade-in-4">
|
||||
<div class="feature-icon">⏻</div>
|
||||
<h3>SSO & Identity</h3>
|
||||
<p>Keycloak-powered authentication. Connect your existing LDAP or SAML provider.</p>
|
||||
</div>
|
||||
<div class="feature-card fade-in fade-in-3">
|
||||
<div class="feature-icon">☰</div>
|
||||
<h3>Full Observability</h3>
|
||||
<p>Langfuse integration for traces, cost tracking, and prompt engineering analytics.</p>
|
||||
</div>
|
||||
<div class="feature-card fade-in fade-in-4">
|
||||
<div class="feature-icon">➔</div>
|
||||
<h3>API-First Design</h3>
|
||||
<p>RESTful endpoints, API key management, and MCP server support built in.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="cta-section">
|
||||
<div class="cta-box">
|
||||
<h2>Ready to take control?</h2>
|
||||
<p>Deploy your private AI infrastructure in under 30 minutes. No credit card required.</p>
|
||||
<button class="btn-white">Start Your Free Trial</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer class="landing-footer">
|
||||
<span>© 2026 CERTifAI. All rights reserved.</span>
|
||||
<div class="footer-links">
|
||||
<a href="#">Privacy</a>
|
||||
<a href="#">Impressum</a>
|
||||
<a href="#">Terms</a>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<!-- ===== DASHBOARD PAGE ===== -->
|
||||
<div id="dashboard" class="view">
|
||||
<div class="dashboard-layout">
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-brand">
|
||||
<h2>CERT<span>if</span>AI</h2>
|
||||
</div>
|
||||
<div class="sidebar-user">
|
||||
<div class="user-avatar">MM</div>
|
||||
<div class="user-info">
|
||||
<div class="user-name">Max Mustermann</div>
|
||||
<div class="user-email">max@company.de</div>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="sidebar-nav">
|
||||
<div class="nav-section-label">Main</div>
|
||||
<a class="nav-item active" href="#">■ Dashboard</a>
|
||||
<a class="nav-item" href="#">◊ Providers</a>
|
||||
<a class="nav-item" href="#">✉ Chat</a>
|
||||
<div class="nav-section-label">Developer</div>
|
||||
<a class="nav-item" href="#">⚙ Agents</a>
|
||||
<a class="nav-item" href="#">⧉ Workflows</a>
|
||||
<a class="nav-item" href="#">☰ Analytics</a>
|
||||
<div class="nav-section-label">Organization</div>
|
||||
<a class="nav-item" href="#">★ Billing</a>
|
||||
<a class="nav-item" href="#">❖ Members</a>
|
||||
</nav>
|
||||
<div class="sidebar-footer">CERTifAI v0.1.0</div>
|
||||
</aside>
|
||||
|
||||
<main class="main-content">
|
||||
<div class="page-header">
|
||||
<div>
|
||||
<h1 class="page-title">Dashboard</h1>
|
||||
<p class="page-subtitle">AI news and system overview</p>
|
||||
</div>
|
||||
<button class="btn-primary">New Search</button>
|
||||
</div>
|
||||
|
||||
<div class="stats-row">
|
||||
<div class="stat-card fade-in fade-in-1">
|
||||
<div class="stat-label">Total Spend</div>
|
||||
<div class="stat-value">$47.82</div>
|
||||
<div class="stat-change">+12% this month</div>
|
||||
</div>
|
||||
<div class="stat-card fade-in fade-in-2">
|
||||
<div class="stat-label">Total Tokens</div>
|
||||
<div class="stat-value">847K</div>
|
||||
<div class="stat-change">of 1M limit</div>
|
||||
</div>
|
||||
<div class="stat-card fade-in fade-in-3">
|
||||
<div class="stat-label">Active Models</div>
|
||||
<div class="stat-value">5</div>
|
||||
<div class="stat-change"><span class="status-dot online"></span>LiteLLM Online</div>
|
||||
</div>
|
||||
<div class="stat-card fade-in fade-in-4">
|
||||
<div class="stat-label">Team Members</div>
|
||||
<div class="stat-value">4/25</div>
|
||||
<div class="stat-change">Seats used</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-grid">
|
||||
<div class="card">
|
||||
<div class="card-title">
|
||||
Usage by Model
|
||||
<span class="badge">This Month</span>
|
||||
</div>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Model</th>
|
||||
<th>Tokens</th>
|
||||
<th>Spend</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><span class="model-tag">Qwen3-Coder-30B</span></td>
|
||||
<td>342K</td>
|
||||
<td>$18.40</td>
|
||||
<td><span class="status-dot online"></span>Active</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="model-tag">Llama-3.1-70B</span></td>
|
||||
<td>285K</td>
|
||||
<td>$15.20</td>
|
||||
<td><span class="status-dot online"></span>Active</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="model-tag">Mistral-7B</span></td>
|
||||
<td>120K</td>
|
||||
<td>$8.42</td>
|
||||
<td><span class="status-dot online"></span>Active</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="model-tag">Gemma-2-9B</span></td>
|
||||
<td>65K</td>
|
||||
<td>$3.80</td>
|
||||
<td><span class="status-dot online"></span>Active</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="model-tag">Phi-3-mini</span></td>
|
||||
<td>35K</td>
|
||||
<td>$2.00</td>
|
||||
<td><span class="status-dot offline"></span>Idle</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-title">Team</div>
|
||||
<div class="member-item">
|
||||
<div class="member-avatar" style="background:#3a8f8b">MM</div>
|
||||
<div>
|
||||
<div class="member-name">Max Mustermann</div>
|
||||
<div class="member-role">max@company.de</div>
|
||||
</div>
|
||||
<span class="member-role-badge">Admin</span>
|
||||
</div>
|
||||
<div class="member-item">
|
||||
<div class="member-avatar" style="background:#6d85c6">EM</div>
|
||||
<div>
|
||||
<div class="member-name">Erika Musterfrau</div>
|
||||
<div class="member-role">erika@company.de</div>
|
||||
</div>
|
||||
<span class="member-role-badge">Member</span>
|
||||
</div>
|
||||
<div class="member-item">
|
||||
<div class="member-avatar" style="background:#8b6db8">JS</div>
|
||||
<div>
|
||||
<div class="member-name">Johann Schmidt</div>
|
||||
<div class="member-role">johann@company.de</div>
|
||||
</div>
|
||||
<span class="member-role-badge">Member</span>
|
||||
</div>
|
||||
<div class="member-item">
|
||||
<div class="member-avatar" style="background:#b8886d">AW</div>
|
||||
<div>
|
||||
<div class="member-name">Anna Weber</div>
|
||||
<div class="member-role">anna@company.de</div>
|
||||
</div>
|
||||
<span class="member-role-badge">Viewer</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function showView(id) {
|
||||
document.querySelectorAll('.view').forEach(v => v.classList.remove('active'));
|
||||
document.querySelectorAll('.view-switcher button').forEach(b => b.classList.remove('active'));
|
||||
document.getElementById(id).classList.add('active');
|
||||
event.target.classList.add('active');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
942
design-templates/02-cyber-command.html
Normal file
@@ -0,0 +1,942 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CERTifAI - Template 2: Cyber Command</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&family=Outfit:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ========================================================================
|
||||
TEMPLATE 2: CYBER COMMAND
|
||||
========================================================================
|
||||
Mood: Dark, high-tech, cyberpunk-inspired command center
|
||||
Audience: DevOps, security teams, tech-forward startups
|
||||
Palette: Deep blacks, neon cyan/green accents, electric highlights
|
||||
Fonts: Outfit (headings) + JetBrains Mono (body/data)
|
||||
Feel: Powerful, technical, mission-critical, the Matrix meets Bloomberg Terminal
|
||||
======================================================================== */
|
||||
|
||||
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
:root {
|
||||
--bg-void: #050508;
|
||||
--bg-primary: #0a0b10;
|
||||
--bg-secondary: #0f1018;
|
||||
--bg-card: #12141e;
|
||||
--bg-surface: #181b28;
|
||||
--bg-hover: #1a1d2c;
|
||||
--text-primary: #d4dae8;
|
||||
--text-secondary: #7a8499;
|
||||
--text-muted: #484f64;
|
||||
--text-bright: #f0f3fa;
|
||||
--cyan: #00e5c8;
|
||||
--cyan-dim: rgba(0, 229, 200, 0.12);
|
||||
--cyan-border: rgba(0, 229, 200, 0.2);
|
||||
--cyan-glow: rgba(0, 229, 200, 0.06);
|
||||
--green: #34d399;
|
||||
--red: #f87171;
|
||||
--yellow: #fbbf24;
|
||||
--border: #1a1d2c;
|
||||
--border-bright: #252a3a;
|
||||
--shadow-glow: 0 0 40px rgba(0, 229, 200, 0.05);
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
color: var(--text-primary);
|
||||
background: var(--bg-void);
|
||||
line-height: 1.65;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-weight: 700;
|
||||
line-height: 1.15;
|
||||
color: var(--text-bright);
|
||||
}
|
||||
|
||||
/* ===== View Switcher ===== */
|
||||
.view-switcher {
|
||||
position: fixed;
|
||||
top: 16px;
|
||||
right: 16px;
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border-bright);
|
||||
padding: 4px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.view-switcher button {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
color: var(--text-muted);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.view-switcher button.active {
|
||||
background: var(--cyan);
|
||||
color: var(--bg-void);
|
||||
}
|
||||
.view-switcher button:hover:not(.active) { color: var(--text-primary); }
|
||||
|
||||
.view { display: none; }
|
||||
.view.active { display: block; }
|
||||
|
||||
/* ===== LANDING PAGE ===== */
|
||||
|
||||
.landing-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 18px 48px;
|
||||
background: rgba(10, 11, 16, 0.85);
|
||||
backdrop-filter: blur(24px);
|
||||
border-bottom: 1px solid var(--border);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
.nav-logo {
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-size: 20px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
color: var(--text-bright);
|
||||
}
|
||||
.nav-logo .accent { color: var(--cyan); }
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
list-style: none;
|
||||
}
|
||||
.nav-links a {
|
||||
text-decoration: none;
|
||||
color: var(--text-secondary);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.nav-links a:hover { color: var(--cyan); }
|
||||
.nav-cta { display: flex; gap: 10px; }
|
||||
.btn-ghost {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
padding: 10px 20px;
|
||||
border: 1px solid var(--border-bright);
|
||||
background: transparent;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.btn-ghost:hover { border-color: var(--cyan-border); color: var(--cyan); }
|
||||
.btn-primary {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
padding: 10px 24px;
|
||||
border: 1px solid var(--cyan);
|
||||
background: var(--cyan);
|
||||
color: var(--bg-void);
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
transition: all 0.25s;
|
||||
}
|
||||
.btn-primary:hover { box-shadow: 0 0 24px rgba(0,229,200,0.3); transform: translateY(-1px); }
|
||||
|
||||
/* -- Hero -- */
|
||||
.hero {
|
||||
padding: 140px 48px 120px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.hero::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -100px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 600px;
|
||||
height: 600px;
|
||||
background: radial-gradient(circle, var(--cyan-glow) 0%, transparent 70%);
|
||||
pointer-events: none;
|
||||
}
|
||||
.hero::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: repeating-linear-gradient(
|
||||
0deg,
|
||||
transparent,
|
||||
transparent 2px,
|
||||
rgba(0, 229, 200, 0.01) 2px,
|
||||
rgba(0, 229, 200, 0.01) 4px
|
||||
);
|
||||
pointer-events: none;
|
||||
}
|
||||
.hero-tag {
|
||||
display: inline-block;
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: var(--cyan);
|
||||
padding: 8px 20px;
|
||||
border: 1px solid var(--cyan-border);
|
||||
border-radius: 4px;
|
||||
margin-bottom: 36px;
|
||||
background: var(--cyan-dim);
|
||||
animation: fadeIn 0.5s ease;
|
||||
}
|
||||
.hero h1 {
|
||||
font-size: 72px;
|
||||
letter-spacing: -2px;
|
||||
margin-bottom: 24px;
|
||||
animation: fadeUp 0.6s ease 0.1s both;
|
||||
}
|
||||
.hero h1 .gradient {
|
||||
background: linear-gradient(135deg, var(--cyan), #34d399, var(--cyan));
|
||||
background-size: 200% 200%;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
animation: shimmer 4s ease infinite;
|
||||
}
|
||||
.hero p {
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
max-width: 520px;
|
||||
margin: 0 auto 44px;
|
||||
line-height: 1.8;
|
||||
animation: fadeUp 0.6s ease 0.2s both;
|
||||
}
|
||||
.hero-actions {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
justify-content: center;
|
||||
animation: fadeUp 0.6s ease 0.3s both;
|
||||
}
|
||||
.btn-outline {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
padding: 12px 28px;
|
||||
border: 1px solid var(--border-bright);
|
||||
background: transparent;
|
||||
color: var(--text-primary);
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
transition: all 0.25s;
|
||||
}
|
||||
.btn-outline:hover { border-color: var(--cyan-border); color: var(--cyan); }
|
||||
|
||||
/* -- Terminal Preview -- */
|
||||
.terminal-preview {
|
||||
max-width: 700px;
|
||||
margin: 60px auto 0;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border-bright);
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
animation: fadeUp 0.6s ease 0.4s both;
|
||||
}
|
||||
.terminal-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px 16px;
|
||||
background: var(--bg-surface);
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.terminal-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.terminal-dot.r { background: var(--red); opacity: 0.7; }
|
||||
.terminal-dot.y { background: var(--yellow); opacity: 0.7; }
|
||||
.terminal-dot.g { background: var(--green); opacity: 0.7; }
|
||||
.terminal-title {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
margin-left: 8px;
|
||||
}
|
||||
.terminal-body {
|
||||
padding: 20px;
|
||||
font-size: 13px;
|
||||
line-height: 1.9;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
.terminal-body .cmd { color: var(--cyan); }
|
||||
.terminal-body .comment { color: var(--text-muted); }
|
||||
.terminal-body .success { color: var(--green); }
|
||||
|
||||
/* -- Trust Bar -- */
|
||||
.trust-bar {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 48px;
|
||||
padding: 40px 48px;
|
||||
border-top: 1px solid var(--border);
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.trust-item {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
color: var(--text-muted);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.trust-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background: var(--cyan);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 8px rgba(0,229,200,0.4);
|
||||
}
|
||||
|
||||
/* -- Features -- */
|
||||
.features {
|
||||
padding: 100px 48px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.section-header {
|
||||
text-align: center;
|
||||
margin-bottom: 64px;
|
||||
}
|
||||
.section-header h2 {
|
||||
font-size: 42px;
|
||||
letter-spacing: -1px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.section-header p {
|
||||
font-size: 13px;
|
||||
color: var(--text-secondary);
|
||||
max-width: 480px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
.feature-card {
|
||||
padding: 28px;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.feature-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg, transparent, var(--cyan), transparent);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
.feature-card:hover::before { opacity: 1; }
|
||||
.feature-card:hover { border-color: var(--border-bright); box-shadow: var(--shadow-glow); }
|
||||
.feature-num {
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: var(--cyan);
|
||||
letter-spacing: 0.1em;
|
||||
margin-bottom: 16px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
.feature-card h3 {
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.feature-card p {
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* -- CTA -- */
|
||||
.cta-section {
|
||||
padding: 80px 48px;
|
||||
text-align: center;
|
||||
}
|
||||
.cta-box {
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 56px;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--cyan-border);
|
||||
border-radius: 12px;
|
||||
box-shadow: var(--shadow-glow);
|
||||
}
|
||||
.cta-box h2 { font-size: 32px; margin-bottom: 12px; }
|
||||
.cta-box p { font-size: 13px; color: var(--text-secondary); margin-bottom: 32px; }
|
||||
|
||||
/* -- Footer -- */
|
||||
.landing-footer {
|
||||
padding: 40px 48px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-top: 1px solid var(--border);
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.footer-links { display: flex; gap: 24px; }
|
||||
.footer-links a { color: var(--text-muted); text-decoration: none; }
|
||||
.footer-links a:hover { color: var(--cyan); }
|
||||
|
||||
/* ===== DASHBOARD ===== */
|
||||
|
||||
.dashboard-layout {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
background: var(--bg-primary);
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 240px;
|
||||
min-width: 240px;
|
||||
background: var(--bg-secondary);
|
||||
border-right: 1px solid var(--border);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
.sidebar-brand {
|
||||
padding: 20px 16px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.sidebar-brand h2 {
|
||||
font-size: 16px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 2px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.sidebar-brand .accent { color: var(--cyan); }
|
||||
.sidebar-status {
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.pulse-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--green);
|
||||
box-shadow: 0 0 8px rgba(52,211,153,0.5);
|
||||
animation: pulse 2s ease infinite;
|
||||
}
|
||||
.sidebar-nav {
|
||||
flex: 1;
|
||||
padding: 12px 8px;
|
||||
}
|
||||
.nav-group-label {
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: var(--text-muted);
|
||||
padding: 12px 12px 6px;
|
||||
}
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
text-decoration: none;
|
||||
border-left: 2px solid transparent;
|
||||
}
|
||||
.nav-item:hover { background: var(--bg-hover); color: var(--text-primary); }
|
||||
.nav-item.active {
|
||||
background: var(--cyan-dim);
|
||||
color: var(--cyan);
|
||||
border-left-color: var(--cyan);
|
||||
}
|
||||
.sidebar-user {
|
||||
padding: 16px;
|
||||
border-top: 1px solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.user-avatar-sm {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 4px;
|
||||
background: var(--cyan-dim);
|
||||
color: var(--cyan);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.user-info-sm .name { font-size: 12px; font-weight: 600; color: var(--text-primary); }
|
||||
.user-info-sm .role { font-size: 10px; color: var(--text-muted); }
|
||||
|
||||
/* -- Main -- */
|
||||
.main-content {
|
||||
flex: 1;
|
||||
padding: 32px 40px;
|
||||
min-width: 0;
|
||||
}
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.page-title { font-size: 24px; letter-spacing: -0.5px; }
|
||||
.page-subtitle {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
margin-top: 4px;
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
}
|
||||
|
||||
/* -- Stats -- */
|
||||
.stats-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 12px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
.stat-card {
|
||||
padding: 20px;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.stat-card::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg, var(--cyan), transparent);
|
||||
opacity: 0.3;
|
||||
}
|
||||
.stat-label {
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.stat-value {
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
color: var(--text-bright);
|
||||
}
|
||||
.stat-change {
|
||||
font-size: 11px;
|
||||
margin-top: 6px;
|
||||
color: var(--green);
|
||||
}
|
||||
|
||||
/* -- Grid -- */
|
||||
.content-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 5fr 3fr;
|
||||
gap: 16px;
|
||||
}
|
||||
.card {
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
}
|
||||
.card-title {
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--text-bright);
|
||||
margin-bottom: 18px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.card-badge {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
padding: 4px 10px;
|
||||
background: var(--cyan-dim);
|
||||
color: var(--cyan);
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--cyan-border);
|
||||
}
|
||||
|
||||
/* -- Table -- */
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.data-table th {
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
color: var(--text-muted);
|
||||
text-align: left;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.data-table td {
|
||||
font-size: 12px;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.data-table tr:last-child td { border-bottom: none; }
|
||||
.model-tag {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
padding: 2px 8px;
|
||||
background: var(--bg-surface);
|
||||
border: 1px solid var(--border-bright);
|
||||
border-radius: 4px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.status-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
margin-right: 6px;
|
||||
}
|
||||
.status-dot.on { background: var(--green); box-shadow: 0 0 6px rgba(52,211,153,0.5); }
|
||||
.status-dot.off { background: var(--text-muted); }
|
||||
|
||||
/* -- Activity List -- */
|
||||
.activity-item {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
align-items: flex-start;
|
||||
}
|
||||
.activity-item:last-child { border-bottom: none; }
|
||||
.activity-time {
|
||||
font-size: 10px;
|
||||
color: var(--text-muted);
|
||||
white-space: nowrap;
|
||||
padding-top: 2px;
|
||||
min-width: 48px;
|
||||
}
|
||||
.activity-text {
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.5;
|
||||
}
|
||||
.activity-text strong { color: var(--text-primary); font-weight: 600; }
|
||||
.activity-text .hl { color: var(--cyan); }
|
||||
|
||||
/* ===== Animations ===== */
|
||||
@keyframes fadeUp {
|
||||
from { opacity: 0; transform: translateY(20px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
@keyframes shimmer {
|
||||
0%, 100% { background-position: 0% 50%; }
|
||||
50% { background-position: 100% 50%; }
|
||||
}
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.4; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="view-switcher">
|
||||
<button class="active" onclick="showView('landing')">LANDING</button>
|
||||
<button onclick="showView('dashboard')">DASHBOARD</button>
|
||||
</div>
|
||||
|
||||
<!-- ===== LANDING ===== -->
|
||||
<div id="landing" class="view active">
|
||||
<nav class="landing-nav">
|
||||
<div class="nav-logo">CERT<span class="accent">IF</span>AI</div>
|
||||
<ul class="nav-links">
|
||||
<li><a href="#">Features</a></li>
|
||||
<li><a href="#">Architecture</a></li>
|
||||
<li><a href="#">Pricing</a></li>
|
||||
<li><a href="#">Docs</a></li>
|
||||
</ul>
|
||||
<div class="nav-cta">
|
||||
<button class="btn-ghost">Sign In</button>
|
||||
<button class="btn-primary">Deploy Now</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section class="hero">
|
||||
<div class="hero-tag">// SELF-HOSTED · GDPR NATIVE · ZERO TRUST</div>
|
||||
<h1>Private AI<br><span class="gradient">Command Center</span></h1>
|
||||
<p>Deploy sovereign AI infrastructure that never phones home. Route LLMs, orchestrate agents, track every token—all inside your perimeter.</p>
|
||||
<div class="hero-actions">
|
||||
<button class="btn-primary" style="padding:14px 32px">Deploy Now</button>
|
||||
<button class="btn-outline" style="padding:14px 32px">Read the Docs</button>
|
||||
</div>
|
||||
|
||||
<div class="terminal-preview">
|
||||
<div class="terminal-bar">
|
||||
<div class="terminal-dot r"></div>
|
||||
<div class="terminal-dot y"></div>
|
||||
<div class="terminal-dot g"></div>
|
||||
<span class="terminal-title">certifai-cli — deploy</span>
|
||||
</div>
|
||||
<div class="terminal-body">
|
||||
<span class="comment"># Deploy CERTifAI to your private cluster</span><br>
|
||||
<span class="cmd">$</span> certifai deploy --region eu-west-1 --gpu a100<br>
|
||||
<span class="success">✓</span> Keycloak SSO configured<br>
|
||||
<span class="success">✓</span> LiteLLM proxy ready (5 models loaded)<br>
|
||||
<span class="success">✓</span> LangGraph agents online<br>
|
||||
<span class="success">✓</span> Langfuse observability active<br>
|
||||
<br>
|
||||
<span class="cmd">$</span> certifai status<br>
|
||||
<span class="success">All systems operational.</span> Uptime: 99.97%
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="trust-bar">
|
||||
<div class="trust-item"><div class="trust-dot"></div>100% ON-PREMISE</div>
|
||||
<div class="trust-item"><div class="trust-dot"></div>GDPR ARTICLE 28</div>
|
||||
<div class="trust-item"><div class="trust-dot"></div>EU DATA RESIDENCY</div>
|
||||
<div class="trust-item"><div class="trust-dot"></div>ZERO THIRD-PARTY</div>
|
||||
<div class="trust-item"><div class="trust-dot"></div>SOC 2 TYPE II</div>
|
||||
</div>
|
||||
|
||||
<section class="features">
|
||||
<div class="section-header">
|
||||
<h2>Full-spectrum control</h2>
|
||||
<p>From model routing to cost analytics, every layer is yours to command.</p>
|
||||
</div>
|
||||
<div class="features-grid">
|
||||
<div class="feature-card">
|
||||
<div class="feature-num">01</div>
|
||||
<h3>LLM Gateway</h3>
|
||||
<p>LiteLLM proxy routes requests across providers. One API, full model flexibility, zero vendor lock-in.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-num">02</div>
|
||||
<h3>Agent Orchestration</h3>
|
||||
<p>LangGraph + LangFlow for building, deploying, and monitoring autonomous agent workflows.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-num">03</div>
|
||||
<h3>Full Observability</h3>
|
||||
<p>Langfuse tracing, cost attribution, prompt versioning. Know exactly what your AI is doing.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-num">04</div>
|
||||
<h3>Identity & Access</h3>
|
||||
<p>Keycloak SSO with SAML, OIDC, LDAP. Fine-grained RBAC across all services.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-num">05</div>
|
||||
<h3>MCP Servers</h3>
|
||||
<p>Model Context Protocol support for tool-augmented AI with secure function calling.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-num">06</div>
|
||||
<h3>API-First</h3>
|
||||
<p>REST endpoints, API key rotation, webhook events. Integrate CERTifAI into your existing stack.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="cta-section">
|
||||
<div class="cta-box">
|
||||
<h2>Your cluster. Your models. Your rules.</h2>
|
||||
<p>Spin up a fully operational AI stack in under 30 minutes.</p>
|
||||
<button class="btn-primary" style="padding:14px 36px; font-size:13px;">Start Deployment</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer class="landing-footer">
|
||||
<span>© 2026 CERTifAI GmbH</span>
|
||||
<div class="footer-links">
|
||||
<a href="#">Privacy</a>
|
||||
<a href="#">Impressum</a>
|
||||
<a href="#">Status</a>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<!-- ===== DASHBOARD ===== -->
|
||||
<div id="dashboard" class="view">
|
||||
<div class="dashboard-layout">
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-brand">
|
||||
<h2>CERT<span class="accent">IF</span>AI</h2>
|
||||
</div>
|
||||
<div class="sidebar-status">
|
||||
<div class="pulse-dot"></div>
|
||||
ALL SYSTEMS OPERATIONAL
|
||||
</div>
|
||||
<nav class="sidebar-nav">
|
||||
<div class="nav-group-label">Core</div>
|
||||
<a class="nav-item active" href="#">>_ Dashboard</a>
|
||||
<a class="nav-item" href="#">◊ Providers</a>
|
||||
<a class="nav-item" href="#">✉ Chat</a>
|
||||
<div class="nav-group-label">Developer</div>
|
||||
<a class="nav-item" href="#">❖ Agents</a>
|
||||
<a class="nav-item" href="#">⧉ Workflows</a>
|
||||
<a class="nav-item" href="#">☰ Analytics</a>
|
||||
<div class="nav-group-label">Organization</div>
|
||||
<a class="nav-item" href="#">★ Billing</a>
|
||||
<a class="nav-item" href="#">♟ Members</a>
|
||||
</nav>
|
||||
<div class="sidebar-user">
|
||||
<div class="user-avatar-sm">MM</div>
|
||||
<div class="user-info-sm">
|
||||
<div class="name">Max Mustermann</div>
|
||||
<div class="role">Admin</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="main-content">
|
||||
<div class="page-header">
|
||||
<div>
|
||||
<h1 class="page-title">Command Center</h1>
|
||||
<p class="page-subtitle">// system overview · feb 2026</p>
|
||||
</div>
|
||||
<button class="btn-primary">+ New Search</button>
|
||||
</div>
|
||||
|
||||
<div class="stats-row">
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Total Spend</div>
|
||||
<div class="stat-value">$47.82</div>
|
||||
<div class="stat-change">+12.4% vs last month</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Tokens Processed</div>
|
||||
<div class="stat-value">847K</div>
|
||||
<div class="stat-change">of 1M monthly cap</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Active Models</div>
|
||||
<div class="stat-value">5</div>
|
||||
<div class="stat-change"><span class="status-dot on"></span>LiteLLM proxy online</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Team Seats</div>
|
||||
<div class="stat-value">4/25</div>
|
||||
<div class="stat-change">21 available</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-grid">
|
||||
<div class="card">
|
||||
<div class="card-title">
|
||||
Model Usage
|
||||
<span class="card-badge">LIVE</span>
|
||||
</div>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr><th>Model</th><th>Tokens</th><th>Spend</th><th>Status</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><span class="model-tag">Qwen3-Coder-30B</span></td><td>342K</td><td>$18.40</td><td><span class="status-dot on"></span>Active</td></tr>
|
||||
<tr><td><span class="model-tag">Llama-3.1-70B</span></td><td>285K</td><td>$15.20</td><td><span class="status-dot on"></span>Active</td></tr>
|
||||
<tr><td><span class="model-tag">Mistral-7B</span></td><td>120K</td><td>$8.42</td><td><span class="status-dot on"></span>Active</td></tr>
|
||||
<tr><td><span class="model-tag">Gemma-2-9B</span></td><td>65K</td><td>$3.80</td><td><span class="status-dot on"></span>Active</td></tr>
|
||||
<tr><td><span class="model-tag">Phi-3-mini</span></td><td>35K</td><td>$2.00</td><td><span class="status-dot off"></span>Idle</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-title">Activity Log</div>
|
||||
<div class="activity-item">
|
||||
<span class="activity-time">2m ago</span>
|
||||
<span class="activity-text"><strong>Erika M.</strong> queried <span class="hl">Qwen3-Coder</span></span>
|
||||
</div>
|
||||
<div class="activity-item">
|
||||
<span class="activity-time">8m ago</span>
|
||||
<span class="activity-text"><strong>Johann S.</strong> deployed agent <span class="hl">doc-parser</span></span>
|
||||
</div>
|
||||
<div class="activity-item">
|
||||
<span class="activity-time">14m ago</span>
|
||||
<span class="activity-text"><strong>Anna W.</strong> viewed analytics trace</span>
|
||||
</div>
|
||||
<div class="activity-item">
|
||||
<span class="activity-time">31m ago</span>
|
||||
<span class="activity-text"><strong>Max M.</strong> rotated API key for <span class="hl">LiteLLM</span></span>
|
||||
</div>
|
||||
<div class="activity-item">
|
||||
<span class="activity-time">1h ago</span>
|
||||
<span class="activity-text">System: <span class="hl">Llama-3.1-70B</span> model health check passed</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function showView(id) {
|
||||
document.querySelectorAll('.view').forEach(v => v.classList.remove('active'));
|
||||
document.querySelectorAll('.view-switcher button').forEach(b => b.classList.remove('active'));
|
||||
document.getElementById(id).classList.add('active');
|
||||
event.target.classList.add('active');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
963
design-templates/03-warm-studio.html
Normal file
@@ -0,0 +1,963 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CERTifAI - Template 3: Warm Studio</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,500;0,9..144,600;0,9..144,700;0,9..144,800;1,9..144,400;1,9..144,500&family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ========================================================================
|
||||
TEMPLATE 3: WARM STUDIO
|
||||
========================================================================
|
||||
Mood: Warm, approachable, creative studio atmosphere
|
||||
Audience: Creative agencies, education, non-technical leadership
|
||||
Palette: Warm cream/sand base, terracotta/amber accents, soft shadows
|
||||
Fonts: Fraunces (headings) + Plus Jakarta Sans (body)
|
||||
Feel: Friendly, human, inviting, like a well-designed co-working space
|
||||
======================================================================== */
|
||||
|
||||
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
:root {
|
||||
--bg-warm: #faf6f1;
|
||||
--bg-white: #ffffff;
|
||||
--bg-cream: #f5efe7;
|
||||
--bg-sand: #ede4d8;
|
||||
--bg-dark: #2c2622;
|
||||
--text-dark: #2c2622;
|
||||
--text-body: #5c524a;
|
||||
--text-muted: #9a8e84;
|
||||
--text-light: #c4b8ac;
|
||||
--text-inverse: #faf6f1;
|
||||
--terracotta: #c4653a;
|
||||
--terracotta-light: #d77a54;
|
||||
--terracotta-muted: rgba(196, 101, 58, 0.08);
|
||||
--terracotta-border: rgba(196, 101, 58, 0.18);
|
||||
--amber: #c99a2e;
|
||||
--amber-muted: rgba(201, 154, 46, 0.1);
|
||||
--sage: #6b8a6b;
|
||||
--sage-muted: rgba(107, 138, 107, 0.1);
|
||||
--border: #e8dfd5;
|
||||
--border-subtle: #f0e9e0;
|
||||
--shadow-warm: 0 2px 12px rgba(44, 38, 34, 0.06);
|
||||
--shadow-lg: 0 8px 32px rgba(44, 38, 34, 0.08);
|
||||
--radius: 14px;
|
||||
--radius-sm: 8px;
|
||||
--radius-xl: 24px;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
color: var(--text-body);
|
||||
background: var(--bg-warm);
|
||||
line-height: 1.65;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
font-family: 'Fraunces', serif;
|
||||
color: var(--text-dark);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* ===== View Switcher ===== */
|
||||
.view-switcher {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
background: var(--bg-dark);
|
||||
padding: 5px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 24px rgba(0,0,0,0.15);
|
||||
}
|
||||
.view-switcher button {
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
padding: 8px 18px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
color: rgba(250,246,241,0.4);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.view-switcher button.active {
|
||||
background: var(--terracotta);
|
||||
color: #fff;
|
||||
}
|
||||
.view-switcher button:hover:not(.active) { color: rgba(250,246,241,0.7); }
|
||||
|
||||
.view { display: none; }
|
||||
.view.active { display: block; }
|
||||
|
||||
/* ===== LANDING ===== */
|
||||
|
||||
.landing-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20px 56px;
|
||||
background: rgba(250, 246, 241, 0.9);
|
||||
backdrop-filter: blur(16px);
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
.nav-logo {
|
||||
font-family: 'Fraunces', serif;
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: var(--text-dark);
|
||||
}
|
||||
.nav-logo em { font-style: italic; color: var(--terracotta); }
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
list-style: none;
|
||||
}
|
||||
.nav-links a {
|
||||
text-decoration: none;
|
||||
color: var(--text-muted);
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.nav-links a:hover { color: var(--text-dark); }
|
||||
.nav-cta { display: flex; gap: 12px; }
|
||||
.btn-ghost {
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
padding: 10px 22px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--text-muted);
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius-sm);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.btn-ghost:hover { color: var(--text-dark); background: var(--bg-cream); }
|
||||
.btn-primary {
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
padding: 10px 26px;
|
||||
border: none;
|
||||
background: var(--terracotta);
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius-sm);
|
||||
transition: all 0.25s;
|
||||
}
|
||||
.btn-primary:hover { background: var(--terracotta-light); transform: translateY(-1px); box-shadow: var(--shadow-warm); }
|
||||
.btn-outline {
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
padding: 12px 28px;
|
||||
border: 1.5px solid var(--border);
|
||||
background: var(--bg-white);
|
||||
color: var(--text-dark);
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius-sm);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.btn-outline:hover { border-color: var(--terracotta-border); }
|
||||
|
||||
/* -- Hero -- */
|
||||
.hero {
|
||||
padding: 100px 56px 80px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 64px;
|
||||
align-items: center;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.hero-text { animation: fadeUp 0.6s ease; }
|
||||
.hero-eyebrow {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--terracotta);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.hero h1 {
|
||||
font-size: 52px;
|
||||
font-weight: 800;
|
||||
letter-spacing: -1px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.hero h1 em {
|
||||
font-style: italic;
|
||||
font-weight: 500;
|
||||
color: var(--terracotta);
|
||||
}
|
||||
.hero p {
|
||||
font-size: 17px;
|
||||
line-height: 1.7;
|
||||
color: var(--text-body);
|
||||
margin-bottom: 36px;
|
||||
max-width: 480px;
|
||||
}
|
||||
.hero-actions { display: flex; gap: 14px; }
|
||||
|
||||
.hero-visual {
|
||||
position: relative;
|
||||
animation: fadeUp 0.6s ease 0.2s both;
|
||||
}
|
||||
.hero-card {
|
||||
background: var(--bg-white);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-xl);
|
||||
padding: 32px;
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
.hero-card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.hero-card-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background: var(--sage);
|
||||
}
|
||||
.hero-card-label {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.hero-metric {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.hero-metric-label {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.hero-metric-value {
|
||||
font-family: 'Fraunces', serif;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: var(--text-dark);
|
||||
}
|
||||
.hero-bar {
|
||||
height: 8px;
|
||||
background: var(--bg-cream);
|
||||
border-radius: 100px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.hero-bar-fill {
|
||||
height: 100%;
|
||||
border-radius: 100px;
|
||||
background: linear-gradient(90deg, var(--terracotta), var(--amber));
|
||||
width: 68%;
|
||||
}
|
||||
.hero-models {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.hero-model-chip {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
padding: 6px 14px;
|
||||
background: var(--bg-cream);
|
||||
border-radius: 100px;
|
||||
color: var(--text-body);
|
||||
}
|
||||
.hero-floating-badge {
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
right: -12px;
|
||||
background: var(--sage);
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
padding: 8px 16px;
|
||||
border-radius: 100px;
|
||||
box-shadow: var(--shadow-warm);
|
||||
}
|
||||
|
||||
/* -- Trust -- */
|
||||
.trust-bar {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 40px;
|
||||
padding: 48px 56px;
|
||||
background: var(--bg-white);
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
}
|
||||
.trust-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.trust-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--terracotta-muted);
|
||||
border-radius: var(--radius-sm);
|
||||
color: var(--terracotta);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* -- Features -- */
|
||||
.features {
|
||||
padding: 100px 56px;
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.section-header {
|
||||
text-align: center;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
.section-header h2 {
|
||||
font-size: 38px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.section-header p {
|
||||
font-size: 16px;
|
||||
color: var(--text-muted);
|
||||
max-width: 440px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 20px;
|
||||
}
|
||||
.feature-card {
|
||||
padding: 28px;
|
||||
background: var(--bg-white);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.feature-card:hover {
|
||||
box-shadow: var(--shadow-warm);
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
.feature-emoji {
|
||||
font-size: 28px;
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--bg-cream);
|
||||
border-radius: 12px;
|
||||
}
|
||||
.feature-card h3 {
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.feature-card p {
|
||||
font-size: 14px;
|
||||
color: var(--text-muted);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* -- CTA -- */
|
||||
.cta-section {
|
||||
padding: 60px 56px 80px;
|
||||
}
|
||||
.cta-box {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 56px;
|
||||
background: var(--bg-dark);
|
||||
border-radius: var(--radius-xl);
|
||||
text-align: center;
|
||||
color: var(--text-inverse);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.cta-box::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -60px;
|
||||
right: -60px;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: var(--terracotta);
|
||||
border-radius: 50%;
|
||||
opacity: 0.15;
|
||||
}
|
||||
.cta-box h2 {
|
||||
font-size: 34px;
|
||||
color: var(--text-inverse);
|
||||
margin-bottom: 12px;
|
||||
position: relative;
|
||||
}
|
||||
.cta-box p {
|
||||
font-size: 15px;
|
||||
color: rgba(250,246,241,0.6);
|
||||
margin-bottom: 28px;
|
||||
position: relative;
|
||||
}
|
||||
.btn-warm {
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
padding: 14px 32px;
|
||||
border: none;
|
||||
background: var(--terracotta);
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius-sm);
|
||||
position: relative;
|
||||
transition: all 0.25s;
|
||||
}
|
||||
.btn-warm:hover { background: var(--terracotta-light); }
|
||||
|
||||
.landing-footer {
|
||||
padding: 40px 56px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 13px;
|
||||
color: var(--text-light);
|
||||
}
|
||||
.footer-links { display: flex; gap: 24px; }
|
||||
.footer-links a { color: var(--text-light); text-decoration: none; }
|
||||
.footer-links a:hover { color: var(--text-dark); }
|
||||
|
||||
/* ===== DASHBOARD ===== */
|
||||
|
||||
.dashboard-layout {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
background: var(--bg-warm);
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 260px;
|
||||
min-width: 260px;
|
||||
background: var(--bg-white);
|
||||
border-right: 1px solid var(--border);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
.sidebar-brand {
|
||||
padding: 24px;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
}
|
||||
.sidebar-brand h2 {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.sidebar-brand em { font-style: italic; color: var(--terracotta); }
|
||||
.sidebar-user {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 20px 24px;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
}
|
||||
.user-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 12px;
|
||||
background: linear-gradient(135deg, var(--terracotta), var(--amber));
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.user-name { font-size: 14px; font-weight: 600; color: var(--text-dark); }
|
||||
.user-email { font-size: 12px; color: var(--text-muted); }
|
||||
.sidebar-nav {
|
||||
flex: 1;
|
||||
padding: 16px 12px;
|
||||
}
|
||||
.nav-section {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--text-light);
|
||||
padding: 16px 16px 6px;
|
||||
}
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 10px 16px;
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--text-body);
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
text-decoration: none;
|
||||
}
|
||||
.nav-item:hover { background: var(--bg-cream); }
|
||||
.nav-item.active {
|
||||
background: var(--terracotta-muted);
|
||||
color: var(--terracotta);
|
||||
font-weight: 600;
|
||||
}
|
||||
.sidebar-footer {
|
||||
padding: 16px 24px;
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
font-size: 12px;
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
padding: 40px 48px;
|
||||
min-width: 0;
|
||||
}
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
.page-title {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.page-subtitle {
|
||||
font-size: 15px;
|
||||
color: var(--text-muted);
|
||||
margin-top: 4px;
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
}
|
||||
|
||||
/* -- Welcome Card -- */
|
||||
.welcome-card {
|
||||
background: linear-gradient(135deg, var(--bg-dark) 0%, #3d3530 100%);
|
||||
border-radius: var(--radius-xl);
|
||||
padding: 36px 40px;
|
||||
margin-bottom: 28px;
|
||||
color: var(--text-inverse);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.welcome-text h2 {
|
||||
font-size: 24px;
|
||||
color: var(--text-inverse);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.welcome-text p {
|
||||
font-size: 14px;
|
||||
color: rgba(250,246,241,0.6);
|
||||
}
|
||||
.welcome-stats {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
}
|
||||
.welcome-stat-value {
|
||||
font-family: 'Fraunces', serif;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: var(--terracotta-light);
|
||||
}
|
||||
.welcome-stat-label {
|
||||
font-size: 12px;
|
||||
color: rgba(250,246,241,0.5);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* -- Stats -- */
|
||||
.stats-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
.stat-card {
|
||||
padding: 24px;
|
||||
background: var(--bg-white);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.stat-card:hover { box-shadow: var(--shadow-warm); }
|
||||
.stat-label {
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.stat-value {
|
||||
font-family: 'Fraunces', serif;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: var(--text-dark);
|
||||
}
|
||||
.stat-badge {
|
||||
display: inline-block;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
padding: 3px 10px;
|
||||
border-radius: 100px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
.stat-badge.up { background: var(--sage-muted); color: var(--sage); }
|
||||
.stat-badge.neutral { background: var(--amber-muted); color: var(--amber); }
|
||||
|
||||
/* -- Content Grid -- */
|
||||
.content-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 3fr 2fr;
|
||||
gap: 20px;
|
||||
}
|
||||
.card {
|
||||
background: var(--bg-white);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
padding: 24px;
|
||||
}
|
||||
.card-title {
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: var(--text-dark);
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.data-table th {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: var(--text-light);
|
||||
text-align: left;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.data-table td {
|
||||
font-size: 14px;
|
||||
padding: 14px 0;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
color: var(--text-body);
|
||||
}
|
||||
.data-table tr:last-child td { border-bottom: none; }
|
||||
.model-chip {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
padding: 4px 12px;
|
||||
background: var(--bg-cream);
|
||||
border-radius: 100px;
|
||||
color: var(--text-body);
|
||||
}
|
||||
|
||||
/* -- Quick Actions -- */
|
||||
.quick-actions {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 10px;
|
||||
}
|
||||
.quick-action {
|
||||
padding: 18px;
|
||||
background: var(--bg-cream);
|
||||
border-radius: var(--radius-sm);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
}
|
||||
.quick-action:hover { background: var(--bg-sand); }
|
||||
.quick-action-icon {
|
||||
font-size: 20px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.quick-action-title {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--text-dark);
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.quick-action-desc {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* ===== Animations ===== */
|
||||
@keyframes fadeUp {
|
||||
from { opacity: 0; transform: translateY(16px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="view-switcher">
|
||||
<button class="active" onclick="showView('landing')">Landing</button>
|
||||
<button onclick="showView('dashboard')">Dashboard</button>
|
||||
</div>
|
||||
|
||||
<!-- ===== LANDING ===== -->
|
||||
<div id="landing" class="view active">
|
||||
<nav class="landing-nav">
|
||||
<div class="nav-logo">Cert<em>if</em>AI</div>
|
||||
<ul class="nav-links">
|
||||
<li><a href="#">Features</a></li>
|
||||
<li><a href="#">How It Works</a></li>
|
||||
<li><a href="#">Pricing</a></li>
|
||||
<li><a href="#">Contact</a></li>
|
||||
</ul>
|
||||
<div class="nav-cta">
|
||||
<button class="btn-ghost">Sign In</button>
|
||||
<button class="btn-primary">Get Started</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section class="hero">
|
||||
<div class="hero-text">
|
||||
<div class="hero-eyebrow">Private AI Infrastructure</div>
|
||||
<h1>AI that stays <em>in-house</em></h1>
|
||||
<p>A friendly, powerful dashboard for managing your self-hosted GenAI tools. No data leaves your servers. No compromises on capability.</p>
|
||||
<div class="hero-actions">
|
||||
<button class="btn-primary" style="padding:14px 32px; font-size:15px;">Start Free Trial</button>
|
||||
<button class="btn-outline" style="padding:14px 32px; font-size:15px;">Watch Demo</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-visual">
|
||||
<div class="hero-floating-badge">5 models live</div>
|
||||
<div class="hero-card">
|
||||
<div class="hero-card-header">
|
||||
<div class="hero-card-dot"></div>
|
||||
<span class="hero-card-label">System Overview</span>
|
||||
</div>
|
||||
<div class="hero-metric">
|
||||
<div class="hero-metric-label">Token usage this month</div>
|
||||
<div class="hero-metric-value">847,000</div>
|
||||
</div>
|
||||
<div class="hero-bar"><div class="hero-bar-fill"></div></div>
|
||||
<div class="hero-models">
|
||||
<span class="hero-model-chip">Qwen3-Coder</span>
|
||||
<span class="hero-model-chip">Llama 3.1</span>
|
||||
<span class="hero-model-chip">Mistral</span>
|
||||
<span class="hero-model-chip">Gemma 2</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="trust-bar">
|
||||
<div class="trust-item"><div class="trust-icon">☑</div>100% On-Premise</div>
|
||||
<div class="trust-item"><div class="trust-icon">⚖</div>GDPR Compliant</div>
|
||||
<div class="trust-item"><div class="trust-icon">⚑</div>EU Data Only</div>
|
||||
<div class="trust-item"><div class="trust-icon">◯</div>Zero Third-Party</div>
|
||||
</div>
|
||||
|
||||
<section class="features">
|
||||
<div class="section-header">
|
||||
<h2>Everything you need, nothing you don't</h2>
|
||||
<p>Simple tools for managing sophisticated AI infrastructure.</p>
|
||||
</div>
|
||||
<div class="features-grid">
|
||||
<div class="feature-card">
|
||||
<div class="feature-emoji">⚙</div>
|
||||
<h3>Self-Hosted Infrastructure</h3>
|
||||
<p>Your hardware, your cloud, your rules. Deploy with a single command.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-emoji">☍</div>
|
||||
<h3>Multi-Model Gateway</h3>
|
||||
<p>One API for all your models. Switch providers without changing a line of code.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-emoji">❖</div>
|
||||
<h3>Visual Agent Builder</h3>
|
||||
<p>Drag-and-drop workflows for building AI agents that actually work.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-emoji">⏻</div>
|
||||
<h3>Single Sign-On</h3>
|
||||
<p>Connect your existing identity provider. One login for everything.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-emoji">☰</div>
|
||||
<h3>Usage Analytics</h3>
|
||||
<p>Track every token, every dollar, every model. Full transparency.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-emoji">➔</div>
|
||||
<h3>API & Integrations</h3>
|
||||
<p>REST APIs, webhooks, and MCP server support out of the box.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="cta-section">
|
||||
<div class="cta-box">
|
||||
<h2>Let's get you set up</h2>
|
||||
<p>No credit card. No sales call. Just your AI infrastructure, ready in minutes.</p>
|
||||
<button class="btn-warm">Start Your Free Trial</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer class="landing-footer">
|
||||
<span>© 2026 CERTifAI</span>
|
||||
<div class="footer-links">
|
||||
<a href="#">Privacy</a>
|
||||
<a href="#">Impressum</a>
|
||||
<a href="#">Contact</a>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<!-- ===== DASHBOARD ===== -->
|
||||
<div id="dashboard" class="view">
|
||||
<div class="dashboard-layout">
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-brand"><h2>Cert<em>if</em>AI</h2></div>
|
||||
<div class="sidebar-user">
|
||||
<div class="user-avatar">MM</div>
|
||||
<div>
|
||||
<div class="user-name">Max Mustermann</div>
|
||||
<div class="user-email">max@company.de</div>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="sidebar-nav">
|
||||
<div class="nav-section">Main</div>
|
||||
<a class="nav-item active">■ Dashboard</a>
|
||||
<a class="nav-item">◊ Providers</a>
|
||||
<a class="nav-item">✉ Chat</a>
|
||||
<div class="nav-section">Developer</div>
|
||||
<a class="nav-item">⚙ Agents</a>
|
||||
<a class="nav-item">⧉ Workflows</a>
|
||||
<a class="nav-item">☰ Analytics</a>
|
||||
<div class="nav-section">Organization</div>
|
||||
<a class="nav-item">★ Billing</a>
|
||||
<a class="nav-item">❖ Members</a>
|
||||
</nav>
|
||||
<div class="sidebar-footer">v0.1.0</div>
|
||||
</aside>
|
||||
|
||||
<main class="main-content">
|
||||
<div class="page-header">
|
||||
<div>
|
||||
<h1 class="page-title">Good morning, Max</h1>
|
||||
<p class="page-subtitle">Here's what's happening with your AI stack today.</p>
|
||||
</div>
|
||||
<button class="btn-primary">New Search</button>
|
||||
</div>
|
||||
|
||||
<div class="welcome-card">
|
||||
<div class="welcome-text">
|
||||
<h2>February Overview</h2>
|
||||
<p>Your team used 847K tokens across 5 models this month.</p>
|
||||
</div>
|
||||
<div class="welcome-stats">
|
||||
<div>
|
||||
<div class="welcome-stat-value">$47.82</div>
|
||||
<div class="welcome-stat-label">Total spend</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="welcome-stat-value">4/25</div>
|
||||
<div class="welcome-stat-label">Seats used</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-row">
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Active Models</div>
|
||||
<div class="stat-value">5</div>
|
||||
<span class="stat-badge up">All healthy</span>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Agents Running</div>
|
||||
<div class="stat-value">3</div>
|
||||
<span class="stat-badge neutral">2 idle</span>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Billing Cycle Ends</div>
|
||||
<div class="stat-value">Mar 1</div>
|
||||
<span class="stat-badge up">3 days left</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-grid">
|
||||
<div class="card">
|
||||
<div class="card-title">Usage by Model</div>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr><th>Model</th><th>Tokens</th><th>Spend</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><span class="model-chip">Qwen3-Coder-30B</span></td><td>342K</td><td>$18.40</td></tr>
|
||||
<tr><td><span class="model-chip">Llama-3.1-70B</span></td><td>285K</td><td>$15.20</td></tr>
|
||||
<tr><td><span class="model-chip">Mistral-7B</span></td><td>120K</td><td>$8.42</td></tr>
|
||||
<tr><td><span class="model-chip">Gemma-2-9B</span></td><td>65K</td><td>$3.80</td></tr>
|
||||
<tr><td><span class="model-chip">Phi-3-mini</span></td><td>35K</td><td>$2.00</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-title">Quick Actions</div>
|
||||
<div class="quick-actions">
|
||||
<a class="quick-action">
|
||||
<div class="quick-action-icon">✉</div>
|
||||
<div class="quick-action-title">Open Chat</div>
|
||||
<div class="quick-action-desc">Ask your models anything</div>
|
||||
</a>
|
||||
<a class="quick-action">
|
||||
<div class="quick-action-icon">⚙</div>
|
||||
<div class="quick-action-title">Manage Agents</div>
|
||||
<div class="quick-action-desc">View running agents</div>
|
||||
</a>
|
||||
<a class="quick-action">
|
||||
<div class="quick-action-icon">☰</div>
|
||||
<div class="quick-action-title">View Analytics</div>
|
||||
<div class="quick-action-desc">Langfuse dashboard</div>
|
||||
</a>
|
||||
<a class="quick-action">
|
||||
<div class="quick-action-icon">❖</div>
|
||||
<div class="quick-action-title">Invite Team</div>
|
||||
<div class="quick-action-desc">Add new members</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function showView(id) {
|
||||
document.querySelectorAll('.view').forEach(v => v.classList.remove('active'));
|
||||
document.querySelectorAll('.view-switcher button').forEach(b => b.classList.remove('active'));
|
||||
document.getElementById(id).classList.add('active');
|
||||
event.target.classList.add('active');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
963
design-templates/04-glass-aurora.html
Normal file
@@ -0,0 +1,963 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CERTifAI - Template 4: Glass Aurora</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?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" rel="stylesheet">
|
||||
<style>
|
||||
/* ========================================================================
|
||||
TEMPLATE 4: GLASS AURORA
|
||||
========================================================================
|
||||
Mood: Vibrant, modern, glassmorphic, bold gradients
|
||||
Audience: SaaS-savvy buyers, modern enterprises, AI-native teams
|
||||
Palette: Deep navy/purple base, aurora gradient accents, glass effects
|
||||
Fonts: Sora (headings) + Literata (body)
|
||||
Feel: Premium SaaS, forward-looking, rich, confident
|
||||
======================================================================== */
|
||||
|
||||
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
:root {
|
||||
--bg-deep: #0c0a1d;
|
||||
--bg-primary: #100e24;
|
||||
--bg-card: rgba(22, 19, 48, 0.7);
|
||||
--bg-glass: rgba(255, 255, 255, 0.04);
|
||||
--bg-glass-hover: rgba(255, 255, 255, 0.07);
|
||||
--text-bright: #f4f0ff;
|
||||
--text-primary: #cfc8e8;
|
||||
--text-secondary: #8b82aa;
|
||||
--text-muted: #5a5280;
|
||||
--gradient-start: #6366f1;
|
||||
--gradient-mid: #a855f7;
|
||||
--gradient-end: #ec4899;
|
||||
--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;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Literata', serif;
|
||||
color: var(--text-primary);
|
||||
background: var(--bg-deep);
|
||||
line-height: 1.7;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-weight: 700;
|
||||
line-height: 1.15;
|
||||
color: var(--text-bright);
|
||||
}
|
||||
|
||||
/* ===== View Switcher ===== */
|
||||
.view-switcher {
|
||||
position: fixed;
|
||||
top: 16px;
|
||||
right: 16px;
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
background: var(--bg-card);
|
||||
backdrop-filter: blur(20px);
|
||||
border: 1px solid var(--glass-border);
|
||||
padding: 4px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.view-switcher button {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
padding: 8px 18px;
|
||||
border-radius: 9px;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
color: var(--text-muted);
|
||||
transition: all 0.25s;
|
||||
}
|
||||
.view-switcher button.active {
|
||||
background: var(--aurora);
|
||||
color: #fff;
|
||||
}
|
||||
.view-switcher button:hover:not(.active) { color: var(--text-primary); }
|
||||
|
||||
.view { display: none; }
|
||||
.view.active { display: block; }
|
||||
|
||||
/* ===== LANDING ===== */
|
||||
|
||||
.landing-bg {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.landing-bg::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-bg::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 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 18px 56px;
|
||||
background: rgba(16, 14, 36, 0.6);
|
||||
backdrop-filter: blur(24px);
|
||||
border-bottom: 1px solid var(--glass-border);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
.nav-logo {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
background: var(--aurora);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
list-style: none;
|
||||
}
|
||||
.nav-links a {
|
||||
text-decoration: none;
|
||||
color: var(--text-secondary);
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.nav-links a:hover { color: var(--text-bright); }
|
||||
.nav-cta { display: flex; gap: 10px; }
|
||||
.btn-ghost {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
padding: 10px 22px;
|
||||
border: 1px solid var(--glass-border);
|
||||
background: transparent;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius-sm);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.btn-ghost:hover { border-color: var(--glass-border-bright); color: var(--text-bright); }
|
||||
.btn-primary {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
padding: 10px 24px;
|
||||
border: none;
|
||||
background: var(--aurora);
|
||||
background-size: 200% 200%;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius-sm);
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.btn-primary:hover { background-position: 100% 0; transform: translateY(-1px); box-shadow: 0 4px 24px rgba(139,92,246,0.3); }
|
||||
|
||||
/* -- Hero -- */
|
||||
.hero {
|
||||
padding: 120px 56px 100px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
.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;
|
||||
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;
|
||||
}
|
||||
.hero h1 {
|
||||
font-size: 68px;
|
||||
letter-spacing: -2px;
|
||||
margin-bottom: 20px;
|
||||
animation: fadeUp 0.6s ease 0.1s both;
|
||||
}
|
||||
.hero h1 .gradient-text {
|
||||
background: var(--aurora);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
.hero p {
|
||||
font-size: 17px;
|
||||
color: var(--text-secondary);
|
||||
max-width: 540px;
|
||||
margin: 0 auto 40px;
|
||||
animation: fadeUp 0.6s ease 0.2s both;
|
||||
}
|
||||
.hero-actions {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
justify-content: center;
|
||||
animation: fadeUp 0.6s ease 0.3s both;
|
||||
}
|
||||
.btn-lg { padding: 14px 36px; font-size: 14px; }
|
||||
.btn-glass {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
padding: 14px 36px;
|
||||
background: var(--bg-glass);
|
||||
backdrop-filter: blur(8px);
|
||||
border: 1px solid var(--glass-border);
|
||||
color: var(--text-primary);
|
||||
cursor: pointer;
|
||||
border-radius: var(--radius-sm);
|
||||
transition: all 0.25s;
|
||||
}
|
||||
.btn-glass:hover { background: var(--bg-glass-hover); border-color: var(--glass-border-bright); }
|
||||
|
||||
/* -- Glass Preview -- */
|
||||
.preview-container {
|
||||
max-width: 900px;
|
||||
margin: 64px auto 0;
|
||||
animation: fadeUp 0.8s ease 0.4s both;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.preview-stat-value {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: var(--text-bright);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.preview-stat-label {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* -- Trust -- */
|
||||
.trust-bar {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 40px;
|
||||
padding: 48px 56px;
|
||||
border-top: 1px solid var(--glass-border);
|
||||
}
|
||||
.trust-item {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: var(--text-muted);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.trust-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: var(--aurora);
|
||||
}
|
||||
|
||||
/* -- Features -- */
|
||||
.features {
|
||||
padding: 100px 56px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.section-header {
|
||||
text-align: center;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
.section-header h2 { font-size: 40px; letter-spacing: -1px; margin-bottom: 12px; }
|
||||
.section-header p { font-size: 16px; color: var(--text-secondary); max-width: 450px; margin: 0 auto; }
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
.feature-card {
|
||||
padding: 28px;
|
||||
background: var(--bg-card);
|
||||
backdrop-filter: blur(12px);
|
||||
border: 1px solid var(--glass-border);
|
||||
border-radius: var(--radius);
|
||||
transition: all 0.3s;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.feature-card:hover {
|
||||
border-color: var(--glass-border-bright);
|
||||
box-shadow: var(--shadow-glow);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.feature-icon-bar {
|
||||
width: 40px;
|
||||
height: 4px;
|
||||
border-radius: 2px;
|
||||
background: var(--aurora);
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.feature-card h3 {
|
||||
font-size: 16px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.feature-card p {
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* -- CTA -- */
|
||||
.cta-section {
|
||||
padding: 80px 56px;
|
||||
text-align: center;
|
||||
}
|
||||
.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-box h2 { font-size: 32px; margin-bottom: 12px; }
|
||||
.cta-box p { font-size: 15px; color: var(--text-secondary); margin-bottom: 28px; }
|
||||
|
||||
.landing-footer {
|
||||
padding: 40px 56px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-top: 1px solid var(--glass-border);
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.footer-links { display: flex; gap: 24px; }
|
||||
.footer-links a { color: var(--text-muted); text-decoration: none; }
|
||||
.footer-links a:hover { color: var(--text-bright); }
|
||||
|
||||
/* ===== DASHBOARD ===== */
|
||||
|
||||
.dashboard-layout {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
background: var(--bg-deep);
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 256px;
|
||||
min-width: 256px;
|
||||
background: rgba(16, 14, 36, 0.8);
|
||||
backdrop-filter: blur(20px);
|
||||
border-right: 1px solid var(--glass-border);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
.sidebar-brand {
|
||||
padding: 22px 20px;
|
||||
border-bottom: 1px solid var(--glass-border);
|
||||
}
|
||||
.sidebar-brand h2 {
|
||||
font-size: 20px;
|
||||
font-weight: 800;
|
||||
background: var(--aurora);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
.sidebar-user {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 18px 20px;
|
||||
border-bottom: 1px solid var(--glass-border);
|
||||
}
|
||||
.user-avatar {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 10px;
|
||||
background: var(--aurora);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.user-name { font-family: 'Sora', sans-serif; font-size: 13px; font-weight: 600; color: var(--text-bright); }
|
||||
.user-email { font-family: 'Sora', sans-serif; font-size: 11px; color: var(--text-muted); }
|
||||
.sidebar-nav {
|
||||
flex: 1;
|
||||
padding: 12px 10px;
|
||||
}
|
||||
.nav-group {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--text-muted);
|
||||
padding: 14px 14px 6px;
|
||||
}
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 9px 14px;
|
||||
border-radius: var(--radius-sm);
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
text-decoration: none;
|
||||
}
|
||||
.nav-item:hover { background: var(--bg-glass-hover); color: var(--text-primary); }
|
||||
.nav-item.active {
|
||||
background: rgba(99,102,241,0.12);
|
||||
color: #a5b4fc;
|
||||
font-weight: 600;
|
||||
}
|
||||
.sidebar-footer {
|
||||
padding: 14px 20px;
|
||||
border-top: 1px solid var(--glass-border);
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
padding: 36px 44px;
|
||||
min-width: 0;
|
||||
}
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.page-title { font-size: 26px; letter-spacing: -0.5px; }
|
||||
.page-subtitle { font-family: 'Sora', sans-serif; font-size: 13px; color: var(--text-muted); margin-top: 4px; }
|
||||
|
||||
/* -- Gradient Banner -- */
|
||||
.gradient-banner {
|
||||
background: var(--aurora);
|
||||
border-radius: var(--radius-xl);
|
||||
padding: 32px 36px;
|
||||
margin-bottom: 24px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.gradient-banner::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: repeating-linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
transparent 100px,
|
||||
rgba(255,255,255,0.03) 100px,
|
||||
rgba(255,255,255,0.03) 101px
|
||||
);
|
||||
}
|
||||
.banner-text h3 { font-size: 20px; margin-bottom: 4px; position: relative; }
|
||||
.banner-text p { font-size: 13px; color: rgba(255,255,255,0.7); position: relative; font-family: 'Sora', sans-serif; }
|
||||
.banner-stats {
|
||||
display: flex;
|
||||
gap: 36px;
|
||||
position: relative;
|
||||
}
|
||||
.banner-stat-value { font-family: 'Sora', sans-serif; font-size: 24px; font-weight: 700; color: #fff; }
|
||||
.banner-stat-label { font-family: 'Sora', sans-serif; font-size: 11px; color: rgba(255,255,255,0.6); }
|
||||
|
||||
/* -- Stats -- */
|
||||
.stats-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 14px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.stat-card {
|
||||
padding: 22px;
|
||||
background: var(--bg-card);
|
||||
backdrop-filter: blur(12px);
|
||||
border: 1px solid var(--glass-border);
|
||||
border-radius: var(--radius);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.stat-card:hover { border-color: var(--glass-border-bright); box-shadow: var(--shadow-glow); }
|
||||
.stat-label {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.stat-value {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
color: var(--text-bright);
|
||||
}
|
||||
.stat-sub {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 11px;
|
||||
margin-top: 4px;
|
||||
color: var(--green);
|
||||
}
|
||||
|
||||
/* -- Grid -- */
|
||||
.content-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 3fr 2fr;
|
||||
gap: 14px;
|
||||
}
|
||||
.card {
|
||||
background: var(--bg-card);
|
||||
backdrop-filter: blur(12px);
|
||||
border: 1px solid var(--glass-border);
|
||||
border-radius: var(--radius);
|
||||
padding: 24px;
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.card-title {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--text-bright);
|
||||
}
|
||||
.card-badge {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
padding: 4px 12px;
|
||||
background: var(--green-dim);
|
||||
color: var(--green);
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.data-table th {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: var(--text-muted);
|
||||
text-align: left;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid var(--glass-border);
|
||||
}
|
||||
.data-table td {
|
||||
font-size: 13px;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid var(--glass-border);
|
||||
}
|
||||
.data-table tr:last-child td { border-bottom: none; }
|
||||
.model-tag {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
padding: 3px 10px;
|
||||
background: var(--bg-glass);
|
||||
border: 1px solid var(--glass-border);
|
||||
border-radius: 6px;
|
||||
}
|
||||
.status-online {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
margin-right: 6px;
|
||||
background: var(--green);
|
||||
box-shadow: 0 0 6px rgba(52,211,153,0.5);
|
||||
}
|
||||
|
||||
/* -- Service Status -- */
|
||||
.service-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 14px 0;
|
||||
border-bottom: 1px solid var(--glass-border);
|
||||
}
|
||||
.service-item:last-child { border-bottom: none; }
|
||||
.service-name {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.service-url {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.service-status {
|
||||
font-family: 'Sora', sans-serif;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
padding: 4px 12px;
|
||||
border-radius: 100px;
|
||||
}
|
||||
.service-status.online {
|
||||
background: var(--green-dim);
|
||||
color: var(--green);
|
||||
}
|
||||
.service-status.offline {
|
||||
background: rgba(248,113,113,0.12);
|
||||
color: #f87171;
|
||||
}
|
||||
|
||||
@keyframes fadeUp {
|
||||
from { opacity: 0; transform: translateY(20px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="view-switcher">
|
||||
<button class="active" onclick="showView('landing')">Landing</button>
|
||||
<button onclick="showView('dashboard')">Dashboard</button>
|
||||
</div>
|
||||
|
||||
<!-- ===== LANDING ===== -->
|
||||
<div id="landing" class="view active landing-bg">
|
||||
<nav class="landing-nav">
|
||||
<div class="nav-logo">CERTifAI</div>
|
||||
<ul class="nav-links">
|
||||
<li><a href="#">Features</a></li>
|
||||
<li><a href="#">Pricing</a></li>
|
||||
<li><a href="#">Docs</a></li>
|
||||
<li><a href="#">Blog</a></li>
|
||||
</ul>
|
||||
<div class="nav-cta">
|
||||
<button class="btn-ghost">Sign In</button>
|
||||
<button class="btn-primary">Get Started Free</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section class="hero">
|
||||
<div class="hero-pills">
|
||||
<span class="pill accent">GDPR Native</span>
|
||||
<span class="pill">Self-Hosted</span>
|
||||
<span class="pill">EU Sovereign</span>
|
||||
</div>
|
||||
<h1>Sovereign AI<br><span class="gradient-text">infrastructure</span></h1>
|
||||
<p>The complete platform for deploying, managing, and scaling private generative AI. Your data never leaves your perimeter.</p>
|
||||
<div class="hero-actions">
|
||||
<button class="btn-primary btn-lg">Start Free Trial</button>
|
||||
<button class="btn-glass">Live Demo</button>
|
||||
</div>
|
||||
|
||||
<div class="preview-container">
|
||||
<div class="glass-preview">
|
||||
<div class="preview-stat">
|
||||
<div class="preview-stat-value">5</div>
|
||||
<div class="preview-stat-label">Active Models</div>
|
||||
</div>
|
||||
<div class="preview-stat">
|
||||
<div class="preview-stat-value">847K</div>
|
||||
<div class="preview-stat-label">Tokens / Month</div>
|
||||
</div>
|
||||
<div class="preview-stat">
|
||||
<div class="preview-stat-value">$47.82</div>
|
||||
<div class="preview-stat-label">Total Spend</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="trust-bar">
|
||||
<div class="trust-item"><div class="trust-dot"></div>100% On-Premise</div>
|
||||
<div class="trust-item"><div class="trust-dot"></div>GDPR Compliant</div>
|
||||
<div class="trust-item"><div class="trust-dot"></div>EU Data Residency</div>
|
||||
<div class="trust-item"><div class="trust-dot"></div>Zero Third-Party</div>
|
||||
</div>
|
||||
|
||||
<section class="features">
|
||||
<div class="section-header">
|
||||
<h2>Your AI, your way</h2>
|
||||
<p>Every tool you need to run production AI without compromise.</p>
|
||||
</div>
|
||||
<div class="features-grid">
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon-bar"></div>
|
||||
<h3>LLM Gateway</h3>
|
||||
<p>Route between any model through a unified API. LiteLLM proxy with full cost tracking.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon-bar"></div>
|
||||
<h3>Agent Platform</h3>
|
||||
<p>Build and deploy LangGraph agents with visual workflows and real-time monitoring.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon-bar"></div>
|
||||
<h3>Observability</h3>
|
||||
<p>Langfuse integration for traces, prompt engineering, and cost attribution.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon-bar"></div>
|
||||
<h3>Identity & SSO</h3>
|
||||
<p>Keycloak-powered auth with SAML, OIDC, and LDAP. One login across services.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon-bar"></div>
|
||||
<h3>MCP Servers</h3>
|
||||
<p>Model Context Protocol for secure, tool-augmented AI with function calling.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon-bar"></div>
|
||||
<h3>API-First</h3>
|
||||
<p>REST endpoints, API keys, webhooks. Plug CERTifAI into your existing stack.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="cta-section">
|
||||
<div class="cta-box">
|
||||
<h2>Deploy in 30 minutes</h2>
|
||||
<p>No credit card required. Full access to every feature.</p>
|
||||
<button class="btn-primary btn-lg">Start Free Trial</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer class="landing-footer">
|
||||
<span>© 2026 CERTifAI GmbH</span>
|
||||
<div class="footer-links">
|
||||
<a href="#">Privacy</a>
|
||||
<a href="#">Impressum</a>
|
||||
<a href="#">Terms</a>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<!-- ===== DASHBOARD ===== -->
|
||||
<div id="dashboard" class="view">
|
||||
<div class="dashboard-layout">
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-brand"><h2>CERTifAI</h2></div>
|
||||
<div class="sidebar-user">
|
||||
<div class="user-avatar">MM</div>
|
||||
<div>
|
||||
<div class="user-name">Max Mustermann</div>
|
||||
<div class="user-email">max@company.de</div>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="sidebar-nav">
|
||||
<div class="nav-group">Main</div>
|
||||
<a class="nav-item active">■ Dashboard</a>
|
||||
<a class="nav-item">◊ Providers</a>
|
||||
<a class="nav-item">✉ Chat</a>
|
||||
<div class="nav-group">Developer</div>
|
||||
<a class="nav-item">❖ Agents</a>
|
||||
<a class="nav-item">⧉ Workflows</a>
|
||||
<a class="nav-item">☰ Analytics</a>
|
||||
<div class="nav-group">Organization</div>
|
||||
<a class="nav-item">★ Billing</a>
|
||||
<a class="nav-item">♟ Members</a>
|
||||
</nav>
|
||||
<div class="sidebar-footer">v0.1.0</div>
|
||||
</aside>
|
||||
|
||||
<main class="main-content">
|
||||
<div class="page-header">
|
||||
<div>
|
||||
<h1 class="page-title">Dashboard</h1>
|
||||
<p class="page-subtitle">AI infrastructure overview</p>
|
||||
</div>
|
||||
<button class="btn-primary">New Search</button>
|
||||
</div>
|
||||
|
||||
<div class="gradient-banner">
|
||||
<div class="banner-text">
|
||||
<h3>February 2026</h3>
|
||||
<p>Your infrastructure is healthy. All models are responding.</p>
|
||||
</div>
|
||||
<div class="banner-stats">
|
||||
<div>
|
||||
<div class="banner-stat-value">$47.82</div>
|
||||
<div class="banner-stat-label">Total Spend</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="banner-stat-value">847K</div>
|
||||
<div class="banner-stat-label">Tokens Used</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-row">
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Active Models</div>
|
||||
<div class="stat-value">5</div>
|
||||
<div class="stat-sub">All responding</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Team Seats</div>
|
||||
<div class="stat-value">4/25</div>
|
||||
<div class="stat-sub">21 available</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Running Agents</div>
|
||||
<div class="stat-value">3</div>
|
||||
<div class="stat-sub">via LangGraph</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Cycle Ends</div>
|
||||
<div class="stat-value">Mar 1</div>
|
||||
<div class="stat-sub" style="color:var(--text-muted)">3 days left</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-grid">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title">Model Usage</div>
|
||||
<span class="card-badge">This Month</span>
|
||||
</div>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr><th>Model</th><th>Tokens</th><th>Spend</th><th>Status</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><span class="model-tag">Qwen3-Coder-30B</span></td><td>342K</td><td>$18.40</td><td><span class="status-online"></span>Active</td></tr>
|
||||
<tr><td><span class="model-tag">Llama-3.1-70B</span></td><td>285K</td><td>$15.20</td><td><span class="status-online"></span>Active</td></tr>
|
||||
<tr><td><span class="model-tag">Mistral-7B</span></td><td>120K</td><td>$8.42</td><td><span class="status-online"></span>Active</td></tr>
|
||||
<tr><td><span class="model-tag">Gemma-2-9B</span></td><td>65K</td><td>$3.80</td><td><span class="status-online"></span>Active</td></tr>
|
||||
<tr><td><span class="model-tag">Phi-3-mini</span></td><td>35K</td><td>$2.00</td><td style="color:var(--text-muted)">Idle</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title">Services</div>
|
||||
</div>
|
||||
<div class="service-item">
|
||||
<div>
|
||||
<div class="service-name">LiteLLM Proxy</div>
|
||||
<div class="service-url">llm-dev.meghsakha.com</div>
|
||||
</div>
|
||||
<span class="service-status online">Online</span>
|
||||
</div>
|
||||
<div class="service-item">
|
||||
<div>
|
||||
<div class="service-name">LangGraph</div>
|
||||
<div class="service-url">agents.internal</div>
|
||||
</div>
|
||||
<span class="service-status online">Online</span>
|
||||
</div>
|
||||
<div class="service-item">
|
||||
<div>
|
||||
<div class="service-name">Langfuse</div>
|
||||
<div class="service-url">analytics.internal</div>
|
||||
</div>
|
||||
<span class="service-status online">Online</span>
|
||||
</div>
|
||||
<div class="service-item">
|
||||
<div>
|
||||
<div class="service-name">LangFlow</div>
|
||||
<div class="service-url">--</div>
|
||||
</div>
|
||||
<span class="service-status offline">Not Configured</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function showView(id) {
|
||||
document.querySelectorAll('.view').forEach(v => v.classList.remove('active'));
|
||||
document.querySelectorAll('.view-switcher button').forEach(b => b.classList.remove('active'));
|
||||
document.getElementById(id).classList.add('active');
|
||||
event.target.classList.add('active');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
928
design-templates/05-swiss-grid.html
Normal file
@@ -0,0 +1,928 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>CERTifAI - Template 5: Swiss Grid</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/* ========================================================================
|
||||
TEMPLATE 5: SWISS GRID
|
||||
========================================================================
|
||||
Mood: Structured, editorial, Swiss design / International Typographic Style
|
||||
Audience: Government, defense, Mittelstand, compliance-heavy industries
|
||||
Palette: High-contrast B&W with a single signal red accent
|
||||
Fonts: IBM Plex Sans (body) + IBM Plex Mono (data/code)
|
||||
Feel: Authoritative, engineered, precise, like a Braun product manual
|
||||
======================================================================== */
|
||||
|
||||
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
:root {
|
||||
--bg-white: #ffffff;
|
||||
--bg-light: #f5f5f5;
|
||||
--bg-warm: #fafafa;
|
||||
--bg-dark: #111111;
|
||||
--bg-darkgrey: #1a1a1a;
|
||||
--text-black: #111111;
|
||||
--text-dark: #333333;
|
||||
--text-body: #555555;
|
||||
--text-muted: #888888;
|
||||
--text-light: #bbbbbb;
|
||||
--text-inverse: #ffffff;
|
||||
--red: #e63525;
|
||||
--red-muted: rgba(230, 53, 37, 0.06);
|
||||
--red-border: rgba(230, 53, 37, 0.15);
|
||||
--green: #1a8754;
|
||||
--green-muted: rgba(26, 135, 84, 0.08);
|
||||
--border: #e5e5e5;
|
||||
--border-dark: #d0d0d0;
|
||||
--shadow: 0 1px 3px rgba(0,0,0,0.04);
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'IBM Plex Sans', sans-serif;
|
||||
color: var(--text-dark);
|
||||
background: var(--bg-white);
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
font-family: 'IBM Plex Sans', sans-serif;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
color: var(--text-black);
|
||||
}
|
||||
|
||||
/* ===== View Switcher ===== */
|
||||
.view-switcher {
|
||||
position: fixed;
|
||||
top: 16px;
|
||||
right: 16px;
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
gap: 0;
|
||||
background: var(--bg-dark);
|
||||
padding: 3px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.view-switcher button {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
color: rgba(255,255,255,0.35);
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.view-switcher button.active {
|
||||
background: var(--red);
|
||||
color: #fff;
|
||||
}
|
||||
.view-switcher button:hover:not(.active) { color: rgba(255,255,255,0.7); }
|
||||
|
||||
.view { display: none; }
|
||||
.view.active { display: block; }
|
||||
|
||||
/* ===== LANDING ===== */
|
||||
|
||||
.landing-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 56px;
|
||||
height: 64px;
|
||||
background: var(--bg-white);
|
||||
border-bottom: 2px solid var(--text-black);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
.nav-logo {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: var(--text-black);
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
.nav-logo .red { color: var(--red); }
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
list-style: none;
|
||||
}
|
||||
.nav-links a {
|
||||
text-decoration: none;
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.03em;
|
||||
text-transform: uppercase;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.nav-links a:hover { color: var(--text-black); }
|
||||
.nav-cta { display: flex; gap: 0; }
|
||||
.btn-dark {
|
||||
font-family: 'IBM Plex Sans', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
padding: 10px 28px;
|
||||
border: 2px solid var(--text-black);
|
||||
background: var(--text-black);
|
||||
color: var(--text-inverse);
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.btn-dark:hover { background: var(--red); border-color: var(--red); }
|
||||
.btn-bordered {
|
||||
font-family: 'IBM Plex Sans', sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
padding: 10px 28px;
|
||||
border: 2px solid var(--text-black);
|
||||
background: transparent;
|
||||
color: var(--text-black);
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.btn-bordered:hover { background: var(--bg-light); }
|
||||
|
||||
/* -- Hero -- */
|
||||
.hero {
|
||||
padding: 100px 56px 80px;
|
||||
display: grid;
|
||||
grid-template-columns: 7fr 5fr;
|
||||
gap: 80px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.hero-text {
|
||||
animation: slideIn 0.5s ease;
|
||||
}
|
||||
.hero-label {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
color: var(--red);
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.hero-label::before {
|
||||
content: '';
|
||||
width: 24px;
|
||||
height: 2px;
|
||||
background: var(--red);
|
||||
}
|
||||
.hero h1 {
|
||||
font-size: 56px;
|
||||
font-weight: 700;
|
||||
letter-spacing: -2px;
|
||||
margin-bottom: 24px;
|
||||
line-height: 1.05;
|
||||
}
|
||||
.hero p {
|
||||
font-size: 17px;
|
||||
color: var(--text-body);
|
||||
line-height: 1.7;
|
||||
margin-bottom: 40px;
|
||||
max-width: 500px;
|
||||
}
|
||||
.hero-actions { display: flex; gap: 0; }
|
||||
.hero-actions .btn-dark { border-right: none; }
|
||||
|
||||
.hero-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
animation: slideIn 0.5s ease 0.15s both;
|
||||
}
|
||||
.hero-fact {
|
||||
padding: 24px;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--bg-warm);
|
||||
}
|
||||
.hero-fact-number {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
color: var(--text-black);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.hero-fact-text {
|
||||
font-size: 14px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.hero-fact.accent {
|
||||
background: var(--text-black);
|
||||
border-color: var(--text-black);
|
||||
}
|
||||
.hero-fact.accent .hero-fact-number { color: var(--red); }
|
||||
.hero-fact.accent .hero-fact-text { color: rgba(255,255,255,0.5); }
|
||||
|
||||
/* -- Principles Bar -- */
|
||||
.principles {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.principle {
|
||||
padding: 36px 32px;
|
||||
border-right: 1px solid var(--border);
|
||||
}
|
||||
.principle:last-child { border-right: none; }
|
||||
.principle-num {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: var(--red);
|
||||
margin-bottom: 12px;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
.principle h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.principle p {
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* -- Features -- */
|
||||
.features {
|
||||
padding: 80px 56px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.section-header {
|
||||
margin-bottom: 56px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 40px;
|
||||
align-items: end;
|
||||
}
|
||||
.section-header h2 {
|
||||
font-size: 36px;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
.section-header p {
|
||||
font-size: 15px;
|
||||
color: var(--text-body);
|
||||
line-height: 1.7;
|
||||
}
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 0;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.feature-cell {
|
||||
padding: 32px;
|
||||
border-right: 1px solid var(--border);
|
||||
border-bottom: 1px solid var(--border);
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.feature-cell:nth-child(3n) { border-right: none; }
|
||||
.feature-cell:nth-child(n+4) { border-bottom: none; }
|
||||
.feature-cell:hover { background: var(--bg-light); }
|
||||
.feature-label {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
color: var(--red);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.feature-cell h3 {
|
||||
font-size: 16px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.feature-cell p {
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* -- CTA -- */
|
||||
.cta-section {
|
||||
padding: 0 56px 80px;
|
||||
}
|
||||
.cta-box {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 64px;
|
||||
background: var(--bg-dark);
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: 40px;
|
||||
align-items: center;
|
||||
}
|
||||
.cta-box h2 {
|
||||
font-size: 32px;
|
||||
color: var(--text-inverse);
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
.cta-box p {
|
||||
font-size: 15px;
|
||||
color: rgba(255,255,255,0.4);
|
||||
margin-top: 8px;
|
||||
}
|
||||
.btn-red {
|
||||
font-family: 'IBM Plex Sans', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
padding: 14px 36px;
|
||||
border: none;
|
||||
background: var(--red);
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.btn-red:hover { opacity: 0.9; }
|
||||
|
||||
.landing-footer {
|
||||
padding: 32px 56px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-top: 2px solid var(--text-black);
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.footer-links { display: flex; gap: 24px; }
|
||||
.footer-links a { color: var(--text-muted); text-decoration: none; }
|
||||
.footer-links a:hover { color: var(--text-black); }
|
||||
|
||||
/* ===== DASHBOARD ===== */
|
||||
|
||||
.dashboard-layout {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
background: var(--bg-light);
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 248px;
|
||||
min-width: 248px;
|
||||
background: var(--bg-dark);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
.sidebar-brand {
|
||||
padding: 20px;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.08);
|
||||
}
|
||||
.sidebar-brand h2 {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--text-inverse);
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
.sidebar-brand .red { color: var(--red); }
|
||||
.sidebar-user {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.08);
|
||||
}
|
||||
.user-avatar {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: var(--red);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.user-name { font-size: 13px; font-weight: 600; color: var(--text-inverse); }
|
||||
.user-email { font-size: 11px; color: rgba(255,255,255,0.3); }
|
||||
.sidebar-nav {
|
||||
flex: 1;
|
||||
padding: 12px 8px;
|
||||
}
|
||||
.nav-section {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: rgba(255,255,255,0.2);
|
||||
padding: 16px 14px 6px;
|
||||
}
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 8px 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: rgba(255,255,255,0.4);
|
||||
cursor: pointer;
|
||||
transition: all 0.12s;
|
||||
text-decoration: none;
|
||||
border-left: 2px solid transparent;
|
||||
}
|
||||
.nav-item:hover { color: rgba(255,255,255,0.7); background: rgba(255,255,255,0.03); }
|
||||
.nav-item.active {
|
||||
color: #fff;
|
||||
border-left-color: var(--red);
|
||||
background: rgba(255,255,255,0.05);
|
||||
font-weight: 600;
|
||||
}
|
||||
.sidebar-footer {
|
||||
padding: 14px 20px;
|
||||
border-top: 1px solid rgba(255,255,255,0.08);
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 10px;
|
||||
color: rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
padding: 32px 40px;
|
||||
min-width: 0;
|
||||
}
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 28px;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 2px solid var(--text-black);
|
||||
}
|
||||
.page-title { font-size: 24px; letter-spacing: -0.5px; }
|
||||
.page-subtitle {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* -- Stats -- */
|
||||
.stats-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 0;
|
||||
margin-bottom: 28px;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--bg-white);
|
||||
}
|
||||
.stat-cell {
|
||||
padding: 24px;
|
||||
border-right: 1px solid var(--border);
|
||||
}
|
||||
.stat-cell:last-child { border-right: none; }
|
||||
.stat-label {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.stat-value {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: var(--text-black);
|
||||
}
|
||||
.stat-bar {
|
||||
height: 3px;
|
||||
background: var(--border);
|
||||
margin-top: 12px;
|
||||
}
|
||||
.stat-bar-fill {
|
||||
height: 100%;
|
||||
background: var(--red);
|
||||
}
|
||||
|
||||
/* -- Content -- */
|
||||
.content-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 5fr 3fr;
|
||||
gap: 0;
|
||||
}
|
||||
.card {
|
||||
background: var(--bg-white);
|
||||
border: 1px solid var(--border);
|
||||
padding: 24px;
|
||||
}
|
||||
.card + .card { border-left: none; }
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.card-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
.card-badge {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
padding: 3px 10px;
|
||||
background: var(--red-muted);
|
||||
color: var(--red);
|
||||
border: 1px solid var(--red-border);
|
||||
}
|
||||
|
||||
.data-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.data-table th {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
color: var(--text-muted);
|
||||
text-align: left;
|
||||
padding: 8px 0;
|
||||
border-bottom: 2px solid var(--text-black);
|
||||
}
|
||||
.data-table td {
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 12px;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
color: var(--text-dark);
|
||||
}
|
||||
.data-table tr:last-child td { border-bottom: none; }
|
||||
.data-table tr:hover { background: var(--bg-light); }
|
||||
.model-mono {
|
||||
font-weight: 600;
|
||||
color: var(--text-black);
|
||||
}
|
||||
.status-indicator {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: 11px;
|
||||
}
|
||||
.status-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
.status-dot.on { background: var(--green); }
|
||||
.status-dot.off { background: var(--text-light); }
|
||||
|
||||
/* -- Member List -- */
|
||||
.member-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 14px 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.member-row:last-child { border-bottom: none; }
|
||||
.member-initial {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
background: var(--bg-dark);
|
||||
color: var(--text-inverse);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.member-name { font-size: 13px; font-weight: 600; color: var(--text-black); }
|
||||
.member-email { font-size: 11px; color: var(--text-muted); }
|
||||
.member-role {
|
||||
margin-left: auto;
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
from { opacity: 0; transform: translateX(-12px); }
|
||||
to { opacity: 1; transform: translateX(0); }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="view-switcher">
|
||||
<button class="active" onclick="showView('landing')">LANDING</button>
|
||||
<button onclick="showView('dashboard')">DASHBOARD</button>
|
||||
</div>
|
||||
|
||||
<!-- ===== LANDING ===== -->
|
||||
<div id="landing" class="view active">
|
||||
<nav class="landing-nav">
|
||||
<div class="nav-logo">CERTIF<span class="red">AI</span></div>
|
||||
<ul class="nav-links">
|
||||
<li><a href="#">Principles</a></li>
|
||||
<li><a href="#">Capabilities</a></li>
|
||||
<li><a href="#">Pricing</a></li>
|
||||
<li><a href="#">Documentation</a></li>
|
||||
</ul>
|
||||
<div class="nav-cta">
|
||||
<button class="btn-bordered">Sign In</button>
|
||||
<button class="btn-dark">Deploy Now</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section class="hero">
|
||||
<div class="hero-text">
|
||||
<div class="hero-label">Private AI Infrastructure</div>
|
||||
<h1>AI that answers<br>only to you.</h1>
|
||||
<p>Sovereign generative AI infrastructure for organizations that treat data protection as non-negotiable. Deploy on your terms, inside your perimeter.</p>
|
||||
<div class="hero-actions">
|
||||
<button class="btn-dark">Request Access</button>
|
||||
<button class="btn-bordered">Read Documentation</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-right">
|
||||
<div class="hero-fact">
|
||||
<div class="hero-fact-number">100%</div>
|
||||
<div class="hero-fact-text">On-premise deployment. No data egress.</div>
|
||||
</div>
|
||||
<div class="hero-fact accent">
|
||||
<div class="hero-fact-number">GDPR</div>
|
||||
<div class="hero-fact-text">Article 28 compliant by architecture.</div>
|
||||
</div>
|
||||
<div class="hero-fact">
|
||||
<div class="hero-fact-number"><30min</div>
|
||||
<div class="hero-fact-text">Full deployment including SSO and models.</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="principles">
|
||||
<div class="principle">
|
||||
<div class="principle-num">01</div>
|
||||
<h3>Data Sovereignty</h3>
|
||||
<p>Your data never leaves your infrastructure. No telemetry, no third-party calls.</p>
|
||||
</div>
|
||||
<div class="principle">
|
||||
<div class="principle-num">02</div>
|
||||
<h3>Full Control</h3>
|
||||
<p>Choose your models, set your policies, define your access rules.</p>
|
||||
</div>
|
||||
<div class="principle">
|
||||
<div class="principle-num">03</div>
|
||||
<h3>Transparency</h3>
|
||||
<p>Every token tracked, every cost attributed, every trace logged.</p>
|
||||
</div>
|
||||
<div class="principle">
|
||||
<div class="principle-num">04</div>
|
||||
<h3>EU-Native</h3>
|
||||
<p>Designed in Germany for EU compliance. No US-dependent services.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="features">
|
||||
<div class="section-header">
|
||||
<h2>Capabilities</h2>
|
||||
<p>A complete platform for operating AI infrastructure at enterprise scale. Every component self-hosted, every interface yours to configure.</p>
|
||||
</div>
|
||||
<div class="features-grid">
|
||||
<div class="feature-cell">
|
||||
<div class="feature-label">ROUTING</div>
|
||||
<h3>LLM Gateway</h3>
|
||||
<p>LiteLLM proxy for unified multi-provider access through a single endpoint.</p>
|
||||
</div>
|
||||
<div class="feature-cell">
|
||||
<div class="feature-label">ORCHESTRATION</div>
|
||||
<h3>Agent Platform</h3>
|
||||
<p>LangGraph for autonomous agents. LangFlow for visual workflow design.</p>
|
||||
</div>
|
||||
<div class="feature-cell">
|
||||
<div class="feature-label">OBSERVABILITY</div>
|
||||
<h3>Analytics</h3>
|
||||
<p>Langfuse integration for tracing, cost tracking, and prompt versioning.</p>
|
||||
</div>
|
||||
<div class="feature-cell">
|
||||
<div class="feature-label">IDENTITY</div>
|
||||
<h3>SSO & RBAC</h3>
|
||||
<p>Keycloak with SAML, OIDC, LDAP. Fine-grained role-based access control.</p>
|
||||
</div>
|
||||
<div class="feature-cell">
|
||||
<div class="feature-label">INTEGRATION</div>
|
||||
<h3>MCP & APIs</h3>
|
||||
<p>Model Context Protocol servers and REST APIs for tool-augmented AI.</p>
|
||||
</div>
|
||||
<div class="feature-cell">
|
||||
<div class="feature-label">MANAGEMENT</div>
|
||||
<h3>Admin Dashboard</h3>
|
||||
<p>Billing, team management, usage monitoring, and system configuration.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="cta-section">
|
||||
<div class="cta-box">
|
||||
<div>
|
||||
<h2>Ready to deploy?</h2>
|
||||
<p>Full operational AI stack. Under 30 minutes. No external dependencies.</p>
|
||||
</div>
|
||||
<button class="btn-red">Request Access</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer class="landing-footer">
|
||||
<span>© 2026 CERTifAI GmbH. Handelsregister HRB XXXXX.</span>
|
||||
<div class="footer-links">
|
||||
<a href="#">Datenschutz</a>
|
||||
<a href="#">Impressum</a>
|
||||
<a href="#">AGB</a>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<!-- ===== DASHBOARD ===== -->
|
||||
<div id="dashboard" class="view">
|
||||
<div class="dashboard-layout">
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-brand"><h2>CERTIF<span class="red">AI</span></h2></div>
|
||||
<div class="sidebar-user">
|
||||
<div class="user-avatar">MM</div>
|
||||
<div>
|
||||
<div class="user-name">Max Mustermann</div>
|
||||
<div class="user-email">max@company.de</div>
|
||||
</div>
|
||||
</div>
|
||||
<nav class="sidebar-nav">
|
||||
<div class="nav-section">Core</div>
|
||||
<a class="nav-item active">■ Dashboard</a>
|
||||
<a class="nav-item">◊ Providers</a>
|
||||
<a class="nav-item">✉ Chat</a>
|
||||
<div class="nav-section">Developer</div>
|
||||
<a class="nav-item">❖ Agents</a>
|
||||
<a class="nav-item">⧉ Workflows</a>
|
||||
<a class="nav-item">☰ Analytics</a>
|
||||
<div class="nav-section">Organization</div>
|
||||
<a class="nav-item">★ Billing</a>
|
||||
<a class="nav-item">♟ Members</a>
|
||||
</nav>
|
||||
<div class="sidebar-footer">CERTifAI v0.1.0</div>
|
||||
</aside>
|
||||
|
||||
<main class="main-content">
|
||||
<div class="page-header">
|
||||
<div>
|
||||
<h1 class="page-title">Dashboard</h1>
|
||||
<p class="page-subtitle">System overview / February 2026</p>
|
||||
</div>
|
||||
<button class="btn-dark">+ New Search</button>
|
||||
</div>
|
||||
|
||||
<div class="stats-row">
|
||||
<div class="stat-cell">
|
||||
<div class="stat-label">Total Spend</div>
|
||||
<div class="stat-value">$47.82</div>
|
||||
<div class="stat-bar"><div class="stat-bar-fill" style="width:48%"></div></div>
|
||||
</div>
|
||||
<div class="stat-cell">
|
||||
<div class="stat-label">Tokens Used</div>
|
||||
<div class="stat-value">847K</div>
|
||||
<div class="stat-bar"><div class="stat-bar-fill" style="width:85%"></div></div>
|
||||
</div>
|
||||
<div class="stat-cell">
|
||||
<div class="stat-label">Active Models</div>
|
||||
<div class="stat-value">5</div>
|
||||
<div class="stat-bar"><div class="stat-bar-fill" style="width:100%"></div></div>
|
||||
</div>
|
||||
<div class="stat-cell">
|
||||
<div class="stat-label">Team Seats</div>
|
||||
<div class="stat-value">4/25</div>
|
||||
<div class="stat-bar"><div class="stat-bar-fill" style="width:16%"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-grid">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title">Model Usage</div>
|
||||
<span class="card-badge">CURRENT MONTH</span>
|
||||
</div>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr><th>Model</th><th>Tokens</th><th>Spend</th><th>Status</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><span class="model-mono">Qwen3-Coder-30B</span></td>
|
||||
<td>342,000</td>
|
||||
<td>$18.40</td>
|
||||
<td><span class="status-indicator"><span class="status-dot on"></span>Active</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="model-mono">Llama-3.1-70B</span></td>
|
||||
<td>285,000</td>
|
||||
<td>$15.20</td>
|
||||
<td><span class="status-indicator"><span class="status-dot on"></span>Active</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="model-mono">Mistral-7B</span></td>
|
||||
<td>120,000</td>
|
||||
<td>$8.42</td>
|
||||
<td><span class="status-indicator"><span class="status-dot on"></span>Active</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="model-mono">Gemma-2-9B</span></td>
|
||||
<td>65,000</td>
|
||||
<td>$3.80</td>
|
||||
<td><span class="status-indicator"><span class="status-dot on"></span>Active</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="model-mono">Phi-3-mini</span></td>
|
||||
<td>35,000</td>
|
||||
<td>$2.00</td>
|
||||
<td><span class="status-indicator"><span class="status-dot off"></span>Idle</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-title">Team</div>
|
||||
</div>
|
||||
<div class="member-row">
|
||||
<div class="member-initial">MM</div>
|
||||
<div>
|
||||
<div class="member-name">Max Mustermann</div>
|
||||
<div class="member-email">max@company.de</div>
|
||||
</div>
|
||||
<span class="member-role">Admin</span>
|
||||
</div>
|
||||
<div class="member-row">
|
||||
<div class="member-initial">EM</div>
|
||||
<div>
|
||||
<div class="member-name">Erika Musterfrau</div>
|
||||
<div class="member-email">erika@company.de</div>
|
||||
</div>
|
||||
<span class="member-role">Member</span>
|
||||
</div>
|
||||
<div class="member-row">
|
||||
<div class="member-initial">JS</div>
|
||||
<div>
|
||||
<div class="member-name">Johann Schmidt</div>
|
||||
<div class="member-email">johann@company.de</div>
|
||||
</div>
|
||||
<span class="member-role">Member</span>
|
||||
</div>
|
||||
<div class="member-row">
|
||||
<div class="member-initial">AW</div>
|
||||
<div>
|
||||
<div class="member-name">Anna Weber</div>
|
||||
<div class="member-email">anna@company.de</div>
|
||||
</div>
|
||||
<span class="member-role">Viewer</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function showView(id) {
|
||||
document.querySelectorAll('.view').forEach(v => v.classList.remove('active'));
|
||||
document.querySelectorAll('.view-switcher button').forEach(b => b.classList.remove('active'));
|
||||
document.getElementById(id).classList.add('active');
|
||||
event.target.classList.add('active');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
BIN
design-templates/screenshots/01-nordic-frost-dashboard.png
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
design-templates/screenshots/01-nordic-frost-landing.png
Normal file
|
After Width: | Height: | Size: 259 KiB |
BIN
design-templates/screenshots/02-cyber-command-dashboard.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
design-templates/screenshots/02-cyber-command-landing.png
Normal file
|
After Width: | Height: | Size: 240 KiB |
BIN
design-templates/screenshots/03-warm-studio-dashboard.png
Normal file
|
After Width: | Height: | Size: 158 KiB |
BIN
design-templates/screenshots/03-warm-studio-landing.png
Normal file
|
After Width: | Height: | Size: 175 KiB |
BIN
design-templates/screenshots/04-glass-aurora-dashboard.png
Normal file
|
After Width: | Height: | Size: 184 KiB |
BIN
design-templates/screenshots/04-glass-aurora-landing.png
Normal file
|
After Width: | Height: | Size: 366 KiB |
BIN
design-templates/screenshots/05-swiss-grid-dashboard.png
Normal file
|
After Width: | Height: | Size: 67 KiB |
BIN
design-templates/screenshots/05-swiss-grid-landing.png
Normal file
|
After Width: | Height: | Size: 142 KiB |
10
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",
|
||||
|
||||
@@ -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::<Signal<Locale>>();
|
||||
@@ -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::<Signal<Locale>>();
|
||||
@@ -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")}
|
||||
}
|
||||
// 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",
|
||||
div { class: "preview-stat",
|
||||
div { class: "preview-stat-value", "$47.82" }
|
||||
div { class: "preview-stat-label",
|
||||
{t(l, "landing.preview_spend")}
|
||||
}
|
||||
// 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::<Signal<Locale>>();
|
||||
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: "trust-item",
|
||||
div { class: "trust-dot" }
|
||||
span { "GDPR " {t(l, "landing.compliant")} }
|
||||
}
|
||||
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 { "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::<Signal<Locale>>();
|
||||
@@ -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,14 +268,15 @@ 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::<Signal<Locale>>();
|
||||
let l = *locale.read();
|
||||
|
||||
rsx! {
|
||||
section { class: "cta-banner",
|
||||
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")}
|
||||
@@ -473,8 +301,10 @@ 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::<Signal<Locale>>();
|
||||
|
||||