/* wiedza-public.css: WYGENEROWANE przez frontend/wiedza/narzedzia/public-assets.mjs.
   Nie edytuj ręcznie: zmień źródło i puść skrypt.
   źródła: 1b0279470446e8dd */

/* ===== prototypy/piosenki/piosenki.css ===== */
/* piosenki.css — wspólna powłoka trzech makiet strony Piosenki.

   PO CO OSOBNY PLIK: trzy makiety różnią się PIERWSZYM EKRANEM, a nie
   paskiem, kartą ani kolorami. Powłoka napisana raz to jedno miejsce, gdzie
   sprawdza się wierność wobec kodu, i zero ryzyka, że wariant B ma inny
   pasek niż A (runda 6 landingu robiła tak samo: runda-6.css).

   WIERNOŚĆ (wartości przepisane, nie wymyślone):
     - tokeny motywu Ognisko i Ognisko za dnia: index.css :262-345, kolor
       w kolor,
     - .glass: index.css :617-641 (karta 72 %, blur 18 px, saturate 1.3,
       cień 0 6px 24px),
     - pasek: TopBar.tsx — na telefonie siatka `1fr auto 1fr`, żeby logo
       stało na środku EKRANU (RUNDA_6 §12, dogrywka), wysokość 3.5rem,
     - pasek dolny: Tabbar.tsx — pięć zakładek, glass, znika od 48rem,
     - pasek sekcji: SectionNav.tsx — etykieta `text-sm font-medium`,
       nieaktywna `--muted-foreground`, aktywna `--primary`,
     - szerokość treści: `max-w-5xl` z _app.tsx = 64rem,
     - kroje: Fraunces TYLKO nagłówki i znak, mono na podpisy i liczby,
       tekst bieżący systemowy (RUNDA_6 §12 pkt 5).

   Czego tu NIE ma: rzeczy wymyślonych na tę rundę (półka, kolekcje, filtr
   po akordach). Te siedzą w <style> swojej makiety, żeby było widać
   granicę między „przepisane z kodu" a „propozycja". */

/* KROJE Z REPO, nie z Google Fonts. Makiety Startu ciągnęły Fraunces
   z sieci i zrzuty potrafiły wisieć na `waiting for fonts to load`; te same
   pliki (OFL) leżą w frontend/public/fonts/ i są w precache'u service
   workera, więc makieta stoi na dokładnie tym rysunku, co produkcja, i
   działa bez sieci. Zakresy unicode jak w index.css :36-100. */
