← Zpět na hub Stáhnout zdroj

DESIGN SYSTEM

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


5. Tvary a stíny

Border-radius

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:

❌ Š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:

❌ Š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:

  1. ✅ Používá CSS variables — Žádné hardcoded barvy kromě hover variant akcentů!
  2. ✅ Má dark mode — Komponenta vypadá dobře v obou módech (přes variables to přijde automaticky, ale testuj)
  3. ✅ Je mobile-first — Otevři DevTools, zmenši viewport na 375px, ověř, že všechno funguje
  4. ✅ 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řes document.createElement() nebo innerHTML, tyto atributy NEMAJÍ → scoped CSS se na ně NEAPLIKUJE. Fix: <style is:global> nebo render přes Astro šablonu.
  5. ✅ Hover stavy jsou jemné150ms ease, max translateY(-2px), shadow z level 1 na 2. Žádné scale(), žádné rotate(), žádné bounce.
  6. ✅ Zachovává warm typografii — Font stack musí být systémový (viz sekce 3), velikosti odpovídají tabulce, letter-spacing -0.02em pro H1, -0.01em pro 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)