feat(frontend): add design tokens, dark mode hook, and i18n scaffold

Part of the Ombrora Convert redesign (Task 1/5).
This commit is contained in:
2026-07-31 14:49:19 +02:00
parent f499196dae
commit ee18cc2d90
8 changed files with 359 additions and 90 deletions
+50 -88
View File
@@ -1,111 +1,73 @@
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap');
:root {
--text: #6b6375;
--text-h: #08060d;
--bg: #fff;
--border: #e5e4e7;
--code-bg: #f4f3ec;
--accent: #aa3bff;
--accent-bg: rgba(170, 59, 255, 0.1);
--accent-border: rgba(170, 59, 255, 0.5);
--social-bg: rgba(244, 243, 236, 0.5);
--shadow:
rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px;
--color-primary: #2563eb;
--color-on-primary: #ffffff;
--color-secondary: #3b82f6;
--color-accent: #d97706;
--color-background: #f8fafc;
--color-foreground: #0f172a;
--color-muted: #f1f5fd;
--color-border: #e4ecfc;
--color-destructive: #dc2626;
--color-ring: #2563eb;
--sans: system-ui, 'Segoe UI', Roboto, sans-serif;
--heading: system-ui, 'Segoe UI', Roboto, sans-serif;
--mono: ui-monospace, Consolas, monospace;
--font-sans: 'Plus Jakarta Sans', system-ui, 'Segoe UI', Roboto, sans-serif;
font: 18px/145% var(--sans);
letter-spacing: 0.18px;
color-scheme: light dark;
color: var(--text);
background: var(--bg);
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
@media (max-width: 1024px) {
font-size: 16px;
}
font: 16px/1.5 var(--font-sans);
}
@media (prefers-color-scheme: dark) {
:root {
--text: #9ca3af;
--text-h: #f3f4f6;
--bg: #16171d;
--border: #2e303a;
--code-bg: #1f2028;
--accent: #c084fc;
--accent-bg: rgba(192, 132, 252, 0.15);
--accent-border: rgba(192, 132, 252, 0.5);
--social-bg: rgba(47, 48, 58, 0.5);
--shadow:
rgba(0, 0, 0, 0.4) 0 10px 15px -3px, rgba(0, 0, 0, 0.25) 0 4px 6px -2px;
}
:root[data-theme='dark'] {
--color-primary: #3b82f6;
--color-on-primary: #0f172a;
--color-secondary: #60a5fa;
--color-accent: #f59e0b;
--color-background: #0f172a;
--color-foreground: #f1f5f9;
--color-muted: #1e293b;
--color-border: #334155;
--color-destructive: #f87171;
--color-ring: #3b82f6;
}
#social .button-icon {
filter: invert(1) brightness(2);
}
*, *::before, *::after {
box-sizing: border-box;
}
body {
margin: 0;
background: var(--color-background);
color: var(--color-foreground);
transition: background-color 200ms ease, color 200ms ease;
}
#root {
width: 1126px;
max-width: 100%;
margin: 0 auto;
text-align: center;
border-inline: 1px solid var(--border);
min-height: 100svh;
display: flex;
flex-direction: column;
box-sizing: border-box;
}
h1,
h2 {
font-family: var(--heading);
font-weight: 500;
color: var(--text-h);
a {
color: var(--color-primary);
}
h1 {
font-size: 56px;
letter-spacing: -1.68px;
margin: 32px 0;
@media (max-width: 1024px) {
font-size: 36px;
margin: 20px 0;
button, input, select {
font-family: inherit;
}
button {
cursor: pointer;
}
:focus-visible {
outline: 2px solid var(--color-ring);
outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
transition: none !important;
animation: none !important;
}
}
h2 {
font-size: 24px;
line-height: 118%;
letter-spacing: -0.24px;
margin: 0 0 8px;
@media (max-width: 1024px) {
font-size: 20px;
}
}
p {
margin: 0;
}
code,
.counter {
font-family: var(--mono);
display: inline-flex;
border-radius: 4px;
color: var(--text-h);
}
code {
font-size: 15px;
line-height: 135%;
padding: 4px 8px;
background: var(--code-bg);
}