@font-face {
  font-family: "Fraunces"; font-style: normal; font-weight: 400 700; font-display: block;
  src: url("/fonts/fraunces-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Fraunces"; font-style: normal; font-weight: 400 700; font-display: block;
  src: url("/fonts/fraunces-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: block;
  src: url("/fonts/ibm-plex-mono-400-latin.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: block;
  src: url("/fonts/ibm-plex-mono-400-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-weight: 600; font-display: block;
  src: url("/fonts/ibm-plex-mono-600-latin.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-weight: 600; font-display: block;
  src: url("/fonts/ibm-plex-mono-600-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* index.css .ognisko */
  --background: #12100d;
  --bg-glow: #1c1813;
  --foreground: #f3ece0;
  --card: #1c1813;
  --primary: #f0a838;
  --primary-foreground: #1b1204;
  --secondary: #241e16;
  --muted-foreground: #a89a86;
  --accent: #e2673a;
  --border: #2e2820;
  --sidebar: #15120e;
  /* atrament akordu: KONTRAST_POMIAR §6, propozycja 1 (5,67:1) */
  --chord-ink: #f0a838;
  --glass-tint: var(--sidebar);
  --glass-edge: var(--foreground);
  --glow-mix: 20%;

  --font-sans: "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --font-mono: "IBM Plex Mono", ui-monospace, Menlo, monospace;
  --tab-h: 3.6rem;
  --bar-h: 3.5rem;
}
body[data-motyw="ognisko-jasne"] {
  /* index.css .ognisko-jasne */
  --background: #f2e9d8;
  --bg-glow: #fdf8ee;
  --foreground: #241d13;
  --card: #faf4e8;
  --primary: #a8620f;
  --primary-foreground: #ffffff;
  --secondary: #ebe0cb;
  --muted-foreground: #6d6049;
  --accent: #b3502a;
  --border: #d8cdb8;
  --sidebar: #f6efe2;
  --chord-ink: #8f520b;
  --glow-mix: 9%;
  /* ⚠ MUSZĄ tu być, choć w kodzie stoją raz. W appce klasę motywu wiesza
     theme-provider na <html>, więc `--glass-tint: var(--sidebar)` liczy się
     już w jasnych wartościach. W makiecie motyw siedzi na <body>, a wartość
     z var() jest podstawiana TAM, GDZIE ZADEKLAROWANA — pasek wychodził
     ciemny na jasnej stronie. */
  --glass-tint: #f6efe2;
  --glass-edge: #241d13;
}

*, *::before, *::after { box-sizing: border-box }
html { -webkit-text-size-adjust: 100% }
body {
  margin: 0; background: var(--background); color: var(--foreground);
  font-family: var(--font-sans); font-size: 16px; line-height: 1.5;
  overflow-x: hidden; transition: background .2s, color .2s;
  padding-bottom: calc(var(--tab-h) + env(safe-area-inset-bottom));
}
@media (min-width: 48rem) { body { padding-bottom: 0 } }
a { color: inherit; text-decoration: none }
:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; border-radius: 8px }
h1, h2, h3, h4 { font-family: var(--font-display); font-optical-sizing: auto; margin: 0 }
.glow {
  position: fixed; inset: auto 0 -30vh 0; height: 70vh; pointer-events: none; z-index: 0;
  background: radial-gradient(60% 60% at 50% 100%,
    color-mix(in srgb, var(--accent) var(--glow-mix), transparent) 0%, transparent 70%);
}
.wrap { position: relative; z-index: 1; max-width: 64rem; margin: 0 auto; padding: 0 1rem }
@media (min-width: 48rem) { .wrap { padding: 0 1.5rem } }

/* persony: to samo, co w makietach Startu — CSS, nie JS */
body[data-konto="uczen"] [data-g] { display: none !important }
body[data-konto="gosc"] [data-u] { display: none !important }

/* ---------- PASEK (TopBar.tsx) ---------- */
.glass {
  background: color-mix(in srgb, var(--glass-tint) 72%, transparent);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  backdrop-filter: blur(18px) saturate(1.3);
  border-color: color-mix(in srgb, var(--glass-edge) 8%, transparent);
  box-shadow: 0 6px 24px rgb(0 0 0 / .28);
}
.topbar {
  position: sticky; top: 0; z-index: 20; height: var(--bar-h);
  display: grid; grid-template-columns: minmax(0,1fr) auto minmax(0,1fr);
  align-items: center; padding: 0 .75rem; border-bottom: 1px solid var(--border);
}
.topbar .start { display: flex; align-items: center; gap: .25rem; justify-self: start }
.topbar .brand { justify-self: center; display: flex; align-items: center; gap: .4rem;
  font-family: var(--font-display); font-weight: 600; font-size: 15px;
  font-variation-settings: "opsz" 40, "SOFT" 40; white-space: nowrap }
.topbar .brand b { color: var(--primary); font-weight: 600 }
.topbar .brand svg { width: 22px; height: 22px }
.topbar .end { display: flex; align-items: center; gap: .25rem; justify-self: end }
@media (min-width: 48rem) {
  .topbar { display: flex; gap: .5rem; padding: 0 1rem }
  .topbar .end { margin-left: auto }
  .topbar .start:empty { display: none }
  .topbar .brand { font-size: 1rem }
  .topbar .brand svg { width: 24px; height: 24px }
}
@media (max-width: 375px) { .topbar .brand .word { display: none } }

/* pasek sekcji (SectionNav.tsx): tylko od 48rem, jak w kodzie */
.secnav { display: none }
@media (min-width: 48rem) {
  .secnav { display: flex; align-items: center; gap: .125rem; margin-left: .5rem }
  .secnav a { display: flex; align-items: center; gap: .15rem; padding: .3rem .5rem;
    border-radius: .5rem; font-size: .875rem; font-weight: 500; color: var(--muted-foreground) }
  .secnav a[aria-current] { color: var(--primary) }
  .secnav a:hover { color: var(--foreground) }
  .secnav .caret { opacity: .6; font-size: .7rem }
}
.ikona { width: 2rem; height: 2rem; display: grid; place-items: center; border-radius: .5rem;
  border: 1px solid var(--border); background: var(--card); color: var(--muted-foreground);
  font-family: var(--font-mono); font-size: .72rem }
.btn { display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  border-radius: 999px; border: 1px solid transparent; cursor: pointer;
  font-family: var(--font-sans); font-size: .9rem; font-weight: 600; padding: .55rem 1rem;
  background: transparent; color: inherit; white-space: nowrap }
.btn-sm { padding: .35rem .8rem; font-size: .82rem }
.btn-primary { background: var(--primary); color: var(--primary-foreground) }
.btn-line { border-color: var(--border); color: var(--foreground) }
.btn-line:hover { border-color: var(--primary); color: var(--primary) }
.btn-quiet { font-family: var(--font-mono); font-size: .74rem; color: var(--muted-foreground);
  border: 0; background: none; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; padding: 0 }

/* ---------- PASEK DOLNY (Tabbar.tsx) ---------- */
.tabbar { position: fixed; inset: auto 0 0 0; z-index: 40; display: grid; grid-template-columns: repeat(5, 1fr);
  border-top: 1px solid var(--border); padding-bottom: env(safe-area-inset-bottom) }
@media (min-width: 48rem) { .tabbar { display: none } }
.tabbar a { display: flex; flex-direction: column; align-items: center; gap: .125rem;
  padding: .5rem .25rem; font-size: 11px; line-height: 1; color: var(--muted-foreground) }
.tabbar a[aria-current] { color: var(--primary) }
.tabbar svg { width: 1.25rem; height: 1.25rem }

/* ---------- NAGŁÓWEK STRONY ---------- */
.crumb { font-family: var(--font-mono); font-size: .68rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--muted-foreground) }
.crumb b { color: var(--primary); font-weight: 500 }
h1 { font-weight: 400; font-variation-settings: "opsz" 144, "SOFT" 20;
  font-size: clamp(1.7rem, 5.6vw, 2.6rem); line-height: 1.05; letter-spacing: -.02em;
  text-wrap: balance; margin: .25rem 0 0 }
h1 .fire { font-style: italic; color: var(--primary); font-weight: 500 }
.lede { color: var(--muted-foreground); font-size: .95rem; max-width: 34rem; margin: .5rem 0 0 }
.lede em { font-style: normal; color: var(--foreground) }

/* ---------- KARTA UTWORU (SongCatalog.tsx: SongCard) ---------- */
.song {
  display: flex; flex-direction: column; gap: .15rem; position: relative;
  border: 1px solid var(--border); border-radius: .5rem; background: var(--card);
  padding: .75rem 2.5rem .75rem .75rem; min-width: 0;
  transition: border-color .18s, transform .18s;
}
.song:hover { border-color: color-mix(in srgb, var(--foreground) 30%, transparent) }
.song .tyt { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.song .wyk { font-size: .875rem; color: var(--muted-foreground);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.song .badges { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; margin-top: .25rem }
.bdg { border: 1px solid var(--border); border-radius: .25rem; padding: 0 .375rem;
  font-size: .75rem; color: var(--muted-foreground); white-space: nowrap }
.bdg.l1 { border-color: #3f7d4e; color: #7fc08e }
.bdg.l2 { border-color: #3f6a8a; color: #86b6d6 }
.bdg.l3 { border-color: #8a6a2a; color: #d9ae5e }
.bdg.l4 { border-color: #8a3f3f; color: #d68686 }
body[data-motyw="ognisko-jasne"] .bdg.l1 { color: #2c6139 }
body[data-motyw="ognisko-jasne"] .bdg.l2 { color: #2f5673 }
body[data-motyw="ognisko-jasne"] .bdg.l3 { color: #7a5410 }
body[data-motyw="ognisko-jasne"] .bdg.l4 { color: #8a3030 }
.warstwy { margin-left: auto; display: flex; gap: .25rem }
.warstwy span { min-width: 1.25rem; text-align: center; border: 1px solid var(--border);
  border-radius: .25rem; font-size: 11px; line-height: 1rem; color: color-mix(in srgb, var(--muted-foreground) 40%, transparent) }
.warstwy span[data-on] { border-color: color-mix(in srgb, var(--foreground) 30%, transparent); color: var(--foreground) }
.gwiazdka { position: absolute; top: .5rem; right: .5rem; font-size: 1.125rem; line-height: 1;
  color: color-mix(in srgb, var(--muted-foreground) 50%, transparent); background: none; border: 0; cursor: pointer }
.gwiazdka[aria-pressed="true"] { color: var(--primary) }

/* utwór ZAMKNIĘTY: karta zostaje, znika droga do niej */
.song[data-zamk] { opacity: .62 }
.song[data-zamk] .tyt { color: var(--muted-foreground) }
.klodka { position: absolute; top: .5rem; right: .5rem; font-size: .8rem; color: var(--muted-foreground) }

/* akordy na karcie: mono, atrament akordu */
.chords { font-family: var(--font-mono); font-size: .85rem; color: var(--chord-ink); letter-spacing: -.01em }

/* ---------- PIGUŁKA FILTRU (FilterPill.tsx) ---------- */
.pigulki { display: flex; gap: .5rem; margin-top: .6rem }
.pigulka { flex: 1 1 0; min-width: 0; min-height: 2.75rem; display: flex; flex-direction: column;
  align-items: flex-start; justify-content: center; gap: .1rem; border-radius: .75rem;
  border: 1px solid var(--border); background: var(--card); padding: .35rem .75rem;
  text-align: left; cursor: pointer; color: inherit; font-family: inherit }
.pigulka[data-active] { border-color: color-mix(in srgb, var(--primary) 70%, transparent) }
.pigulka .lbl { font-size: .62rem; font-weight: 500; text-transform: uppercase;
  letter-spacing: .08em; color: var(--muted-foreground) }
.pigulka .val { display: flex; width: 100%; align-items: center; gap: .25rem;
  font-size: .875rem; font-weight: 600 }
.pigulka .val i { margin-left: auto; font-style: normal; font-size: .7rem; color: var(--muted-foreground) }

/* ---------- SZUKAJKA ---------- */
.szukaj { display: flex; align-items: center; gap: .5rem; border: 1px solid var(--border);
  border-radius: .75rem; background: var(--card); padding: .55rem .75rem; margin-top: .6rem }
.szukaj input { flex: 1; min-width: 0; border: 0; background: none; color: inherit;
  font: inherit; outline: none }
.szukaj input::placeholder { color: var(--muted-foreground) }

/* ---------- SYGNATURA: chwyt + pas bicia ---------- */
.grip { opacity: .45; transition: opacity .25s }
.grip[data-on] { opacity: 1 }
.lane { display: flex; gap: .15rem }
.lane b { width: .7rem; height: 1.5rem; border-radius: 3px; background: var(--secondary);
  display: grid; place-items: center; font-family: var(--font-mono); font-size: .58rem;
  font-weight: 400; color: color-mix(in srgb, var(--muted-foreground) 60%, transparent) }
.lane b[data-acc] { color: var(--muted-foreground) }
.lane b[data-on] { background: var(--primary); color: var(--primary-foreground) }

/* ---------- STOPKA I PRZEŁĄCZNIK MAKIETY ---------- */
footer { margin: 2.5rem 0 1.5rem; padding-top: 1rem; border-top: 1px solid var(--border);
  font-size: .8rem; color: var(--muted-foreground); display: grid; gap: .35rem }
footer .mono { font-family: var(--font-mono); font-size: .7rem }
.persona { position: fixed; right: .75rem; z-index: 30; display: grid; gap: .3rem; justify-items: end;
  bottom: calc(var(--tab-h) + .6rem + env(safe-area-inset-bottom)) }
@media (min-width: 48rem) { .persona { bottom: .9rem } }
.persona .grp { display: flex; align-items: center; gap: .25rem; padding: .25rem .25rem .25rem .6rem;
  border-radius: 999px; border: 1px solid var(--border);
  background: color-mix(in srgb, var(--background) 92%, transparent);
  font-family: var(--font-mono); font-size: .6rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted-foreground); box-shadow: 0 12px 30px -12px rgb(0 0 0 / .5) }
.persona button { font: inherit; letter-spacing: inherit; text-transform: inherit; border: 0;
  cursor: pointer; border-radius: 999px; padding: .25rem .5rem; background: transparent; color: var(--muted-foreground) }
.persona button[aria-pressed="true"] { background: var(--primary); color: var(--primary-foreground) }

@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important } }

/* Pasek na telefonie kontra na szerokim (RUNDA_6 §12, dogrywka): logo ma
   stać na środku EKRANU, więc na telefonie po bokach zostaje po jednym
   elemencie, a reszta wchodzi dopiero od 48rem. */
.tylko-szer { display: none !important }
@media (min-width: 48rem) {
  .tylko-tel { display: none !important }
  .tylko-szer { display: inline-flex !important }
  body[data-konto="gosc"] [data-u].tylko-szer,
  body[data-konto="uczen"] [data-g].tylko-szer { display: none !important }
}

/* ============================================================
   DOPISANE dla makiety a2 („szukajka na wierzchu") i strony
   kategorii (2026-08-29, ANALIZA §H.3). Wyłącznie NOWE nazwy klas,
   zero zmian w tym, co wyżej: ten sam plik ładują a-polka, b-chwyty,
   c-kolekcje oraz makiety Rytmu i Wiedzy budowane równolegle.
   Rzeczy tylko-a2 (karta „Zagraj to teraz", półka) siedzą w <style>
   swojej makiety, tu jest to, co a2 dzieli ze stroną kategorii.
   ============================================================ */

/* `hidden` musi wygrać z `display: flex/grid` niżej. Reguła jest wąska
   celowo: globalne `[hidden] { display: none !important }` zmieniłoby
   rysunek makiet A/B/C, a te mają zostać nietknięte. */
.wyniki[hidden], .wyniki-info[hidden], .pigulki3[hidden], .pusto-szukaj[hidden] { display: none }

/* ---------- SZUKAJKA NA WIERZCHU (§H.3 pkt 1) ---------- */
.szukajka { position: relative }
.szukajka .szukaj { margin-top: .6rem; min-height: 3rem; border-radius: .85rem;
  padding-right: .4rem }
.szukajka input[type="search"] { -webkit-appearance: none; appearance: none }
/* Jeden krzyżyk, nie dwa (USPRAWNIENIA Katalog #6): natywny znika,
   zostaje nasz, bo tylko nasz da się opisać dla czytnika ekranu. */
.szukajka input[type="search"]::-webkit-search-cancel-button,
.szukajka input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; appearance: none }
.szukajka .kasuj { flex: 0 0 auto; width: 2rem; height: 2rem; display: none;
  place-items: center; border: 0; border-radius: 999px; cursor: pointer;
  background: var(--secondary); color: var(--muted-foreground); font: inherit; padding: 0 }
.szukajka[data-pelne] .kasuj { display: grid }
.szukajka .kasuj:hover { color: var(--foreground) }

.wyniki-info { margin-top: .7rem; font-size: .9rem; color: var(--muted-foreground) }
.wyniki-info b { color: var(--foreground); font-weight: 600 }
.wyniki-info q { font-style: italic; color: var(--primary); quotes: "»" "«" }

/* trzy pigułki w rzędzie: te same tokeny co FilterPill.tsx */
.pigulki3 { display: flex; gap: .4rem; margin-top: .6rem }
.pigulki3 .pigulka { flex: 1 1 0 }

/* pigułka zawężenia nad wynikami („Kategoria: Kolędy ✕") */
.zawezenie { display: inline-flex; align-items: center; gap: .4rem; margin-top: .6rem;
  min-height: 2rem; border-radius: 999px; border: 1px solid var(--primary);
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  color: var(--foreground); font-size: .82rem; padding: .2rem .3rem .2rem .75rem }
.zawezenie b { font-weight: 600 }
.zawezenie button { border: 0; background: none; cursor: pointer; color: var(--muted-foreground);
  font: inherit; width: 1.5rem; height: 1.5rem; border-radius: 999px; display: grid; place-items: center }
.zawezenie button:hover { color: var(--foreground) }

/* ---------- WYNIK JAKO WIERSZ, NIE KARTA (§H.2 pkt 5) ---------- */
.wyniki { margin-top: .5rem; display: grid; gap: .25rem }
.wynik { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center;
  gap: .5rem; min-height: 3.5rem; padding: .4rem .6rem; border-radius: .6rem;
  border: 1px solid transparent; background: var(--card) }
.wynik:hover { border-color: color-mix(in srgb, var(--foreground) 24%, transparent) }
.wynik .w-lewa { display: block; min-width: 0 }
.wynik .w-tyt { display: block; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.wynik .w-tyt mark { background: none; color: var(--primary); font-weight: 700 }
.wynik .w-pod { display: flex; gap: .5rem; align-items: baseline; font-size: .8rem;
  color: var(--muted-foreground); overflow: hidden }
.wynik .w-pod .w-wyk { overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.wynik .w-pod .w-ak { font-family: var(--font-mono); color: var(--chord-ink);
  white-space: nowrap; flex: 0 0 auto }
.wynik .w-prawa { display: flex; align-items: center; gap: .4rem }
.wiecej { margin-top: .5rem; width: 100%; justify-content: center }

/* ---------- ZERO WYNIKÓW MÓWI, CO DALEJ (§H.2 pkt 8 i 11) ---------- */
.pusto-szukaj { margin-top: .8rem; border: 1px dashed var(--border); border-radius: .9rem;
  padding: 1rem; background: color-mix(in srgb, var(--card) 60%, transparent) }
.pusto-szukaj p { margin: 0 0 .7rem; color: var(--muted-foreground); font-size: .92rem }
.pusto-szukaj q { font-style: italic; color: var(--foreground); quotes: "»" "«" }

/* ============================================================
   DOPISANE dla makiety a3 („uczeń bez nagłówka, filtry przy
   szukajce, narzędzia rozdzielone", 2026-08-29, ANALIZA §H.6).
   Znowu WYŁĄCZNIE nowe nazwy klas albo reguły ZAWĘŻONE do nowego
   pojemnika `.filtry`: ten sam plik ładują a-polka, b-chwyty,
   c-kolekcje, a2-szukaj i makiety Rytmu oraz Wiedzy, więc nic
   z wcześniejszych bloków nie zmienia się ani nie znika.
   ============================================================ */

/* ---------- RZĄD FILTRÓW OBOK SZUKAJKI (§H.6, feedback 3) ----------
   Telefon: pole pełnej szerokości, pod nim pigułki.
   Desktop (≥ 48rem): jeden rząd [ pole ][ Kategoria ][ Język ][ Poziom ],
   dokładnie jak dziś w katalogu, tylko że tam pigułki stoją POD polem
   na każdej szerokości, a tu od 48rem wchodzą obok. */
.filtry { display: flex; flex-direction: column }
.filtry .szukajka .szukaj { margin-top: .5rem }
.filtry .pigulki3 { margin-top: .4rem; flex-wrap: wrap }
/* Podstawa 5rem, nie 6: przy 6rem trzy pigułki nie mieściły się na 320 px
   (288 px światła kontra 300 px potrzeby) i łamały się 2 + 1, spychając
   rząd narzędzi o 50 px. Przy 5rem trzy stoją w rzędzie na 320, a cztery
   (strona kategorii) łamią się dopiero poniżej 360 px. */
.filtry .pigulki3 .pigulka { flex: 1 1 5rem; min-height: 2.75rem; padding: .3rem .5rem }
.filtry .pigulki3 .pigulka .val { min-width: 0 }
.filtry .pigulki3 .pigulka .val span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
/* Sama WARTOŚĆ nie skraca się nigdy; ucina się dopisek o źródle, bo to
   przypis, a nie odpowiedź na pytanie „jaki język?". */
.filtry .pigulki3 .pigulka .val > span:first-child { flex: 0 0 auto }
.filtry .pigulki3 .pigulka .val > span.skad { flex: 0 1 auto; min-width: 0 }
/* „· z konta" / „· z urządzenia" przy języku: skąd wzięła się wartość
   (decyzja Adriana, §H.6 pkt 2). Na telefonie nie ma na to miejsca
   (zmierzone: 105 px tekstu na 91 px pigułki), więc zostaje sam język. */
.pigulka .skad { display: none; color: var(--muted-foreground); font-weight: 400;
  font-size: .78rem }
@media (min-width: 34rem) { .pigulka .skad { display: inline } }
@media (min-width: 48rem) {
  .filtry { flex-direction: row; align-items: center; gap: .5rem; margin-top: .6rem }
  .filtry .szukajka { flex: 1 1 18rem; min-width: 0 }
  .filtry .szukajka .szukaj { margin-top: 0 }
  .filtry .pigulki3 { flex: 0 1 34rem; margin-top: 0; flex-wrap: nowrap }
  .filtry .pigulki3 .pigulka { min-height: 3rem }
}

/* ---------- RZĄD KAFLI NARZĘDZI (§H.6 pkt 3) ----------
   `ToolCard compact` z SectionLanding.tsx: obramowanie `--border`, tło
   `--card`, nazwa `font-medium` zawijana do dwóch linii, strzałka.
   Trzy w rzędzie na KAŻDEJ szerokości: na telefonie zamiast menu sekcji,
   na desktopie jako półka narzędzi (ta sama, co w Teorii i Ćwiczeniach). */
.narzedzia { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: .4rem; margin-top: .4rem }
.narzedzie { display: flex; align-items: center; gap: .2rem; min-width: 0;
  border: 1px solid var(--border); border-radius: .5rem; background: var(--card);
  padding: .26rem .4rem; transition: border-color .18s }
.narzedzie:hover { border-color: color-mix(in srgb, var(--foreground) 30%, transparent) }
.narzedzie .nz { flex: 1 1 auto; min-width: 0; font-weight: 500;
  font-size: .78rem; line-height: 1.15 }
.narzedzie svg { flex: 0 0 auto; color: var(--muted-foreground) }
@media (min-width: 48rem) {
  .narzedzia { gap: .5rem; margin-top: .6rem }
  .narzedzie { padding: .55rem .7rem; gap: .5rem }
  .narzedzie .nz { font-size: .9rem; line-height: 1.3 }
}

/* ---------- MENU SEKCJI W PASKU (§H.6 pkt 2, SectionNav.tsx) ----------
   Rejestr `SECTIONS[songs].tools` ma dziś JEDEN wpis (Kreator melodii),
   więc menu Piosenek ma jedną pozycję. Po rozdzieleniu ma trzy i to
   pokazuje ta makieta. Rysunek 1:1 z SectionNav.tsx: karta pod linkiem,
   pozycja to nazwa `font-medium text-sm` i jedna linijka `text-xs`
   w `--muted-foreground`. Menu jest tylko od 48rem, bo `.secnav` też. */
.secitem { position: relative; display: inline-flex; align-items: center }
/* Tło NIEPRZEZROCZYSTE, choć menu nosi `.glass` po cień i obramowanie:
   w SectionNav.tsx menu stoi na `bg-popover`, a szkło nad rzędem kafli
   przepuszczało ich napisy i pozycje robiły się nieczytelne. */
.secmenu { position: absolute; top: 100%; left: 0; z-index: 40; display: none;
  width: 20rem; margin-top: .375rem; padding: .375rem; background: var(--card);
  border: 1px solid var(--border); border-radius: .75rem }
.secmenu[data-open] { display: block }
.secnav .secmenu a { display: block; width: 100%; padding: .5rem .75rem;
  border-radius: .5rem; font-size: .875rem; font-weight: 400; color: var(--foreground) }
.secnav .secmenu a:hover { background: var(--secondary); color: var(--foreground) }
.secmenu .t { display: block; font-size: .875rem; font-weight: 500; line-height: 1.375 }
.secmenu .m { display: block; font-size: .75rem; line-height: 1.375; color: var(--muted-foreground) }


/* ===== prototypy/wiedza/wiedza.css ===== */
/* wiedza.css - to, czego w powłoce Piosenek nie ma.

   POWŁOKA (tokeny, pasek, pasek dolny, karta utworu, chwyt, pigułka,
   szukajka, przełącznik makiety) siedzi w ../piosenki/piosenki.css i NIE
   jest tu powtórzona ani nadpisana. Tutaj są tylko rzeczy nowe dla sekcji
   Wiedza: karta ścieżki, kafel działu, wiersz pytania, półka narzędzi,
   blok autora, kolumna artykułu i karty kroków huba.

   Cztery makiety dzielą ten plik z tego samego powodu, dla którego trzy
   makiety Piosenek dzielą piosenki.css: mają się różnić układem pierwszego
   ekranu, nie rysunkiem kafla.

   Kolory WYŁĄCZNIE przez var(--...) z piosenki.css. Fraunces tylko
   w nagłówkach (WIEDZA_PLAN §4.3), tekst bieżący var(--font-sans). */

/* ---------- szapka sekcji ---------- */
.szapka { padding: 1.1rem 0 0 }
.wrap > .szapka:first-child { padding-top: .8rem }
.szapka .lede { margin-bottom: .2rem }

/* ---------- karta ścieżki (wariant A, sygnatura) ---------- */
.sciezki { display: grid; gap: .7rem; margin-top: 1rem }
@media (min-width: 48rem) { .sciezki { grid-template-columns: 1fr 1fr } }

.sciezka {
  border: 1px solid var(--border); border-radius: 1.1rem; background: var(--card);
  padding: .9rem 1rem 1rem; display: flex; flex-direction: column; gap: .1rem;
  box-shadow: 0 30px 60px -34px rgb(0 0 0 / .7);
}
body[data-motyw="ognisko-jasne"] .sciezka { box-shadow: 0 24px 48px -34px rgb(90 70 40 / .35) }
.sciezka[data-sezon] {
  grid-column: 1 / -1; flex-direction: row; align-items: center; flex-wrap: wrap;
  gap: .5rem .9rem; padding: .7rem 1rem; box-shadow: none;
  background: color-mix(in srgb, var(--card) 60%, transparent);
  border-style: dashed;
}
.k { font-family: var(--font-mono); font-size: .66rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--primary) }
.sciezka h2 { margin: .15rem 0 0; font-size: clamp(1.25rem, 4.2vw, 1.6rem); font-weight: 400;
  font-variation-settings: "opsz" 72, "SOFT" 25; letter-spacing: -.018em; line-height: 1.15 }
.sciezka[data-sezon] h2 { font-size: 1.1rem; margin: 0 }
.sciezka p { margin: .45rem 0 0; font-size: .92rem; color: var(--muted-foreground) }
.sciezka[data-sezon] p { margin: 0; flex: 1 1 12rem }
.sciezka .stopa { margin-top: .85rem; display: flex; flex-wrap: wrap; align-items: center; gap: .5rem }
.sciezka[data-sezon] .stopa { margin: 0 }

/* kropki postępu: ●●○○○○○ */
.postep { display: flex; align-items: center; gap: .5rem; margin-top: .6rem; flex-wrap: wrap }
.kropki { display: flex; gap: .25rem }
.kropki i { width: .5rem; height: .5rem; border-radius: 999px; border: 1px solid var(--muted-foreground);
  display: block }
.kropki i[data-on] { background: var(--primary); border-color: var(--primary) }
.kropki i[data-teraz] { background: var(--primary); border-color: var(--primary);
  outline: 2px solid color-mix(in srgb, var(--primary) 35%, transparent); outline-offset: 2px }
.postep .gdzie { font-family: var(--font-mono); font-size: .72rem; color: var(--muted-foreground) }
.sciezka .ile { font-family: var(--font-mono); font-size: .72rem; color: var(--muted-foreground) }

/* ---------- półka: nagłówek z liczbą ---------- */
.polka-head { display: flex; align-items: baseline; gap: .6rem; margin-bottom: .5rem }
.polka-head h2 { font-size: 1.05rem; font-weight: 500; font-variation-settings: "opsz" 40;
  letter-spacing: -.01em }
.polka-head .ile { font-family: var(--font-mono); font-size: .7rem; color: var(--muted-foreground) }
.polka-head .wsz { margin-left: auto; font-family: var(--font-mono); font-size: .72rem;
  color: var(--primary) }

/* ---------- kafel działu z dwoma pytaniami (wariant A) ---------- */
.dzialy { display: grid; gap: .6rem; margin-top: .5rem }
@media (min-width: 48rem) { .dzialy { grid-template-columns: 1fr 1fr } }
.dzial { border: 1px solid var(--border); border-radius: .9rem; background: var(--card);
  padding: .7rem .85rem .5rem }
.dzial .lbl { font-family: var(--font-mono); font-size: .62rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted-foreground) }
.dzial ul { list-style: none; margin: .35rem 0 0; padding: 0 }
.dzial li { border-top: 1px solid var(--border) }
.dzial li:first-child { border-top: 0 }
.dzial li a { display: flex; align-items: baseline; gap: .5rem; padding: .5rem 0; font-size: .92rem }
.dzial li a .strz { margin-left: auto; color: var(--muted-foreground); font-family: var(--font-mono);
  font-size: .8rem }
.dzial li a:hover { color: var(--primary) }
.dzial .wiecej { display: block; padding: .45rem 0; font-family: var(--font-mono); font-size: .7rem;
  color: var(--primary); border-top: 1px solid var(--border) }

/* ---------- lista pytań (wariant B) ---------- */
.grupa { margin-top: 1.2rem }
.lista { display: grid; gap: 0; margin-top: .3rem }
.wiersz { display: grid; grid-template-columns: 1fr; gap: .1rem; padding: .65rem 0;
  border-top: 1px solid var(--border) }
.wiersz .tyt { font-weight: 500; font-size: .95rem }
.wiersz .lede-w { font-size: .85rem; color: var(--muted-foreground); margin: 0 }
.wiersz .akcje { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-top: .25rem }
.wiersz .cwicz { font-family: var(--font-mono); font-size: .72rem; color: var(--primary) }
.wiersz .wkrotce { font-family: var(--font-mono); font-size: .68rem; color: var(--muted-foreground);
  border: 1px solid var(--border); border-radius: 999px; padding: .05rem .5rem }
@media (min-width: 48rem) {
  .wiersz { grid-template-columns: 1fr auto; align-items: baseline; column-gap: 1rem }
  .wiersz .lede-w { grid-column: 1 }
  .wiersz .akcje { grid-column: 2; grid-row: 1 / span 2; margin: 0; justify-content: flex-end }
}
.pusto { padding: 1.2rem 0; color: var(--muted-foreground); font-size: .9rem }
.pigulki { flex-wrap: wrap }
.pigulki .pigulka { flex: 0 1 auto; min-height: 2.25rem; border-radius: 999px;
  flex-direction: row; align-items: center; gap: .4rem; padding: .3rem .8rem;
  font-size: .82rem; font-family: var(--font-mono) }

/* ---------- półka narzędzi (trzy kafle ze zrzutem) ---------- */
.narzedzia { margin-top: 1.6rem }
.kafle { display: grid; gap: .6rem }
@media (min-width: 48rem) { .kafle { grid-template-columns: repeat(3, 1fr) } }
.kafel { display: flex; align-items: center; gap: .75rem; border: 1px solid var(--border);
  border-radius: .9rem; background: var(--card); padding: .6rem .75rem; overflow: hidden }
.kafel:hover { border-color: color-mix(in srgb, var(--primary) 60%, transparent) }
.kafel-tresc { display: flex; flex-direction: column; gap: .15rem; min-width: 0 }
.kafel-tyt { font-weight: 500 }
.kafel-meta { font-size: .8rem; color: var(--muted-foreground) }
.kafel img { margin-left: auto; flex: 0 0 auto; width: 5.5rem; height: 5.5rem; object-fit: cover;
  object-position: 50% 12%; border-radius: .6rem; border: 1px solid var(--border) }

/* ---------- kto to pisze ---------- */
.autor { margin-top: 1.6rem; border-top: 1px solid var(--border); padding-top: 1rem }
.autor h2 { font-size: 1rem; font-weight: 500; font-variation-settings: "opsz" 40 }
.autor blockquote { margin: .5rem 0 0; font-size: .95rem; color: var(--muted-foreground);
  max-width: 40rem; line-height: 1.55 }
.autor .kto { margin: .5rem 0 0; font-family: var(--font-mono); font-size: .74rem }
.autor .kto a { color: var(--primary) }

/* ---------- ARTYKUŁ ---------- */
.wroc { display: block; font-family: var(--font-mono); font-size: .72rem;
  color: var(--muted-foreground); padding: .8rem 0 0 }
.wroc:hover { color: var(--primary) }
.art { padding-top: .8rem }
/* 65 znaków w wierszu (WIEDZA_PLAN §4.3). Kolumna, nie cała szerokość.
   ZMIERZONE: samo `65ch` tego NIE daje. `ch` to szerokość znaku „0",
   a w tym kroju „0" jest szeroki: 65ch wyszło 655 px, czyli 90 znaków
   polskiego tekstu w wierszu. Prawdziwe 65 znaków wypada na ~30rem,
   więc kolumnę tnie mniejsza z dwóch wartości. */
.kolumna { max-width: min(65ch, 30rem) }
.art h1 { font-size: clamp(1.55rem, 5.2vw, 2.2rem); margin-top: .3rem }
.art .odp { font-size: 1.05rem; color: var(--foreground); margin: .7rem 0 0; max-width: 65ch;
  line-height: 1.5 }
.art .podpis { font-family: var(--font-mono); font-size: .7rem; color: var(--muted-foreground);
  margin: .6rem 0 0; display: flex; flex-wrap: wrap; gap: .5rem }
.art p, .art li { font-family: var(--font-sans); font-size: 1rem; line-height: 1.62 }
.art p { margin: .95rem 0 0 }
.art h2 { font-size: 1.2rem; font-weight: 500; font-variation-settings: "opsz" 40;
  letter-spacing: -.01em; margin: 1.6rem 0 0 }
.art table { border-collapse: collapse; margin: .9rem 0 0; width: 100%; max-width: 65ch;
  font-size: .92rem }
.art th, .art td { text-align: left; padding: .4rem .6rem; border-bottom: 1px solid var(--border) }
.art th { font-family: var(--font-mono); font-size: .68rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted-foreground); font-weight: 400 }
.art td.mono { font-family: var(--font-mono); font-size: .85rem; color: var(--chord-ink) }

/* żywy element: dwa chwyty i strzałka zmiany */
.zywy { margin: 1.1rem 0 0; border: 1px solid var(--border); border-radius: 1rem;
  background: var(--card); padding: .8rem 1rem; max-width: min(65ch, 30rem) }
.zywy-rzad { display: flex; align-items: center; justify-content: center; gap: .6rem; flex-wrap: wrap }
.zywy-strzalka { font-family: var(--font-mono); color: var(--muted-foreground) }
.zywy figcaption, .zywy > figcaption { font-size: .82rem; color: var(--muted-foreground);
  margin-top: .6rem; text-align: center }

/* Zrób to teraz */
.zrob { margin: 1.4rem 0 0; border: 1px solid color-mix(in srgb, var(--primary) 45%, var(--border));
  border-radius: 1rem; background: var(--card); padding: .9rem 1rem 1rem; max-width: min(65ch, 30rem) }
.zrob h2 { margin: .1rem 0 0 }
.zrob .why { font-size: .92rem; color: var(--muted-foreground); margin: .5rem 0 0 }
.zrob .miara { font-family: var(--font-mono); font-size: .74rem; color: var(--foreground);
  margin: .6rem 0 0 }
.zrob .stopa { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin-top: .8rem }
.zrob .adres { font-family: var(--font-mono); font-size: .68rem; color: var(--muted-foreground) }

/* Zagraj to: karty utworów w rzędzie przewijanym w bok */
.karty { display: flex; gap: .6rem; overflow-x: auto; scroll-snap-type: x proximity;
  padding-bottom: .3rem; margin: .6rem -1rem 0; padding-left: 1rem; padding-right: 1rem }
@media (min-width: 48rem) { .karty { margin: .6rem -1.5rem 0; padding-left: 1.5rem; padding-right: 1.5rem } }
.karty .song { flex: 0 0 14rem; scroll-snap-align: start }

/* Dalej */
.dalej { margin: 1.6rem 0 0; border-top: 1px solid var(--border); padding-top: .9rem; max-width: min(65ch, 30rem) }
.dalej .lbl { font-family: var(--font-mono); font-size: .62rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted-foreground) }
.dalej a { display: block; margin-top: .25rem; font-family: var(--font-display);
  font-size: 1.05rem; font-variation-settings: "opsz" 40 }
.dalej a:hover { color: var(--primary) }
.niedowiarek { margin: 1.4rem 0 0; max-width: 65ch; border-left: 2px solid var(--border);
  padding-left: .9rem }
.niedowiarek .glos { font-family: var(--font-mono); font-size: .88rem; color: var(--muted-foreground) }
.niedowiarek p { margin-top: .5rem }

/* ---------- HUB: karty kroków ---------- */
.kroki { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; gap: .5rem }
.krok { display: flex; gap: .75rem; border: 1px solid var(--border); border-radius: .9rem;
  background: var(--card); padding: .7rem .85rem }
.krok .nr { flex: 0 0 1.9rem; height: 1.9rem; border-radius: 999px; border: 1px solid var(--border);
  display: grid; place-items: center; font-family: var(--font-mono); font-size: .8rem;
  color: var(--muted-foreground) }
.krok-tresc { min-width: 0; flex: 1 }
.krok-tyt { font-weight: 500; display: block }
.krok-lede { margin: .2rem 0 0; font-size: .86rem; color: var(--muted-foreground) }
.krok-meta { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-top: .4rem }
.krok-meta .mono { font-family: var(--font-mono); font-size: .7rem; color: var(--muted-foreground) }
.krok-meta .cwicz { color: var(--primary) }
.krok-meta .wkrotce { border: 1px solid var(--border); border-radius: 999px; padding: .05rem .5rem }
.krok-meta .teraz { color: var(--primary) }
body[data-konto="uczen"] .krok[data-zrobiony-u] .nr { border-color: var(--primary); color: var(--primary) }
body[data-konto="uczen"] .krok[data-zrobiony-u] .krok-tyt { color: var(--muted-foreground) }
body[data-konto="uczen"] .krok[data-teraz-u] { border-color: color-mix(in srgb, var(--primary) 60%, transparent) }
body[data-konto="uczen"] .krok[data-teraz-u] .nr { background: var(--primary); color: var(--primary-foreground);
  border-color: var(--primary) }

/* ---------- przełącznik makiety bez JS (linki zamiast przycisków) ---------- */
.persona-linki a { font: inherit; letter-spacing: inherit; text-transform: inherit;
  border-radius: 999px; padding: .25rem .5rem; color: var(--muted-foreground) }
body[data-konto="gosc"] .persona-linki a[href*="konto=gosc"],
body[data-konto="uczen"] .persona-linki a[href*="konto=uczen"],
body[data-motyw="ognisko"] .persona-linki a[href*="motyw=ognisko"]:not([href*="jasne"]),
body[data-motyw="ognisko-jasne"] .persona-linki a[href*="motyw=ognisko-jasne"] {
  background: var(--primary); color: var(--primary-foreground);
}

/* podpis przy żywym elemencie w karcie ścieżki */
.zywy-rzad .gdzie { font-family: var(--font-mono); font-size: .72rem; color: var(--muted-foreground) }
.sciezka .zywa:empty { display: none }

/* `hidden` musi wygrać z `display: grid` z .persona w piosenki.css:
   bez tego przełącznik makiety widać na zrzucie bez JS. */
.persona-linki[hidden] { display: none !important }

/* ===========================================================================
   MAKIETA 2 (układ jak Claude Academy): a2-akademia.html, hub2.html,
   artykul2.html. ANALIZA §I.

   Dopisane, nie podmienione: makiety rundy 1 (a-sciezki, b-pytania,
   artykul, hub) korzystają z reguł WYŻEJ i żadna z nich nie jest tu
   nadpisana. Reguła numer jeden tej rundy: KAŻDA KARTA MA OBRAZEK, więc
   ilustracje mają własne klasy (`.ilu`, `.ikw`, `.kadr`) i wszystkie
   biorą obrazek z silnika: chwyt (P.grip), pas bicia (P.lane), zrzut
   z runda-6/img albo ikona lucide z icons.js.
   =========================================================================== */

/* ---------- blok z nagłówkiem i lede ---------- */
.blok { margin-top: 1.7rem }
/* pierwszy blok pod szapką stoi bliżej: liczy się droga do pierwszej
   karty kursu (miara z §I.5) */
.szapka + .blok { margin-top: .9rem }
.blok-head { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap }
.blok-head h2 { font-size: 1.15rem; font-weight: 500; font-variation-settings: "opsz" 40;
  letter-spacing: -.01em }
.blok-head .ile { font-family: var(--font-mono); font-size: .7rem; color: var(--muted-foreground) }
.blok > .lede { margin: .15rem 0 .55rem; font-size: .88rem }

/* ---------- etykieta typu treści (KURS / PORADNIK / LEKCJA n z m) ---------- */
.typ { font-family: var(--font-mono); font-size: .62rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--primary); display: block }
.typ a { color: inherit; text-decoration: underline; text-underline-offset: .2em }

/* ---------- ikona lucide w kwadracie (§I.4) ---------- */
.ikw { display: grid; place-items: center; width: 2.2rem; height: 2.2rem; flex: 0 0 auto;
  border-radius: .65rem; color: var(--primary);
  background: color-mix(in srgb, var(--primary) 14%, var(--card));
  border: 1px solid color-mix(in srgb, var(--primary) 22%, transparent) }

/* ---------- ilustracja karty: chwyt, pas bicia albo kadr ze zrzutu ---------- */
.ilu { display: flex; align-items: center; justify-content: center; gap: .25rem;
  border-radius: .7rem; padding: .35rem .45rem;
  background: color-mix(in srgb, var(--primary) 8%, var(--card));
  border: 1px solid var(--border) }
.ilu.kadr { padding: 0; overflow: hidden }
.ilu.kadr img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 14%; display: block }

/* ---------- KURSY: karta pozioma pełnej szerokości ---------- */
.kursy { display: grid; gap: .6rem }
.kurs { display: grid; grid-template-columns: auto 1fr; gap: .6rem .8rem; align-items: start;
  border: 1px solid var(--border); border-radius: 1.1rem; background: var(--card);
  padding: .75rem .8rem; box-shadow: 0 30px 60px -34px rgb(0 0 0 / .7) }
body[data-motyw="ognisko-jasne"] .kurs { box-shadow: 0 24px 48px -34px rgb(90 70 40 / .35) }
.kurs-ilu { width: 5.4rem; height: 4.6rem; display: grid; place-items: center; overflow: hidden;
  border-radius: .8rem; border: 1px solid var(--border);
  background: color-mix(in srgb, var(--primary) 12%, var(--card)) }
.kurs-ilu img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 12% }
.kurs-ilu .lane b { width: .55rem; height: 1.15rem }
.kurs h2 { margin: .2rem 0 0; font-size: clamp(1.15rem, 4vw, 1.45rem); font-weight: 400;
  font-variation-settings: "opsz" 72, "SOFT" 25; letter-spacing: -.018em; line-height: 1.15 }
.kurs p { margin: .3rem 0 0; font-size: .88rem; color: var(--muted-foreground) }
.kurs .meta { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .5rem;
  font-family: var(--font-mono); font-size: .7rem; color: var(--muted-foreground) }
.kurs .stopa { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-top: .55rem }
.kurs .strzalka-kolo { display: none }
@media (min-width: 48rem) {
  .kurs { grid-template-columns: auto 1fr auto; align-items: center }
  .kurs-ilu { width: 8.5rem; height: 6rem }
  .kurs .strzalka-kolo { display: grid; place-items: center; width: 2.4rem; height: 2.4rem;
    border-radius: 999px; border: 1px solid var(--border); color: var(--primary) }
  .kurs:hover .strzalka-kolo { border-color: var(--primary) }
}

/* pasek postępu kursu */
.pasek { display: block; width: 100%; max-width: 12rem; height: .35rem; border-radius: 999px;
  background: color-mix(in srgb, var(--muted-foreground) 30%, transparent); overflow: hidden }
.pasek > span { display: block; height: 100%; background: var(--primary) }
.kurs-akcja { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin-top: .8rem }
.kurs-postep { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .7rem }
.kurs-postep .mono { font-family: var(--font-mono); font-size: .72rem; color: var(--muted-foreground) }
.pasek-kursu { max-width: 18rem; margin-top: .5rem }

/* ---------- NA POCZĄTEK: trzy karty z miniaturą 16:10 ----------
   ZMIERZONE: trzy karty jedna pod drugą kosztują na telefonie 750 px
   i spychają blok „Tematy" o dwa przewinięcia w dół (bramka §I.5 chce
   cztery kafle tematów po JEDNYM). Na telefonie jest to więc rząd
   przewijany w bok, jak karty utworów; na desktopie siatka 3 × 1. */
.start-siatka { display: flex; gap: .6rem; overflow-x: auto; scroll-snap-type: x proximity;
  margin: 0 -1rem; padding: 0 1rem .3rem }
.start-karta { flex: 0 0 15rem; scroll-snap-align: start }
@media (min-width: 34rem) {
  .start-siatka { display: grid; grid-template-columns: repeat(3, 1fr); gap: .7rem;
    margin: 0; padding: 0; overflow: visible }
  .start-karta { flex: initial }
}
.start-karta { display: flex; flex-direction: column; border: 1px solid var(--border);
  border-radius: .9rem; background: var(--card); overflow: hidden }
.start-karta:hover { border-color: color-mix(in srgb, var(--primary) 60%, transparent) }
.start-karta .kadr { position: relative; aspect-ratio: 16 / 10; border: 0; border-radius: 0;
  border-bottom: 1px solid var(--border) }
.start-karta .znaczek { position: absolute; right: .4rem; bottom: .4rem; border-radius: 999px;
  padding: .1rem .5rem; font-family: var(--font-mono); font-size: .64rem;
  background: var(--background); color: var(--foreground); border: 1px solid var(--border) }
.start-tresc { padding: .6rem .75rem .75rem }
.start-tresc .tyt { display: block; margin-top: .25rem; font-weight: 500; font-size: .95rem;
  line-height: 1.3 }
.start-tresc .mono { display: block; margin-top: .35rem; font-family: var(--font-mono);
  font-size: .68rem; color: var(--muted-foreground) }

/* ---------- TEMATY: kafel z ikoną, 2 kolumny na telefonie ---------- */
.tematy { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem }
@media (min-width: 48rem) { .tematy { grid-template-columns: repeat(3, 1fr) } }
.temat { display: flex; align-items: center; gap: .6rem; border: 1px solid var(--border);
  border-radius: .9rem; background: var(--card); padding: .65rem .7rem }
.temat:hover { border-color: color-mix(in srgb, var(--primary) 60%, transparent) }
.temat .tyt { display: block; font-weight: 500; font-size: .9rem; line-height: 1.2 }
.temat .mono { display: block; margin-top: .15rem; font-family: var(--font-mono);
  font-size: .66rem; color: var(--muted-foreground) }

/* ---------- baner „Ćwicz codziennie" ---------- */
.baner { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; margin-top: 1.6rem;
  border: 1px solid color-mix(in srgb, var(--primary) 35%, var(--border)); border-radius: 1rem;
  background: var(--card); padding: .8rem .9rem }
.baner .tresc { flex: 1 1 14rem; min-width: 0 }
.baner .tyt { display: block; font-family: var(--font-display); font-size: 1.05rem;
  font-variation-settings: "opsz" 40 }
.baner p { margin: .2rem 0 0; font-size: .88rem; color: var(--muted-foreground) }

/* ---------- HUB2: lekcje kursu ---------- */
.lekcje { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; gap: .5rem }
.lekcja { display: grid; grid-template-columns: auto 1fr; gap: .55rem .7rem; align-items: start;
  border: 1px solid var(--border); border-radius: .9rem; background: var(--card);
  padding: .7rem .8rem }
.lekcja-znak { display: flex; flex-direction: column; align-items: center; gap: .35rem }
.lekcja .nr { width: 1.9rem; height: 1.9rem; border-radius: 999px; border: 1px solid var(--border);
  display: grid; place-items: center; font-family: var(--font-mono); font-size: .8rem;
  color: var(--muted-foreground) }
.lekcja-tresc { min-width: 0 }
.lekcja-tyt { display: block; margin-top: .15rem; font-weight: 500; line-height: 1.25 }
.lekcja-lede { margin: .2rem 0 0; font-size: .86rem; color: var(--muted-foreground) }
.lekcja .ilu { grid-column: 2; justify-self: start; margin-top: .1rem }
.lekcja .ilu.kadr { width: 5rem; height: 3.2rem }
@media (min-width: 34rem) {
  .lekcja { grid-template-columns: auto 1fr auto }
  .lekcja .ilu { grid-column: 3; grid-row: 1; align-self: center; margin: 0 }
}
body[data-konto="uczen"] .lekcja[data-zrobiony-u] .nr { border-color: var(--primary); color: var(--primary) }
body[data-konto="uczen"] .lekcja[data-zrobiony-u] .lekcja-tyt { color: var(--muted-foreground) }
body[data-konto="uczen"] .lekcja[data-teraz-u] { border-color: color-mix(in srgb, var(--primary) 60%, transparent) }
body[data-konto="uczen"] .lekcja[data-teraz-u] .nr { background: var(--primary);
  color: var(--primary-foreground); border-color: var(--primary) }

/* ---------- ARTYKUL2: kolumna 42 rem, 17 px, interlinia 1.65 (§I.3) ---------- */
.kolumna2 { max-width: 42rem }
.art2 .odp { max-width: 42rem; font-size: 1.1rem }
.art2 .kolumna2 p, .art2 .kolumna2 li { font-size: 1.0625rem; line-height: 1.65 }
.art2 .kolumna2 p { margin: 1.05rem 0 0 }
.art2 table { max-width: 42rem }
.art2 .zywy, .art2 .zrob, .art2 .niedowiarek { max-width: 42rem }
.art2 .niedowiarek p { font-size: 1.0625rem; line-height: 1.65 }
.blok-head .ikw { width: 1.9rem; height: 1.9rem; border-radius: .55rem }

/* karta „Następna lekcja" */
.nastepna { display: flex; align-items: center; gap: .75rem; max-width: 42rem; margin-top: 1rem;
  border: 1px solid var(--border); border-radius: .9rem; background: var(--card);
  padding: .75rem .8rem }
.nastepna:hover { border-color: color-mix(in srgb, var(--primary) 60%, transparent) }
.nast-tresc { min-width: 0; flex: 1 }
.nast-tyt { display: block; margin-top: .2rem; font-family: var(--font-display); font-size: 1.05rem;
  font-variation-settings: "opsz" 40; line-height: 1.25 }
.nast-tresc .mono { display: block; margin-top: .25rem; font-family: var(--font-mono);
  font-size: .68rem; color: var(--muted-foreground) }
.nastepna .strzalka { color: var(--primary); flex: 0 0 auto }

/* ===========================================================================
   STRONA KURSU (hub2) i prawa kolumna lekcji (artykul2), wg prawdziwych
   zrzutów strony kursu Claude Academy (Adrian, 2026-08-29 18:20).
   Różnice wobec §I.5 są opisane w README („z zrzutów Adriana 18:20").
   =========================================================================== */

/* ---------- pas nagłówka na pełną szerokość ---------- */
.kurs-pas { background: color-mix(in srgb, var(--primary) 14%, var(--card));
  border-bottom: 1px solid var(--border); padding: .6rem 0 1.2rem; position: relative; z-index: 1 }
.kurs-pas-tresc { display: grid; gap: 1rem; align-items: center }
.kurs-pas h1 { font-size: clamp(1.7rem, 6vw, 2.4rem); margin: .2rem 0 0 }
.kurs-pas .odp { margin: .55rem 0 0; max-width: 34rem; font-size: 1rem; color: var(--foreground) }
.kurs-pas .crumb { margin-top: .5rem }
.kurs-pas-ilu { display: none }
@media (min-width: 48rem) {
  .kurs-pas-tresc { grid-template-columns: minmax(0, 1fr) auto; gap: 2rem }
  .kurs-pas-ilu { display: flex; align-items: center; justify-content: center; gap: .3rem;
    width: 11rem; height: 11rem; border-radius: 999px; background: var(--card);
    border: 1px solid var(--border); box-shadow: 0 30px 60px -34px rgb(0 0 0 / .7) }
}

/* ---------- chipy meta z ikonami ---------- */
.chipy { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .9rem }
.chip { display: inline-flex; align-items: center; gap: .35rem; border-radius: 999px;
  border: 1px solid var(--border); background: var(--card); padding: .25rem .7rem;
  font-family: var(--font-mono); font-size: .72rem; color: var(--foreground) }
.chip svg { color: var(--primary) }

/* ---------- dwa przyciski, u ucznia przycisk i pasek ---------- */
.kurs-akcja .pary { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem }

/* ---------- „Czego się nauczysz" ---------- */
.nauczysz { margin-top: 1.4rem; border: 1px solid var(--border); border-radius: 1rem;
  background: var(--card); padding: .9rem 1rem 1rem; max-width: 42rem }
.nauczysz h2 { font-size: 1.15rem; font-weight: 500; font-variation-settings: "opsz" 40; margin: 0 }
.nauczysz .pod { margin: .25rem 0 .5rem; font-family: var(--font-mono); font-size: .7rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted-foreground) }
.nauczysz ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .1rem }
.nauczysz li { display: grid; grid-template-columns: 1rem 1fr; gap: .4rem; align-items: baseline;
  padding: .35rem 0; border-top: 1px solid var(--border); font-size: .95rem }
.nauczysz li:first-child { border-top: 0 }
.nauczysz .ch { color: var(--primary); font-family: var(--font-mono) }

/* ---------- układ dwukolumnowy: treść + spis lekcji ---------- */
.kurs-uklad { display: block }
.kurs-spis { margin-top: 1.6rem }
.spis-tyt { font-size: 1.05rem; font-weight: 500; font-variation-settings: "opsz" 40;
  margin-bottom: .2rem }
.modul-nazwa { margin: 1rem 0 .35rem; font-family: var(--font-mono); font-size: .64rem;
  letter-spacing: .16em; text-transform: uppercase; color: var(--muted-foreground) }
.spis-nota { margin-top: .8rem; font-size: .82rem; color: var(--muted-foreground); max-width: 42rem }
.lekcje + .modul-nazwa { margin-top: 1.1rem }

@media (min-width: 64rem) {
  .kurs-uklad { display: grid; grid-template-columns: minmax(0, 1fr) 20rem; gap: 2rem;
    align-items: start }
  /* Sticky BEZ wewnętrznego przewijania: siedem lekcji mieści się w oknie
     1280 × 800 (zmierzone), a `overflow: auto` ucinałby dwie ostatnie na
     każdym zrzucie i u każdego, kto ma niższe okno. Gdy kurs urośnie ponad
     ekran, kolumna po prostu przestanie się kleić i pojedzie z treścią. */
  .kurs-spis { position: sticky; top: 4.6rem; margin-top: 1.2rem;
    border-left: 1px solid var(--border); padding-left: 1rem }
  /* w wąskiej kolumnie zostaje to, co prowadzi: numer, ikona, tytuł, stan */
  .kurs-spis .lekcje { gap: .4rem }
  .kurs-spis .lekcja { padding: .45rem .5rem; gap: .35rem .5rem }
  .kurs-spis .wkrotce { white-space: nowrap; font-size: .64rem }
  .kurs-spis .lekcja-lede, .kurs-spis .cwicz, .kurs-spis .lekcja .typ,
  .kurs-spis .temat-nazwa, .kurs-spis .krok-meta [aria-hidden] { display: none }
  .kurs-spis .lekcja-tyt { font-size: .84rem; line-height: 1.25; margin: 0 }
  .kurs-spis .krok-meta { gap: .3rem; margin-top: .25rem }
  .kurs-spis .ilu { padding: .2rem .25rem }
  .kurs-spis .ilu .grip { width: 26px; height: 36px }
  .kurs-spis .ilu.kadr { width: 3rem; height: 2rem }
  .kurs-spis .lane b { width: .4rem; height: .9rem; font-size: .45rem }
  .kurs-spis .ikw { width: 1.5rem; height: 1.5rem; border-radius: .45rem }
  .kurs-spis .nr { width: 1.5rem; height: 1.5rem; font-size: .7rem }
}
/* Na stronie lekcji prawa kolumna jest DODATKIEM: telefon dostaje zamiast
   niej kartę „Następna lekcja", więc spis pokazuje się dopiero na desktopie. */
.art-spis { display: none }
@media (min-width: 64rem) { .art-spis { display: block } }
/* lekcja, którą właśnie czytasz: podświetlona bez względu na personę */
.lekcja[data-teraz] { border-color: color-mix(in srgb, var(--primary) 60%, transparent) }
.lekcja[data-teraz] .nr { background: var(--primary); color: var(--primary-foreground);
  border-color: var(--primary) }
.lekcja[data-zrobiony] .nr { border-color: var(--primary); color: var(--primary) }
.lekcja[data-zrobiony] .lekcja-tyt { color: var(--muted-foreground) }
.krok-meta .teraz { color: var(--primary) }

/* ===========================================================================
   MAKIETA 3 (a3-akademia.html, 2026-09-03): strona sekcji z pasem nagłówka
   i chipami z hub2, kursy jako trzy równe kafle, narzędzia rysowane
   z silnika. Dopisane, nie podmienione: a2 korzysta z reguł wyżej
   i żadna nie jest tu nadpisana; wspólne klasy (.kurs-pas, .chip, .pasek,
   .start-karta, .temat, .baner) są używane bez zmian.
   =========================================================================== */

/* pas nagłówka sekcji: ten sam .kurs-pas co w hub2, tylko ciaśniejszy dół,
   bo pod nim zaczyna się lista, a nie treść */
.a3-pas { padding-bottom: 1.1rem }
.a3-pas .kurs-akcja { margin-top: .9rem }
.a3-pas .pasek-kursu { margin-top: .5rem }
.a3-strzalka { color: var(--muted-foreground); font-family: var(--font-mono); font-size: 1rem;
  padding: 0 .15rem }
/* pierwszy blok pod pasem stoi bliżej (jak .szapka + .blok) */
.a3 > .blok:first-child { margin-top: 1.1rem }

/* ---------- KURSY: trzy równe kafle (Featured courses), jedna akcja ---------- */
.a3-kursy { display: grid; gap: .6rem }
@media (min-width: 48rem) { .a3-kursy { grid-template-columns: repeat(3, 1fr); gap: .8rem } }
.a3-kurs { display: grid; grid-template-columns: auto 1fr; gap: .6rem .8rem; align-items: start;
  border: 1px solid var(--border); border-radius: 1.1rem; background: var(--card);
  padding: .7rem .75rem; color: inherit; text-decoration: none;
  box-shadow: 0 30px 60px -34px rgb(0 0 0 / .7) }
body[data-motyw="ognisko-jasne"] .a3-kurs { box-shadow: 0 24px 48px -34px rgb(90 70 40 / .35) }
.a3-kurs:hover { border-color: color-mix(in srgb, var(--primary) 60%, transparent) }
.a3-kurs[data-zaczety] { border-color: color-mix(in srgb, var(--primary) 45%, var(--border)) }
.a3-kurs-ilu { width: 5.2rem; height: 4.6rem; display: flex; align-items: center; justify-content: center;
  gap: .15rem; overflow: hidden; border-radius: .8rem; border: 1px solid var(--border);
  background: color-mix(in srgb, var(--primary) 12%, var(--card)) }
.a3-kurs-ilu.kadr img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 12%; display: block }
.a3-kurs-ilu .lane b { width: .5rem; height: 1.1rem }
.a3-kurs-ilu .a3-strzalka { font-size: .8rem; padding: 0 }
.a3-kurs-tresc { min-width: 0; display: flex; flex-direction: column }
.a3-kurs h3 { margin: .15rem 0 0; font-family: var(--font-display); font-weight: 400;
  font-size: clamp(1.1rem, 4vw, 1.3rem); font-variation-settings: "opsz" 72, "SOFT" 25;
  letter-spacing: -.018em; line-height: 1.15 }
.a3-kurs p { margin: .3rem 0 0; font-size: .86rem; color: var(--muted-foreground) }
.a3-kurs .meta { display: block; margin-top: .45rem; font-family: var(--font-mono); font-size: .68rem;
  color: var(--muted-foreground) }
.a3-kurs .stopa { display: grid; gap: .4rem; margin-top: .55rem }
.a3-dalej { font-weight: 500; font-size: .88rem; color: var(--primary) }
@media (min-width: 48rem) {
  /* na desktopie kafel pionowy: ilustracja NAD treścią, jak Featured courses */
  .a3-kurs { grid-template-columns: 1fr; padding: .75rem .85rem .85rem }
  .a3-kurs-ilu { width: 100%; height: 6.4rem; gap: .35rem }
  .a3-kurs-ilu .lane b { width: .7rem; height: 1.5rem }
  .a3-kurs-ilu .grip { transform: scale(1.15) }
  .a3-kurs-tresc { flex: 1 }
  .a3-kurs .stopa { margin-top: auto; padding-top: .6rem }
}

/* ---------- NA POCZĄTEK i NARZĘDZIA: na telefonie rząd z podglądem
   następnej karty (78 % szerokości), żeby było widać, że jest co przewinąć;
   a2 miało sztywne 15 rem i ucięcie wyglądało jak błąd, nie zaproszenie */
.a3-start .start-karta { flex: 0 0 min(78vw, 15rem) }
@media (min-width: 34rem) { .a3-start .start-karta { flex: initial } }
.a3-narz-ilu { aspect-ratio: 16 / 10; border: 0; border-radius: 0; border-bottom: 1px solid var(--border);
  gap: .3rem; padding: .4rem }
.a3-narz-ilu .grip { width: 26px; height: 36px }
.a3-stopnie { display: flex; gap: .3rem; margin-bottom: .35rem }
.a3-stopnie b { display: grid; place-items: center; min-width: 1.7rem; height: 1.7rem; padding: 0 .3rem;
  border-radius: .5rem; border: 1px solid var(--border); background: var(--card);
  font-family: var(--font-mono); font-weight: 500; font-size: .78rem }
.a3-stopnie b:first-child { border-color: var(--primary); color: var(--primary) }
.a3-narz-ilu:has(.a3-stopnie) { flex-direction: column }
.a3-lane-static b { width: .5rem; height: 1.05rem }
.a3-skala { max-width: 100%; height: auto }

/* ---------- TEMATY: jedno zdanie pod nazwą (Browse by role) ----------
   Dwie kolumny już od 360 px, zdanie ucięte do dwóch linijek: z jedną
   kolumną po jednym przewinięciu było widać 2 kafle z 6 (bramka §I.5 chce
   4), z dwiema i klamrą wchodzi cała szóstka. Na 320 px jedna kolumna. */
.a3-tematy { grid-template-columns: 1fr; gap: .5rem }
@media (min-width: 22.5rem) { .a3-tematy { grid-template-columns: 1fr 1fr } }
@media (min-width: 64rem) { .a3-tematy { grid-template-columns: repeat(3, 1fr) } }
.a3-temat { align-items: flex-start; padding: .6rem .65rem; gap: .5rem }
.a3-temat .ikw { margin-top: .1rem; width: 2rem; height: 2rem }
.a3-temat > span { min-width: 0 }
.a3-temat .tyt { font-size: .86rem }
.a3-temat-lede { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
  margin-top: .15rem; font-size: .76rem; line-height: 1.3; color: var(--muted-foreground) }
@media (min-width: 48rem) {
  .a3-temat { padding: .7rem .75rem }
  .a3-temat .tyt { font-size: .9rem }
  .a3-temat-lede { font-size: .82rem; -webkit-line-clamp: 3 }
}

/* czwarty chip pasa i większe chwyty CAGED tylko od 48 rem */
.a3-chip-desk { display: none }
.a3-link { align-self: center; font-size: .9rem; font-weight: 500; color: var(--foreground);
  text-decoration: underline; text-underline-offset: .2em; text-decoration-color: var(--primary) }
@media (min-width: 48rem) {
  .a3-chip-desk { display: inline-flex }
  .a3-narz-ilu .grip { width: 38px; height: 52px }
  .a3-narz-ilu .a3-skala { transform: scale(1.35) }
  .a3-narz-ilu .a3-stopnie b { min-width: 2rem; height: 2rem; font-size: .9rem }
  .a3-narz-ilu .a3-lane-static b { width: .65rem; height: 1.3rem }
}


/* ===== wiedza/wiedza-art.css ===== */
/* wiedza-art.css: biblioteka figur, animacji i widgetów artykułu Wiedzy.

   PO CO OSOBNY PLIK: `prototypy/wiedza/wiedza.css` jest oprawą MAKIET
   (pasek, karty kursu, układ lekcji) i zostaje nietknięty. Tu leży tylko
   to, czego artykuł potrzebuje ponad makietę: ramka rysunku, pięć animacji,
   ramki widgetów i bloki, których makieta nie miała (bibliografia,
   przełącznik języka, callout). Nic stąd nie powtarza reguł z wiedza.css
   ani z piosenki.css.

   Kolejność wczytania (artykuł w frontend/wiedza/pl/ albo /en/):
     ../../prototypy/piosenki/piosenki.css   tokeny motywu, powłoka, .lane, .grip
     ../../prototypy/wiedza/wiedza.css       układ artykułu, .zywy, .zrob
     ../wiedza-art.css                       ten plik

   SPIS KLAS

   Figury
     .fig               ramka rysunku: karta z obramowaniem, rysunek na środku, podpis pod spodem.
     .fig-szeroka       ta sama ramka na pełną szerokość kolumny tekstu (42 rem).
     .fig figcaption    podpis mono, mówiący na co patrzeć; jedno albo dwa zdania.

   Animacje (ruch pokazuje CZAS, nie błyszczy; czas taktu w zmiennej --tempo)
     .anim-zmiana       dwa chwyty w .zywy-rzad zapalają się na przemian.
     .anim-bicie        kolejne pola paska .lane świecą po kolei w tempie taktu.
     .anim-wahadlo      wahadło metronomu (grupa .wahadlo w SVG) kołysze się o 20 stopni.
     .anim-puls         kropka .progress-dots albo .puls pulsuje na miarę.
     .anim-strzalka     strzałka .strzalka bije w dół, .strzalka-gora w górę.
     Każda z nich stoi pod @media (prefers-reduced-motion: reduce).

   Bloki treści
     .doczytaj          bibliografia: tytuł, autor, po co; linki zewnętrzne z ikoną strzałki.
     .jezyk             przełącznik PL i EN w prawym górnym rogu nagłówka artykułu.
     .tabela-danych     tabela palców, strun i temp: nagłówki mono, wiersze na przemian.
     .callout           ramka wyróżnienia, jedno zdanie do dwóch akapitów.
     .callout-miara     wariant z miarą sukcesu (znak nuty, barwa primary).
     .callout-uwaga     wariant ostrzeżenia (wykrzyknik, barwa accent).
     .callout-ja        wariant „co mnie myliło", głosem autora (cudzysłów).

   Widgety (ożywia je wiedza-art.js; bez skryptu sterowanie się nie pokazuje)
     .widget            ramka widgetu z lede, wynikiem i sterowaniem.
     .widget-lede       zdanie nad widgetem, czytelne także bez JavaScriptu.
     .widget-sterowanie przyciski i suwaki; widoczne dopiero przy .widget[data-zywy].
     .wynik             wynik pomiaru albo stan, krojem mono.
     .suwak             etykieta z suwakiem tempa.
     .tap-pad           duże pole do stukania palcem, min 9 rem wysokości.
     .tuner-tones       sześć przycisków strun E A D G B e w rzędzie.
     .progress-dots     kropki miary pod metronomem.

   Sprawdź się (mały test na koniec artykułu)
     .sprawdz           ramka testu; to też .widget, więc sterowanie chowa się bez JS.
     .pytanie           jedno pytanie w ramce jak .callout, z legendą i odpowiedziami.
     .pytanie label     odpowiedź jako duży, stukalny wiersz (min 44 px na telefonie).
     .dobrze / .zle     odpowiedź trafiona (primary) i nietrafiona (accent).
     .wyjasnienie       zdanie „czemu tak", krojem mono jak .wynik; domyślnie hidden.
     .odpowiedz         <details> z odpowiedzią dla strony bez JavaScriptu.

   Druk
     @media print       chowa sterowanie widgetów, przełącznik makiety i pasek dolny. */

/* ---------------------------------------------------------------------------
   FIGURY
--------------------------------------------------------------------------- */
.fig {
  margin: 1.2rem 0 0; width: 100%; max-width: 32rem; min-width: 0;
  border: 1px solid var(--border); border-radius: 1rem;
  background: var(--card); padding: .9rem 1rem; text-align: center;
  overflow-x: auto;
}
.fig-szeroka { max-width: 42rem }
/* Rysunek ma stałe px z gen.mjs, a na telefonie schodzi do szerokości ramki. */
.fig svg { max-width: 100%; height: auto }
.fig figcaption {
  margin: .65rem 0 0; text-align: left;
  font-family: var(--font-mono); font-size: .72rem; line-height: 1.55;
  color: var(--muted-foreground);
}
/* Rząd chwytów bywa szerszy niż telefon: niech się zawija, nie przewija. */
.fig .zywy-rzad { gap: .5rem }

/* ---------------------------------------------------------------------------
   ANIMACJE
   Reguła z STYL.md §5: pętla 2 do 6 sekund, jeden ruch na ekran, czas taktu
   ustawia autor zmienną --tempo na kontenerze (np. style="--tempo:2s").
--------------------------------------------------------------------------- */
@keyframes wiedza-zapal {
  0%, 46% { opacity: 1; transform: scale(1) }
  54%, 100% { opacity: .35; transform: scale(.955) }
}
.anim-zmiana .grip { animation: wiedza-zapal var(--tempo, 3s) infinite ease-in-out }
.anim-zmiana .grip:nth-of-type(2) { animation-delay: calc(var(--tempo, 3s) / -2) }

/* Pole paska świeci krótko i gaśnie; opóźnienie liczy się z liczby slotów,
   którą gen.mjs wpisuje w --slotow na .lane. */
@keyframes wiedza-slot {
  0%, 12% { background: var(--primary); color: var(--primary-foreground) }
  32%, 100% {
    background: var(--secondary);
    color: color-mix(in srgb, var(--muted-foreground) 60%, transparent);
  }
}
.anim-bicie .lane b { animation: wiedza-slot var(--tempo, 2s) infinite linear }
.anim-bicie .lane b:nth-child(1) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 0) }
.anim-bicie .lane b:nth-child(2) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 1) }
.anim-bicie .lane b:nth-child(3) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 2) }
.anim-bicie .lane b:nth-child(4) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 3) }
.anim-bicie .lane b:nth-child(5) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 4) }
.anim-bicie .lane b:nth-child(6) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 5) }
.anim-bicie .lane b:nth-child(7) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 6) }
.anim-bicie .lane b:nth-child(8) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 7) }
.anim-bicie .lane b:nth-child(9) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 8) }
.anim-bicie .lane b:nth-child(10) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 9) }
.anim-bicie .lane b:nth-child(11) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 10) }
.anim-bicie .lane b:nth-child(12) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 11) }
.anim-bicie .lane b:nth-child(13) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 12) }
.anim-bicie .lane b:nth-child(14) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 13) }
.anim-bicie .lane b:nth-child(15) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 14) }
.anim-bicie .lane b:nth-child(16) { animation-delay: calc(var(--tempo, 2s) / var(--slotow, 8) * 15) }

