Skip to content

Manager — Apple-Style Design

Filozofia projektowania

Manager-Content stosuje filozofie projektowania inspirowana Apple Human Interface Guidelines:

  • Czystosc — brak zbednych elementow, kazdy piksel ma swoje uzasadnienie
  • Minimalizm — ograniczona paleta kolorow, subtelne cienie zamiast ciezkich ramek
  • Fokus na tresci — interfejs schodzi na drugi plan, tresc jest bohaterem
  • Przestrzen — generyczny whitespace daje elementom "oddech"
  • Konsystencja — te same wzorce powtarzaja sie w calym interfejsie

Whitespace

Generyczny padding i marginesy tworza wrazenie przestronnosci:

ElementPadding / Margin
Strona (main)px-6 py-8
Kartap-6 lub p-8
Tabela (komorki)px-6 py-4
Sekcje miedzy sobaspace-y-6 lub space-y-8
Sidebarpx-4 py-6
Formularz (pola)space-y-5

Zasada: Jesli nie wiesz ile dac przestrzeni — daj wiecej.


Typografia

Dwie rodziny fontow tworzace hierarchie wizualna:

RolaFontKlasa CSSWagi
NaglowkiNunitofont-display600, 700
Body / UIInterfont-sans400, 500, 600

Konfiguracja Tailwind

js
// tailwind.config.js
module.exports = {
  theme: {
    fontFamily: {
      display: ['Nunito', 'system-ui', 'sans-serif'],
      sans: ['Inter', 'system-ui', 'sans-serif'],
    },
  },
}

Skala typograficzna

ElementKlasy Tailwind
H1 (tytul str.)text-2xl font-display font-bold text-gray-900
H2 (sekcja)text-xl font-display font-semibold text-gray-900
H3 (karta)text-lg font-display font-semibold text-gray-800
Bodytext-sm font-sans text-gray-700
Labeltext-sm font-medium text-gray-700
Caption / Helptext-xs text-gray-500

Karty

Karty sa podstawowym kontenerem grupujacym tresc.

html
<!-- Bazowa karta -->
<div class="bg-white rounded-xl border border-gray-100 shadow-sm
            hover:shadow-md transition-shadow duration-200">
  <div class="p-6">
    <h3 class="text-lg font-display font-semibold text-gray-800">
      Tytul karty
    </h3>
    <p class="mt-2 text-sm text-gray-600">
      Opis lub zawartosc karty.
    </p>
  </div>
</div>

Warianty kart

html
<!-- Karta z headerem i borderem dolnym -->
<div class="bg-white rounded-xl border border-gray-100 shadow-sm">
  <div class="px-6 py-4 border-b border-gray-100">
    <h3 class="text-lg font-display font-semibold text-gray-800">Header</h3>
  </div>
  <div class="p-6">
    <!-- tresc -->
  </div>
</div>

<!-- Karta z footerem -->
<div class="bg-white rounded-xl border border-gray-100 shadow-sm">
  <div class="p-6">
    <!-- tresc -->
  </div>
  <div class="px-6 py-4 bg-gray-50 rounded-b-xl border-t border-gray-100">
    <!-- footer / akcje -->
  </div>
</div>

Tabele

Lekkie, czytelne tabele bez ciezkich ramek:

html
<div class="bg-white rounded-xl border border-gray-100 shadow-sm overflow-hidden">
  <table class="w-full">
    <thead>
      <tr class="border-b border-gray-100">
        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
          Nazwa
        </th>
        <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
          Status
        </th>
      </tr>
    </thead>
    <tbody id="table-body" class="divide-y divide-gray-50">
      <tr class="hover:bg-gray-50 transition-colors duration-150">
        <td class="px-6 py-4 text-sm text-gray-900">
          Zadanie matematyczne
        </td>
        <td class="px-6 py-4">
          <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-50 text-green-700">
            Aktywne
          </span>
        </td>
      </tr>
    </tbody>
  </table>
</div>

Zasady tabel

  • Brak ciezkich borderow — uzyj divide-y divide-gray-50 miedzy wierszami
  • Header: text-xs uppercase tracking-wider text-gray-500
  • Hover: hover:bg-gray-50 transition-colors duration-150
  • Padding: px-6 py-4 (generyczny)
  • Font: text-sm dla zawartosci

