Design System — Personal Hub
Tento dokument definuje vizuální jazyk Personal Hubu. Používej ho před každou novou komponentou, stránkou nebo větší změnou CSS.
1. Princip
Personal Hub má navozovat klidný, teplý a profesionální dojem. Inspirace: Things (typografie a spacing), Craft (jemné stíny a teplé tóny), Raycast (přesnost a rychlost). Design se vyhýbá "AI-generated" clichés — žádné saturované barvy, velké gradienty, dramatické animace nebo studené modré tóny. Místo toho: warm gray paleta, systémový font stack, jemné stíny a konzistentní spacing. Každá komponenta má fungovat v dark i light módu automaticky přes CSS variables.
2. Paleta — CSS Variables
Dark mode (výchozí)
:root {
/* Pozadí */
--bg-page: #1c1917; /* Hlavní pozadí stránky (tmavší) */
--bg-surface: #2c2825; /* Karty, formuláře (světlejší než page) */
/* Text */
--text-primary: #fafaf9; /* Hlavní text (skoro bílá) */
--text-secondary: #a8a29e; /* Popisky, metadata (šedá) */
--text-tertiary: #78716c; /* Placeholdery, nejméně důležité (tmavší šedá) */
/* Rámečky */
--border-subtle: #44403c; /* Jemné rámečky (normální stav) */
--border-strong: #57534e; /* Zvýrazněné rámečky (hover, focus) */
/* Akcenty */
--accent-blue: #2563eb; /* Primární akce (tlačítka, linky) */
--accent-amber: #f59e0b; /* Myšlenky, project badges (teplá) */
--accent-green: #16a34a; /* Úspěšné akce (toast notifikace) */
/* Stíny */
--shadow-1: 0 1px 2px rgba(0,0,0,0.04); /* Jemné — karty v normálním stavu */
--shadow-2: 0 2px 8px rgba(0,0,0,0.06); /* Střední — hover, elevation */
--shadow-3: 0 10px 40px rgba(0,0,0,0.1); /* Velké — modaly, dialogy */
}
Light mode
@media (prefers-color-scheme: light) {
:root {
/* Pozadí */
--bg-page: #faf9f7; /* Teplá bílá (ne čistě bílá!) */
--bg-surface: #ffffff; /* Čistě bílá pro karty */
/* Text */
--text-primary: #1c1917; /* Tmavě hnědá (ne černá!) */
--text-secondary: #78716c; /* Střední šedá */
--text-tertiary: #a8a29e; /* Světlejší šedá */
/* Rámečky */
--border-subtle: #e7e5e4; /* Světlé rámečky */
--border-strong: #d6d3d1; /* Tmavší rámečky */
/* Akcenty (většina stejná jako dark, amber světlejší) */
--accent-blue: #2563eb;
--accent-amber: #d97706; /* Světlejší amber pro lepší kontrast */
--accent-green: #16a34a;
}
}
Poznámka: Stíny se v light mode nemění (rgba zůstává stejná).
3. Typografie
Font stack
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, system-ui, sans-serif;
Proč: Systémové fonty jsou rychlé, čitelné a vypadají nativně na každém zařízení. Žádné webové fonty (šetří bandwidth, zrychluje loading).
Velikosti a váhy
| Element | Velikost | Weight | Letter-spacing | Použití |
|---|---|---|---|---|
| H1 | 1.75rem (28px) | 600 | -0.02em | Hlavní nadpisy stránek |
| H2 | 1.25rem (20px) | 600 | -0.01em | Podnadpisy, sekce |
| Body | 15px | 400 | -0.011em | Hlavní text, odstavce |
| Button | 14px | 500 | inherit | Tlačítka, akce |
| Small | 13px | 400 | inherit | Metadata, časy, tagy |
| Tiny | 12px | 500 | inherit | Pill badges uvnitř textu |
Line-height: Univerzálně 1.5 pro body text, 1 nebo inherit pro nadpisy.
4. Spacing
Scale (v px)
4, 8, 12, 16, 20, 24, 32, 48, 64
V CSS používej rem hodnoty:
0.25rem, 0.5rem, 0.75rem, 1rem, 1.25rem, 1.5rem, 2rem, 3rem, 4rem
Pravidla
- Padding karet:
1.25rem(20px) na desktopu,1rem(16px) na mobilu - Gap mezi sekcemi:
2rem(32px) mezi většími bloky,1.5rem(24px) mezi menšími - Max-width obsahu:
1200pxpro wide layout (home),800pxpro text-heavy stránky (dokumenty, to-do) - Gap mezi elementy:
0.5rem(8px) pro malé prvky (tlačítka v toolbar),0.75rem(12px) pro střední (badges),1rem(16px) pro velké (karty v gridu)
5. Tvary a stíny
Border-radius
- Karty:
0.5rem(8px) — projekty na home, to-do položky, formuláře - Tlačítka a inputy:
0.375rem(6px) — menší, jemnější - Badges a pills:
999pxnebo9999px— úplně kulaté (pill shape)
Stíny — kdy použít kterou
| Level | CSS Variable | Kdy použít |
|---|---|---|
| Level 1 | var(--shadow-1) |
Normální stav karet, formulářů, tlačítek. Jemné oddělení od pozadí. |
| Level 2 | var(--shadow-2) |
Hover stav karet, zvýšená elevation (něco se "zvedá"). Používej s transform: translateY(-2px). |
| Level 3 | var(--shadow-3) |
Modaly, dialogy, plovoucí panely (FAB, dropdown). Výrazné oddělení od obsahu pod ním. |
Pravidlo: Nikdy nepoužívej víc než level 3. Pokud potřebuješ "ještě větší stín", pravděpodobně něco navrhuješ špatně.
6. Komponenty — Vzory
Karta (Card)
HTML:
<a href="/projects/foo" class="card">
<img src="thumb.jpg" class="card-thumb" />
<div class="card-content">
<h2 class="card-title">Název projektu</h2>
<p class="card-description">Krátký popis...</p>
</div>
</a>
CSS Pattern:
.card {
background: var(--bg-surface);
border: 1px solid var(--border-subtle);
border-radius: 0.5rem;
overflow: hidden;
transition: all 150ms ease;
box-shadow: var(--shadow-1);
}
.card:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-2);
border-color: var(--border-strong);
}
✅ Dobrá implementace:
- Používá CSS variables pro všechny barvy
- Má jemný hover (2px nahoru, stín z 1 na 2)
- Border se zvýrazní na hover
❌ Špatná implementace:
.card {
background: #292524; /* ❌ hardcoded barva */
box-shadow: 0 4px 20px rgba(0,0,0,0.3); /* ❌ příliš velký stín */
}
.card:hover {
transform: scale(1.05); /* ❌ dramatická animace */
}
Tlačítko (Button)
HTML:
<button class="btn-primary">Přidat úkol</button>
CSS Pattern:
.btn-primary {
background: var(--accent-blue);
color: white;
border: none;
border-radius: 0.375rem;
padding: 0.625rem 1.25rem;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 150ms ease;
box-shadow: var(--shadow-1);
}
.btn-primary:hover {
background: #1d4ed8; /* Trochu tmavší modrá — může být hardcoded pro hover */
box-shadow: var(--shadow-2);
}
Poznámka: Pro hover stavy primárních barev je OK hardcoded lehké ztmavnutí (např. #1d4ed8 místo #2563eb), protože CSS variables nemají built-in darken() funkci.
Badge (Pill)
HTML:
<span class="badge badge-ukol">8 otevřených úkolů</span>
<span class="badge badge-myslenka">2 myšlenky</span>
CSS Pattern:
.badge {
display: inline-flex;
align-items: center;
gap: 0.25rem;
padding: 0.25rem 0.75rem;
border-radius: 999px;
font-size: 14px;
font-weight: 600;
white-space: nowrap;
}
.badge-ukol {
background: var(--accent-blue);
color: white;
}
.badge-myslenka {
background: #451a03; /* Amber dark */
color: #fbbf24;
}
@media (prefers-color-scheme: light) {
.badge-myslenka {
background: #fef3c7; /* Amber light */
color: #92400e;
}
}
✅ Dobrá implementace:
- Pill shape (
border-radius: 999px) - Používá CSS variables kde možné, specifické barvy (amber) definuje inline pro dark/light
- Kompaktní padding
❌ Špatná implementace:
.badge {
border-radius: 4px; /* ❌ ne pill, jen rounded */
padding: 1rem 2rem; /* ❌ příliš velký */
background: linear-gradient(135deg, #667eea, #764ba2); /* ❌ gradientový kitsch */
}
7. Pravidla pro novou komponentu — Checklist
Každá nová komponenta musí projít tímto checklistem:
- ✅ Používá CSS variables — Žádné hardcoded barvy kromě hover variant akcentů!
- ✅ Má dark mode — Komponenta vypadá dobře v obou módech (přes variables to přijde automaticky, ale testuj)
- ✅ Je mobile-first — Otevři DevTools, zmenši viewport na 375px, ověř, že všechno funguje
- ✅ Pokud renderuje přes JS → použij
<style is:global>— Důvod: Astro CSS scoping přidávádata-astro-cid-*atributy jen do HTML v šabloně. Pokud vytváříš elementy přesdocument.createElement()neboinnerHTML, tyto atributy NEMAJÍ → scoped CSS se na ně NEAPLIKUJE. Fix:<style is:global>nebo render přes Astro šablonu. - ✅ Hover stavy jsou jemné —
150ms ease, maxtranslateY(-2px), shadow z level 1 na 2. Žádnéscale(), žádnérotate(), žádné bounce. - ✅ Zachovává warm typografii — Font stack musí být systémový (viz sekce 3), velikosti odpovídají tabulce, letter-spacing
-0.02empro H1,-0.01empro H2.
Pokud komponenta nesplňuje všech 6 bodů, není hotová.
8. Anti-patterns (čeho se vyhnout)
❌ Hardcoded barvy
.card {
background: #1a1a1a; /* ❌ */
color: #e0e0e0; /* ❌ */
}
Správně: background: var(--bg-surface); color: var(--text-primary);
❌ Tailwind / shadcn / Pico CSS
Hub používá vlastní CSS s CSS variables. Žádné utility frameworky, žádné komponenty z npm. Důvod: Plná kontrola nad designem, minimální dependencies.
❌ Webové fonty
<link rel="stylesheet" href="https://fonts.googleapis.com/..."> <!-- ❌ -->
Správně: Jen systémový font stack (viz sekce 3). Šetří bandwidth, zrychluje loading.
❌ Velké nebo dramatické stíny
box-shadow: 0 20px 60px rgba(0,0,0,0.5); /* ❌ příliš velké */
Správně: Max var(--shadow-3) pro modaly. Normální karty používají level 1 nebo 2.
❌ Saturované nebo chladné barvy
--accent: #00bfff; /* ❌ neon blue */
--text: #000000; /* ❌ čistě černá */
Správně: Warm tones (hnědá místo černé, teplá šedá místo studené slate). Akcenty jsou umírněné (#2563eb místo #00bfff).
❌ Animace nad rámec hover transitions
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
.card:hover {
animation: bounce 0.5s infinite; /* ❌ */
}
Správně: Pouze transition: all 150ms ease; a jemné transform na hover.
❌ Více než 5 npm dependencies celkem
Aktuální stav: 3/5 (Astro, marked, @supabase/supabase-js). Přidávání nové knihovny vyžaduje souhlas uživatele a zdůvodnění.
Závěr
Tento design system není košile — je to základ, který drží Hub konzistentní a profesionální. Pokud narazíš na případ, který zde není popsaný, konzultuj s uživatelem místo improvizace.
Verze: 2026-04-18 (finální pass po FÁZI 6)