@keyframes wiedza-wahadlo { from { transform: rotate(-20deg) } to { transform: rotate(20deg) } }
/* transform-origin liczony w układzie viewBox: oś wahadła stoi na (60, 140)
   w SVG 120 na 170, czyli 50% i 82,4%. gen.mjs wpisuje to samo inline,
   żeby SVG kołysał się nawet wzięty bez tego pliku. */
.wahadlo { transform-box: view-box; transform-origin: 50% 82.4% }
.anim-wahadlo .wahadlo {
  animation: wiedza-wahadlo calc(var(--tempo, 2s) / 2) infinite alternate ease-in-out;
}

@keyframes wiedza-puls {
  0%, 100% { transform: scale(1); opacity: .55 }
  10% { transform: scale(1.55); opacity: 1 }
  40% { transform: scale(1); opacity: .55 }
}
.anim-puls .progress-dots b[data-on], .anim-puls .puls {
  animation: wiedza-puls var(--tempo, 2s) infinite ease-out;
}
.puls { display: inline-block; width: .7rem; height: .7rem; border-radius: 999px; background: var(--primary) }

@keyframes wiedza-strzalka {
  0%, 100% { transform: translateY(0); opacity: .55 }
  10% { transform: translateY(5px); opacity: 1 }
  38% { transform: translateY(0); opacity: .55 }
}
@keyframes wiedza-strzalka-gora {
  0%, 100% { transform: translateY(0); opacity: .55 }
  10% { transform: translateY(-5px); opacity: 1 }
  38% { transform: translateY(0); opacity: .55 }
}
.anim-strzalka .strzalka {
  display: inline-block; animation: wiedza-strzalka var(--tempo, 2s) infinite ease-out;
}
.anim-strzalka .strzalka-gora {
  animation-name: wiedza-strzalka-gora;
  animation-delay: calc(var(--tempo, 2s) / 2);
}