Przyciski

Primary (glowna akcja)

html
<button class="inline-flex items-center gap-2 px-4 py-2.5
               bg-indigo-600 text-white text-sm font-medium
               rounded-lg shadow-sm
               hover:bg-indigo-700 active:bg-indigo-800
               transition-colors duration-150
               focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
  <i data-lucide="plus" class="w-4 h-4"></i>
  Dodaj zadanie
</button>

Secondary (akcja drugorzedna)

html
<button class="inline-flex items-center gap-2 px-4 py-2.5
               bg-white text-gray-700 text-sm font-medium
               rounded-lg border border-gray-300 shadow-sm
               hover:bg-gray-50 active:bg-gray-100
               transition-colors duration-150
               focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
  <i data-lucide="filter" class="w-4 h-4"></i>
  Filtruj
</button>

Danger (akcja niebezpieczna)

html
<button class="inline-flex items-center gap-2 px-4 py-2.5
               bg-white text-red-600 text-sm font-medium
               rounded-lg border border-red-200 shadow-sm
               hover:bg-red-50 active:bg-red-100
               transition-colors duration-150
               focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2">
  <i data-lucide="trash-2" class="w-4 h-4"></i>
  Usun
</button>

Ghost (bezramkowy)

html
<button class="inline-flex items-center gap-2 px-3 py-2
               text-gray-500 text-sm font-medium
               rounded-lg
               hover:bg-gray-100 hover:text-gray-700
               transition-colors duration-150">
  <i data-lucide="more-horizontal" class="w-4 h-4"></i>
</button>

Stat Card (karta statystyk)

html
<div class="bg-white rounded-xl border border-gray-100 shadow-sm p-6">
  <div class="flex items-center gap-4">
    <div class="flex-shrink-0 w-12 h-12 bg-indigo-50 rounded-xl
                flex items-center justify-center">
      <i data-lucide="zap" class="w-6 h-6 text-indigo-600"></i>
    </div>
    <div>
      <p class="text-sm font-medium text-gray-500">Zebrane XP</p>
      <p class="text-2xl font-display font-bold text-gray-900">2,450</p>
    </div>
  </div>
  <div class="mt-4 flex items-center gap-1 text-xs">
    <i data-lucide="trending-up" class="w-3.5 h-3.5 text-green-600"></i>
    <span class="font-medium text-green-600">+12%</span>
    <span class="text-gray-500">vs poprzedni tydzien</span>
  </div>
</div>

Empty State (pusty stan)

html
<div class="flex flex-col items-center justify-center py-16 px-6">
  <div class="w-16 h-16 bg-gray-100 rounded-2xl
              flex items-center justify-center mb-4">
    <i data-lucide="inbox" class="w-8 h-8 text-gray-400"></i>
  </div>
  <h3 class="text-lg font-display font-semibold text-gray-800">
    Brak zadan
  </h3>
  <p class="mt-1 text-sm text-gray-500 text-center max-w-sm">
    Nie masz jeszcze zadnych zadan. Stworz pierwsze zadanie,
    aby rozpoczac przygode edukacyjna.
  </p>
  <button class="mt-6 inline-flex items-center gap-2 px-4 py-2.5
                 bg-indigo-600 text-white text-sm font-medium
                 rounded-lg shadow-sm hover:bg-indigo-700
                 transition-colors duration-150">
    <i data-lucide="plus" class="w-4 h-4"></i>
    Stworz zadanie
  </button>
</div>

Paleta kolorow

Neutralne (tla, tekst, bordery)

CelKolorKlasa Tailwind
Tlo strony#F9FAFBbg-gray-50
Tlo karty#FFFFFFbg-white
Border karty#F3F4F6border-gray-100
Border inputa#D1D5DBborder-gray-300
Tekst glowny#111827text-gray-900
Tekst drugorzedny#6B7280text-gray-500
Tekst wylaczony#9CA3AFtext-gray-400
Hover wiersza tabeli#F9FAFBbg-gray-50

Akcent (primary)

CelKlasa Tailwind
Przycisk primarybg-indigo-600
Przycisk hoverbg-indigo-700
Tlo aktywnego navbg-indigo-50
Tekst aktywnego navtext-indigo-700
Focus ringring-indigo-500

Statusy