/* Ustawienie „ogranicz ruch" w systemie wyłącza KAŻDĄ z powyższych. */
@media (prefers-reduced-motion: reduce) {
  .anim-zmiana .grip,
  .anim-bicie .lane b,
  .anim-wahadlo .wahadlo,
  .anim-puls .progress-dots b[data-on],
  .anim-puls .puls,
  .anim-strzalka .strzalka { animation: none !important }
}

/* ---------------------------------------------------------------------------
   BLOKI TREŚCI
--------------------------------------------------------------------------- */
.doczytaj {
  margin: 1.8rem 0 0; max-width: 42rem;
  border-top: 1px solid var(--border); padding-top: .9rem;
}
.doczytaj h3 {
  font-family: var(--font-display); font-size: 1.05rem; font-weight: 500;
  font-variation-settings: "opsz" 40; margin: 0;
}
.doczytaj ul { list-style: none; margin: .7rem 0 0; padding: 0; display: grid; gap: .8rem }
.doczytaj li { display: grid; gap: .12rem }
.doczytaj .tyt { font-weight: 500 }
.doczytaj .kto { font-family: var(--font-mono); font-size: .72rem; color: var(--muted-foreground) }
.doczytaj .poco { font-size: .88rem; color: var(--muted-foreground); line-height: 1.5 }
.doczytaj a { color: var(--primary) }
.doczytaj a:hover { text-decoration: underline }
.doczytaj a[href^="http"]::after { content: " ↗"; font-size: .78em; color: var(--muted-foreground) }

.jezyk {
  display: flex; justify-content: flex-end; gap: .3rem; max-width: 42rem; margin: .5rem 0 0;
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .08em; text-transform: uppercase;
}
.jezyk a { padding: .2rem .55rem; border-radius: 999px; color: var(--muted-foreground) }
.jezyk a:hover { color: var(--primary) }
.jezyk a[aria-current] { background: var(--primary); color: var(--primary-foreground) }

.tabela-danych {
  border-collapse: collapse; width: 100%; max-width: 42rem; margin: 1rem 0 0; font-size: .92rem;
}
.tabela-danych th, .tabela-danych td {
  text-align: left; padding: .45rem .6rem; border-bottom: 1px solid var(--border);
}
.tabela-danych th {
  font-family: var(--font-mono); font-size: .66rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted-foreground); font-weight: 400;
}
.tabela-danych td.mono { font-family: var(--font-mono); font-size: .85rem; color: var(--chord-ink) }
.tabela-danych tbody tr:nth-child(even) {
  background: color-mix(in srgb, var(--secondary) 45%, transparent);
}

/* Tabele sprzętowe mają po cztery kolumny i długie nazwy modeli.
   Ich szerokość minimalna wypychała cały artykuł poza ekran iPhone'a
   14 Pro Max. Na telefonie kolumny dostają jawny podział szerokości,
   a długie nazwy mogą się złamać; przewijanie figury zostaje ostatnim
   bezpiecznikiem dla przyszłej tabeli, zamiast poszerzać dokument. */