StatusTloTekst
Aktywnebg-green-50text-green-700
Oczekujacebg-amber-50text-amber-700
Odrzuconebg-red-50text-red-700
Szkicbg-gray-100text-gray-600

Ikony — Lucide

Uzyj Lucide Icons w rozmiarze 20px z cienkim obrysem:

html
<!-- Domyslna ikona (20px, stroke 1.5) -->
<i data-lucide="home" class="w-5 h-5" style="stroke-width: 1.5"></i>

<!-- Mala ikona (16px) -->
<i data-lucide="chevron-right" class="w-4 h-4"></i>

<!-- Duza ikona (24px, np. w empty state) -->
<i data-lucide="inbox" class="w-6 h-6 text-gray-400"></i>

Czesto uzywane ikony

IkonaNazwa Lucide
Dashboardlayout-dashboard
Contentbook-open
Worldsglobe
Todocheck-square
Settingssettings
Dodajplus
Edytujpencil
Usuntrash-2
Szukajsearch
Filtrujfilter
Zamknijx
Menumenu

Animacje i przejscia

CSS transitions

html
<!-- Subtelne przejscie na hover (cien, kolor) -->
<div class="transition-all duration-200 ease-in-out">

<!-- Przejscie koloru tla -->
<tr class="transition-colors duration-150">

<!-- Przejscie cienia karty -->
<div class="shadow-sm hover:shadow-md transition-shadow duration-200">

HTMX swap transitions

css
/* Fade-in dla nowo zaladowanej tresci */
.htmx-swapping {
  opacity: 0;
  transition: opacity 200ms ease-out;
}

.htmx-settling {
  opacity: 1;
  transition: opacity 200ms ease-in;
}

/* Klasa dla elementow ladujacych */
.htmx-request .htmx-indicator {
  display: inline-flex;
}

.htmx-indicator {
  display: none;
}

Alpine.js transitions

html
<!-- Slide-in panel -->
<div x-show="open"
     x-transition:enter="transition ease-out duration-200"
     x-transition:enter-start="opacity-0 translate-x-4"
     x-transition:enter-end="opacity-100 translate-x-0"
     x-transition:leave="transition ease-in duration-150"
     x-transition:leave-start="opacity-100 translate-x-0"
     x-transition:leave-end="opacity-0 translate-x-4">
</div>

<!-- Fade modal backdrop -->
<div x-show="open"
     x-transition:enter="transition ease-out duration-200"
     x-transition:enter-start="opacity-0"
     x-transition:enter-end="opacity-100"
     x-transition:leave="transition ease-in duration-150"
     x-transition:leave-start="opacity-100"
     x-transition:leave-end="opacity-0"
     class="fixed inset-0 bg-black/30 backdrop-blur-sm">
</div>

Responsive design

Podejscie desktop-first — Manager jest narzedziem przeznaczonym glownie na desktop:

BreakpointSzerokoscZachowanie
Desktop>= 1024pxPelny sidebar + tresc
Tablet768-1023pxSidebar kolapsuje do ikon
Mobile< 768pxSidebar jako hamburger overlay
html
<!-- Sidebar: pelny na desktop, ikony na tablet, ukryty na mobile -->
<aside class="hidden md:flex md:w-16 lg:w-64 flex-col ...">

<!-- Main content: dostosowuje margines -->
<main class="ml-0 md:ml-16 lg:ml-64 ...">

Wzorce formularzy

html
<!-- Pole tekstowe -->
<div>
  <label class="block text-sm font-medium text-gray-700 mb-1.5">
    Tytul zadania
  </label>
  <input type="text"
         class="w-full px-3.5 py-2.5 text-sm text-gray-900
                bg-white border border-gray-300 rounded-lg
                placeholder:text-gray-400
                focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500
                transition-colors duration-150"
         placeholder="Wpisz tytul...">
</div>

<!-- Select -->
<div>
  <label class="block text-sm font-medium text-gray-700 mb-1.5">
    Grupa wiekowa
  </label>
  <select class="w-full px-3.5 py-2.5 text-sm text-gray-900
                 bg-white border border-gray-300 rounded-lg
                 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500
                 transition-colors duration-150">
    <option>Wybierz...</option>
  </select>
</div>

Lumos Islands v2 - Dokumentacja Projektowa