@media (max-width: 40rem) {
  .art, .kurs-tresc, .kolumna2 { min-width: 0; max-width: 100% }
  .tabela-danych { table-layout: fixed }
  .tabela-danych th, .tabela-danych td {
    padding-inline: .35rem;
    overflow-wrap: anywhere;
  }
}

.callout {
  margin: 1.1rem 0 0; max-width: 42rem; display: flex; gap: .7rem;
  border: 1px solid var(--border); border-left-width: 3px; border-radius: .8rem;
  background: var(--card); padding: .75rem .9rem;
}
.callout::before {
  content: "•"; flex: 0 0 auto; font-family: var(--font-mono); font-size: 1rem; line-height: 1.5;
  color: var(--muted-foreground);
}
.callout p { margin: 0; font-size: .95rem; line-height: 1.6 }
.callout p + p { margin-top: .5rem }
.callout-miara { border-left-color: var(--primary) }
.callout-miara::before { content: "♩"; color: var(--primary) }
.callout-uwaga { border-left-color: var(--accent) }
.callout-uwaga::before { content: "!"; color: var(--accent) }
.callout-ja { border-left-color: var(--muted-foreground) }
.callout-ja::before { content: "„"; color: var(--muted-foreground) }
.callout-ja p { color: var(--muted-foreground) }

/* ---------------------------------------------------------------------------
   WIDGETY
   Sterowanie stoi w HTML, ale pokazuje się dopiero, gdy wiedza-art.js
   powie „żyję" (data-zywy). Bez skryptu zostaje rysunek i zdanie, i nikt
   nie klika w martwy przycisk.
--------------------------------------------------------------------------- */
.widget {
  margin: 1.2rem 0 0; max-width: 42rem;
  border: 1px solid color-mix(in srgb, var(--primary) 30%, var(--border));
  border-radius: 1rem; background: var(--card); padding: .9rem 1rem 1rem;
}
.widget .widget-lede { margin: 0 0 .7rem; font-size: .92rem; color: var(--muted-foreground) }
.widget .wynik {
  display: block; margin: .7rem 0 0; min-height: 1.2rem;
  font-family: var(--font-mono); font-size: .8rem; line-height: 1.5; color: var(--foreground);
}
.widget .wynik b { color: var(--primary); font-weight: 400 }
/* Dwie klasy, bo .tuner-tones też ustawia display: sterowanie chowamy
   regułą MOCNIEJSZĄ (dwie klasy), żeby nie zależeć od kolejności w pliku. */
.widget .widget-sterowanie { display: none; flex-wrap: wrap; align-items: center; gap: .6rem; margin-top: .8rem }
.widget[data-zywy] .widget-sterowanie { display: flex }
.widget .suwak {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--font-mono); font-size: .7rem; color: var(--muted-foreground);
}
.widget input[type="range"] { accent-color: var(--primary); width: 9rem; max-width: 42vw }
.widget .zywy-rzad { margin-bottom: .2rem }

/* Siatka, nie blok: pole bywa <button> albo <div role="button">, a napis
   ma stać na środku w obu przypadkach. */
.tap-pad {
  display: grid; place-items: center; width: 100%; min-height: 9rem; margin: 0;
  border-radius: .9rem; border: 1px dashed color-mix(in srgb, var(--primary) 55%, var(--border));
  background: var(--secondary); color: var(--muted-foreground);
  font-family: var(--font-mono); font-size: .8rem; letter-spacing: .04em;
  cursor: pointer; touch-action: manipulation; -webkit-user-select: none; user-select: none;
  transition: background .08s, color .08s;
}
.tap-pad[data-bij] {
  background: var(--primary); color: var(--primary-foreground); border-color: var(--primary);
}

/* Sześć strun ma stać w JEDNYM rzędzie także na telefonie 390 px, więc
   siatka na sześć kolumn, nie zawijany flex. Reguła z .widget[data-zywy]
   jest powtórzona, bo tamta ustawia flex i ma tę samą siłę. */
.tuner-tones { display: grid; grid-template-columns: repeat(6, 1fr); gap: .4rem }
.widget[data-zywy] .tuner-tones { display: grid }
.tuner-tones button {
  min-width: 0; min-height: 3rem; padding: .3rem .1rem;
  border-radius: .7rem; border: 1px solid var(--border);
  background: var(--secondary); color: var(--foreground);
  font-family: var(--font-mono); font-size: 1rem; cursor: pointer;
  display: grid; place-items: center; line-height: 1.1;
}
.tuner-tones button span { font-size: .58rem; color: var(--muted-foreground) }
.tuner-tones button[data-on] {
  background: var(--primary); color: var(--primary-foreground); border-color: var(--primary);
}
.tuner-tones button[data-on] span { color: var(--primary-foreground) }

.progress-dots { display: inline-flex; gap: .45rem; align-items: center }
.progress-dots b {
  display: block; width: .55rem; height: .55rem; border-radius: 999px; background: var(--border);
}
.progress-dots b:first-child { width: .75rem; height: .75rem }
.progress-dots b[data-on] { background: var(--primary) }

/* ---------------------------------------------------------------------------
   SPRAWDŹ SIĘ
   Blok jest .widget, więc ramkę, .wynik i chowanie sterowania ma z góry.
   Tu dochodzi tylko to, czego widget nie ma: pytanie i odpowiedzi.
--------------------------------------------------------------------------- */
.sprawdz .blok-head { margin-bottom: .2rem }
.sprawdz .blok-head h2 { margin: 0 }

/* Pytanie wygląda jak .callout, ale jest <fieldset>, więc trzeba zdjąć
   domyślną ramkę przeglądarki i wyprowadzić <legend> z obrysu. */
.pytanie {
  margin: 1rem 0 0; padding: .75rem .9rem; min-inline-size: 0;
  border: 1px solid var(--border); border-left: 3px solid var(--primary);
  border-radius: .8rem; background: color-mix(in srgb, var(--secondary) 55%, transparent);
}
.pytanie legend {
  padding: 0; margin-bottom: .45rem; float: left; width: 100%;
  font-size: .98rem; line-height: 1.45; font-weight: 500;
}
.pytanie legend + label { clear: both }

/* Odpowiedź to duży wiersz do stuknięcia palcem: 44 px to najmniejszy cel,
   jaki da się trafić kciukiem na telefonie. */
.pytanie label {
  display: flex; align-items: center; gap: .6rem;
  min-height: 2.75rem; padding: .45rem .6rem; margin-top: .3rem;
  border: 1px solid transparent; border-radius: .6rem;
  font-size: .95rem; line-height: 1.4; cursor: pointer;
  transition: background .12s, border-color .12s;
}
.pytanie label:hover { background: color-mix(in srgb, var(--foreground) 6%, transparent) }
.pytanie input[type="radio"] {
  flex: 0 0 auto; width: 1.1rem; height: 1.1rem; margin: 0; accent-color: var(--primary);
}
.pytanie label.dobrze {
  border-color: var(--primary); background: color-mix(in srgb, var(--primary) 14%, transparent);
}
.pytanie label.zle {
  border-color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent);
}
/* Słowo werdyktu przychodzi z data-txt-good i data-txt-bad, więc siedzi
   w HTML artykułu, a nie w skrypcie ani w tym pliku. */
.pytanie label[data-znak]::after {
  content: attr(data-znak); margin-left: auto; flex: 0 0 auto;
  font-family: var(--font-mono); font-size: .66rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted-foreground);
}
.pytanie label.dobrze[data-znak]::after { color: var(--primary) }
.pytanie label.zle[data-znak]::after { color: var(--accent) }

.wyjasnienie {
  margin: .5rem 0 0; font-family: var(--font-mono); font-size: .74rem; line-height: 1.55;
  color: var(--muted-foreground);
}

/* Odpowiedź dla strony bez JavaScriptu; styl jak w „Doczytaj". */
.odpowiedz { margin-top: .5rem }
.odpowiedz summary {
  cursor: pointer; font-family: var(--font-mono); font-size: .72rem; color: var(--primary);
}
.odpowiedz > p { margin: .4rem 0 0; font-size: .88rem; line-height: 1.5; color: var(--muted-foreground) }

@media (prefers-reduced-motion: reduce) {
  .pytanie label { transition: none !important }
}

/* ---------------------------------------------------------------------------
   DRUK: na kartce zostaje wiedza, znika wszystko, w co się klika.
--------------------------------------------------------------------------- */
@media print {
  .widget button, .widget input, .widget-sterowanie,
  .persona, .persona-linki, .tabbar { display: none !important }
  .fig, .widget, .callout, .doczytaj li, .pytanie { break-inside: avoid }
  /* Test na kartce ma sens tylko z odpowiedziami, więc <details> idzie
     w całości na wierzch, także wtedy, gdy skrypt go schował. */
  .odpowiedz[hidden] { display: block !important }
  .odpowiedz > summary { display: none }
  .odpowiedz > p { display: block !important }
  .widget { border-color: var(--border) }
}

/* Linki w prozie: piosenki.css zdejmuje kolor i podkreślenie z każdego <a>
   (pasek, karty), więc link w akapicie był niewidoczny. Tu wraca kolor
   marki i cienkie podkreślenie; bloki „Zrób to teraz” i karty utworów mają
   własne style i tej reguły nie dostają. */
.kolumna2 a, .niedowiarek a, .zrob .why a, .art2 figcaption a, .art2 .tabela-danych a {
  color: var(--primary); text-decoration: underline; text-decoration-thickness: 1px;
  text-underline-offset: .18em; text-decoration-color: color-mix(in srgb, var(--primary) 55%, transparent) }
.kolumna2 a:hover, .niedowiarek a:hover { text-decoration-color: var(--primary) }

/* Nagłówki artykułu jak nagłówek hero landingu (landing.css `.landing h1.hero-h1`,
   unifikacja z /login na prośbę Adriana 2026-08-30/31): Fraunces w wadze 400,
   BEZ przykręconych osi (`font-variation-settings: normal`, więc `opsz` dobiera
   się do rozmiaru), letter-spacing -0.02em, interlinia 1.15. Makieta dziedziczyła
   domyślne `bold` przeglądarki i rysunek szyldowy, co Adrian na telefonie
   nazwał „źle się czyta” (2026-09-03). */
.art h1, .kurs-pas h1 {
  font-weight: 400; font-variation-settings: normal; letter-spacing: -0.02em;
  line-height: 1.15; font-size: clamp(1.5rem, 3vw, 2.2rem); text-wrap: balance }
.art h2, .art2 .nauczysz h2, .spis-tyt, .nast-tyt, .lekcja-tyt {
  font-weight: 500; font-variation-settings: normal; letter-spacing: -0.01em }

/* ---------- DOKŁADKI STRONY SERWEROWEJ (public-assets.mjs) ---------- */
.podglad-pasek { position: sticky; top: 0; z-index: 30; background: var(--accent);
  color: var(--accent-foreground); font-family: var(--font-mono); font-size: .72rem;
  letter-spacing: .06em; text-align: center; padding: .35rem .8rem }
.secnav a { text-decoration: none }
.topbar .start .ikona { text-decoration: none }
.crumb a, .typ a, .lekcja-tyt, .nastepna, .song, .jezyk { text-decoration: none }

/* ---------- POWŁOKA JAK W APPCE (zgłoszenie Adriana 2026-09-02) ----------

   Makieta rysowała pasek „na oko": własny znak marki, podkreślony
   monospace zamiast przycisków i sierota z przełącznikiem języka nad
   kolumną tekstu. Poniżej te miejsca dostają wygląd z powłoki React
   (Common/BrandMark.tsx, ui/button.tsx wariant ghost, routes/_app.tsx).

   Kroje i kolory NIE są tu przepisywane — jadą tokenami, które
   wiedza-public.css bierze prosto z index.css. */

/* DWIE BRAKUJĄCE PALETY: „dark” i „light” z lib/theme.ts.

   Warsztat zna tylko dwa motywy marki (Ognisko i Ognisko za dnia) i to jest
   w porządku — makiety rysuje się w motywie marki. Appka ma ich CZTERY,
   a strona artykułu jest tą samą appką z innej strony: do 2026-09-02
   proteza w base.html spłaszczała wybór do dwóch, więc kto wybrał „dark”,
   dostawał na artykule brąz Ogniska (#12100d) zamiast grafitu (#0f1115),
   a kto „light” — krem zamiast bieli.

   Wartości są PRZEPISANE z frontend/src/index.css (bloki .dark i :root),
   tak samo jak warsztat przepisał u siebie .ognisko. Zmieniasz tam,
   zmieniasz tu — hex, który się rozjedzie, widać na styku appki i artykułu
   jako „inne tło paska".

   Klucz jest inny niż wyżej: data-motyw mówi JASNY CZY CIEMNY (na tym
   stoją cienie i odznaki warsztatu, więc „light” dziedziczy je po Ognisku
   za dnia), a data-paleta mówi, KTÓRY to motyw — i to on podmienia same
   kolory. Bloki muszą stać PO warsztacie, żeby wygrać z jego :root. */
body[data-paleta="dark"] {
  /* index.css .dark */
  --background: #0f1115;
  --bg-glow: #1a1e27;
  --foreground: #e8eaf0;
  --card: #171a21;
  --primary: #f0a838;
  --primary-foreground: #1b1204;
  --secondary: #1e222b;
  --muted-foreground: #9aa3b2;
  --accent: #7fa8c9;
  --border: #2a2f3a;
  --sidebar: #13161c;
  --chord-ink: #f0a838;
  --glass-tint: #13161c;
  --glass-edge: #e8eaf0;
  --glow-mix: 20%;
}
body[data-paleta="light"] {
  /* index.css :root */
  --background: #f4f6fb;
  --bg-glow: #ffffff;
  --foreground: #1f2a44;
  --card: #ffffff;
  --primary: #b45309;
  --primary-foreground: #ffffff;
  --secondary: #eef2f7;
  --muted-foreground: #5f6b7d;
  --accent: #2b6cb0;
  --border: #dfe5ee;
  --sidebar: #ffffff;
  --chord-ink: #8f520b;
  /* literalnie, nie var(--sidebar): motyw siedzi na body, a var() liczy
     sie TAM, GDZIE ZADEKLAROWANA (ten sam powod, co w piosenki.css) */
  --glass-tint: #ffffff;
  --glass-edge: #1a1e27;
  --glow-mix: 9%;
}

/* ZNAK MARKI (Common/BrandMark.tsx). Plektron ma dwa własne tokeny, bo
   na kremie wnętrze jest PRZEZROCZYSTE, a zarys palony, żeby znak nie
   czytał się jak kleks (index.css, blok o kontraście znaku). */
:root { --gm-mark-tile: #1c1813; --gm-mark-line: #f0a838 }
body[data-motyw="ognisko-jasne"] { --gm-mark-tile: transparent; --gm-mark-line: #a8620f }
.gm-brand { display: inline-flex; align-items: center; gap: .55rem }
.gm-wordmark { font-family: var(--font-display); font-weight: 600;
  font-optical-sizing: auto; font-variation-settings: "opsz" 40, "SOFT" 40;
  letter-spacing: -.005em; white-space: nowrap; font-size: 15px }
.gm-wordmark b { font-weight: inherit; color: var(--primary) }
.topbar .brand svg { width: 22px; height: 22px }
@media (min-width: 64rem) {
  .gm-wordmark { font-size: 1rem }
  .topbar .brand svg { width: 24px; height: 24px }
}
@media (max-width: 375px) { .gm-wordmark { display: none } }

/* PRZYCISKI PRAWEJ STRONY (ui/button.tsx: ghost i default). „Zaloguj się"
   w appce jest cichym przyciskiem krojem powłoki, nie podkreślonym
   monospace — „btn-quiet” zostaje w arkuszu dla makiet, ale pasek go już
   nie używa. */
.btn-ghost { color: var(--foreground); font-weight: 500 }
.btn-ghost:hover { background: var(--secondary) }
.topbar .end { gap: .25rem }

/* PRZEŁĄCZNIK WERSJI JĘZYKOWEJ — DWA MIEJSCA, ZAWSZE JEDNO WIDOCZNE.

   Od 48 rem stoi w pasku, w rogu, w którym appka trzyma język
   (routes/_app.tsx, „settings”). Krojem powłoki, nie monospace: w pasku
   appki nie ma ani jednego napisu monospace.

   Węziej w pasku nie ma dla niego miejsca obok wyśrodkowanego logo —
   i tak samo robi appka, która na telefonie zostawia w pasku samą ikonę
   konta, a język i motyw spycha do szuflady. Strona z serwera szuflady
   nie ma, więc przełącznik schodzi na KONIEC TREŚCI (_stopka.html),
   a nie w skrót „EN” obok ikony konta: skrótu w pasku appki nie ma nigdzie,
   a wciśnięty na siłę trzeci element rozjeżdżał wyśrodkowane logo (to samo
   zmierzenie, przez które w appce wyleciały stamtąd język i motyw).

   Do 2026-09-02 na telefonie nie było ŻADNEGO: merge powłoki zdjął link
   z ciała artykułu i kursu, a w pasku zapalał go dopiero 48 rem. */
.jezyk-link { display: none; font-size: .82rem; color: var(--muted-foreground);
  padding: .35rem .6rem; border-radius: 999px; white-space: nowrap }
.jezyk-link:hover { color: var(--foreground); background: var(--secondary) }
@media (min-width: 48rem) { .jezyk-link { display: inline-flex; align-items: center } }
.jezyk-stopka { justify-self: start; margin-bottom: .35rem; font-size: .82rem;
  color: var(--muted-foreground); padding: .35rem .6rem; border-radius: 999px;
  border: 1px solid var(--border); text-decoration: none }
.jezyk-stopka:hover { color: var(--foreground); background: var(--secondary) }
@media (min-width: 48rem) { .jezyk-stopka { display: none } }

/* WYJŚCIE W LEWYM SLOCIE TELEFONU. Makieta dawała mu ramkę i tło karty
   (.ikona), a w pasku appki lewy slot to ikona BEZ pudełka (≡ szuflady,
   ui/button.tsx wariant ghost). Jedno pudełko po lewej przy gołej ikonie
   po prawej robiło pasek niesymetryczny. */
.topbar .start .ikona { border: 0; background: none }
.topbar .start .ikona:hover { background: var(--secondary) }

/* KONTO (proteza stanu w base.html): sama ikona, jak „AccountMenu”
   z „compact” na telefonie i w wąskiej belce. */
.ikona-konto { display: inline-grid; place-items: center; width: 2rem; height: 2rem;
  border-radius: .5rem; color: var(--foreground) }
.ikona-konto:hover { background: var(--secondary) }

/* ---------- KOLOR SEKCJI NA STRONIE SERWEROWEJ (runda 3 „przyjazny",
   prototypy/przyjazny-design/SYSTEM_KOLOROW.md, OBSZAR_WIEDZA.md) ----------

   Strona kursu i strona lekcji miały JEDEN bursztyn na wszystko: nadtytuł
   „KURS", ikony chipów, kwadrat ikony, numer kroku, pasek postępu, strzałki
   „›", link „ćwicz" I przycisk „Zacznij kurs". Adrian 2026-09-02: „w Wiedzy
   mało kolorów, wszystko bardzo kremowe, jednokolorowe".

   Role z kontraktu §2, w tej samej kolejności co w appce:
     tożsamość sekcji  nadtytuł, ikona, numer kroku, pasek postępu → --section
     wezwanie          .btn-primary i NIC więcej                   → --primary
     link              okruszek, „ćwicz →", strzałka „dalej"       → --info
   Wiedza jest w rejestrze sekcją theory, więc jej kolorem jest BŁĘKIT;
   wartości przepisane co do hexa z src/system-kolorow.css.

   Bloku nie da się napisać w warsztacie: makiety prototypy/wiedza/*.html
   nie znają tokenów sekcji, a arkusz appki (system-kolorow.css) nie jedzie
   na strony serwerowe. Stąd tutaj, w dokładkach — razem z powłoką. */
body { --section: #7fb2e0; --section-wash: #2b2c2c; --info: #7fb2e0 }
body[data-motyw="ognisko-jasne"] { --section: #2b6cb0; --section-wash: #e5e6e2; --info: #2b6cb0 }

/* tożsamość sekcji */
.typ { color: var(--section) }
.chip svg { color: var(--muted-foreground) }
.ikw { color: var(--section);
  background: color-mix(in srgb, var(--section) 14%, var(--card));
  border-color: color-mix(in srgb, var(--section) 22%, transparent) }
.pasek > span { background: var(--section) }
.nauczysz .ch { color: var(--section) }
.lekcja[data-teraz] .nr,
body[data-konto="uczen"] .lekcja[data-teraz-u] .nr,
body[data-konto="uczen"] .krok[data-teraz-u] .nr {
  background: var(--section); color: #fff; border-color: var(--section) }
.lekcja[data-zrobiony] .nr,
body[data-konto="uczen"] .lekcja[data-zrobiony-u] .nr,
body[data-konto="uczen"] .krok[data-zrobiony-u] .nr {
  border-color: var(--section); color: var(--section) }
.krok-meta .teraz { color: var(--section) }
.crumb b { color: var(--section) }
/* AKTYWNA ZAKŁADKA na kolorze sekcji, tak jak w powłoce appki: klik
   w „Wiedza" na dole ekranu przenosi ze strony serwerowej do SPA i obie
   połowy mają świecić tym samym błękitem. */
.tabbar a[aria-current], .secnav a[aria-current] { color: var(--section) }

/* link i informacja */
.crumb a, .krok-meta .cwicz, .wiersz .cwicz, .nastepna .strzalka,
.doczytaj a, .kolumna2 a, .niedowiarek a, .autor .kto a, .dzial li a:hover,
.lekcja-tyt:hover, .wroc:hover, .jezyk a:hover { color: var(--info) }
.kolumna2 a, .niedowiarek a { text-decoration-color: color-mix(in srgb, var(--info) 55%, transparent) }
.kolumna2 a:hover, .niedowiarek a:hover { text-decoration-color: var(--info) }
.nastepna:hover, .kafel:hover, .btn-line:hover, .kurs:hover .strzalka-kolo,
.lekcja[data-teraz], body[data-konto="uczen"] .krok[data-teraz-u] {
  border-color: color-mix(in srgb, var(--section) 60%, transparent) }
.btn-line:hover { color: var(--section) }

/* WEZWANIE ZOSTAJE BURSZTYNOWE. .btn-primary i pigułka wybranego języka
   to jedyne dwa miejsca, w których --primary ma prawo być plamą. */

