/* Komponenty. Wartosci wylacznie z tokens.css. */

/* --- Przyciski --- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border: 1px solid transparent;
  border-radius: var(--radius);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.2s, border-color 0.2s, color 0.2s;
}
.btn--primary { background: var(--c-accent); color: var(--c-accent-ink); }
.btn--primary:hover { background: var(--c-accent-hi); color: var(--c-accent-ink); }
.btn--ghost { border-color: var(--c-border); color: var(--c-text); }
.btn--ghost:hover { border-color: var(--c-accent); color: var(--c-accent); }

/* --- Formularz schowany pod przyciskiem --- */
/* Natywny <details>, nie przelacznik na JS: formularz kontaktowy musi dzialac
   takze bez skryptow. Element daje rozwijanie, obsluge klawiatury i ogloszenie
   stanu czytnikowi ekranu za darmo. */
.reveal > summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background: var(--c-accent);
  color: var(--c-accent-ink);
  border-radius: var(--radius);
  font-weight: 600;
  cursor: pointer;
  list-style: none; /* Firefox */
}
.reveal > summary::-webkit-details-marker { display: none; }
.reveal > summary::after {
  content: '';
  width: 0.5rem;
  height: 0.5rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 0.2s;
}
.reveal[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.reveal > summary:hover { background: var(--c-accent-hi); }

/* TA REGULA JEST OBOWIAZKOWA. Przegladarka ukrywa tresc zwinietego <details>
   regula ze swojego arkusza, a KAZDA regula autora ja bije - niezaleznie od
   specyficznosci. '.form { display: grid }' sprawialo, ze formularz byl w pelni
   widoczny mimo details.open === false: przycisk niby chowal, a nie chowal nic.
   To trzeci raz w tym projekcie: tak samo bylo z [hidden] na menu (Zadanie 6)
   i z dialog:not([open]) w lightboxie (Zadanie 9). Wzorzec jest zawsze ten sam -
   jesli autor ustawia 'display' na elemencie, ktory UA ukrywa stanem, musi
   dopisac tez regule na stan zamkniety. */
.reveal:not([open]) > .form { display: none; }
.reveal[open] > summary { margin-bottom: var(--space-4); }

/* --- Powrot na gore --- */
/* Zwykla kotwica w rogu ekranu. Bez JS, bez pojawiania sie po przewinieciu -
   element, ktory istnieje od razu, nie zaskakuje i nie wymaga skryptu.
   Obwodka z --c-border-strong: element interaktywny, prog 3:1 (SC 1.4.11). */
.to-top {
  position: fixed;
  right: var(--space-3);
  bottom: var(--space-3);
  z-index: var(--z-nav);
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  color: var(--c-text-dim);
  background: color-mix(in srgb, var(--c-surface) 88%, transparent);
  backdrop-filter: blur(10px);
  border: 1px solid var(--c-border-strong);
  border-radius: 50%;
  transition: color 0.2s, border-color 0.2s, transform 0.2s;
}
.to-top:hover {
  color: var(--c-accent);
  border-color: var(--c-accent);
  transform: translateY(-3px);
}

/* --- Karty projektow --- */
.card-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}
.card {
  position: relative; /* kotwica dla nakladki .card__title a::after */
  display: flex;
  flex-direction: column;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: border-color 0.2s, transform 0.2s;
}
.card:hover { border-color: var(--c-accent); transform: translateY(-3px); }
.card__media { background: var(--c-bg); aspect-ratio: 16 / 10; overflow: hidden; }
.card__media img { width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.card__body { padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); flex: 1; }
.card__title { font-size: var(--step-1); }
.card__title a { color: var(--c-text); text-decoration: none; }
.card__title a::after { content: ''; position: absolute; inset: 0; } /* cala karta klikalna */
/* Nakladka wyzej przykrywa CALA karte, wiec kazdy inny odnosnik czy przycisk
   w srodku bylby nieklikalny - bez bledu, po prostu martwy. Ten guard wynosi
   je nad nakladke. Dzis w .meta sa same <span>, ale pierwszy link tam wstawiony
   przestalby dzialac i nikt by nie wiedzial dlaczego. */
.card :is(a, button):not(.card__title a) { position: relative; z-index: 1; }
.card__desc { color: var(--c-text-dim); font-size: var(--step--1); }

/* Metadane - glos 'IT' */
.meta {
  font-family: var(--f-mono);
  font-size: var(--step--1);
  color: var(--c-text-dim);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-3);
}
/* Jedyny odnosnik wychodzacy na stronie glownej: dziala tu sklep, ktory
   czytelnik moze otworzyc i sprawdzic sam. Wczesniej byl to <span> - wygladal
   jak odnosnik i nie byl nim, czyli najgorszy mozliwy wariant. */
.meta__live { color: var(--c-accent); text-decoration: underline; text-underline-offset: 0.2em; }
.meta__live:hover { color: var(--c-accent-hi); }

/* --- Ramka zrzutu (§5 specu: bez skeuomorficznych laptopow) --- */
.shot {
  border: 1px solid var(--c-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--c-surface);
  box-shadow: 0 18px 40px -18px rgb(0 0 0 / 0.8);
}
.shot__chrome {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--c-border);
}
.shot__dot { width: 0.55rem; height: 0.55rem; border-radius: 50%; background: var(--c-border); }
.shot__url {
  margin-left: var(--space-2);
  font-family: var(--f-mono);
  font-size: 0.72rem;
  color: var(--c-text-dim);
}
.shot img { width: 100%; }
/* Zrzuty mobilne sa waskie i bardzo wysokie - nie rozciagaj ich na cala szerokosc */
.shot--mobile { max-width: 22rem; margin-inline: auto; }
/* Tablet PIONOWO (768x1024, proporcja 3:4): szerszy od telefonu, ale wciaz
   wysoki. Bez limitu w kolumnie .gallery--wide (~33rem) uroslby do ~44rem
   wysokosci i jeden zrzut zajmowalby ekran. */
.shot--tablet { max-width: 26rem; margin-inline: auto; }

/* --- Galeria --- */
.gallery {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  align-items: start;
}
/* Zrzuty desktopowe sa szerokie i gestе tekstem - w kolumnie 16rem robia sie
   nieczytelne. Szersza siatka daje dwie kolumny zamiast trzech.
   Galerie zrzutow mobilnych zostaja przy .gallery. */
.gallery--wide {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr));
}
.gallery figure { margin: 0; }
.gallery figcaption {
  margin-top: var(--space-2);
  font-size: var(--step--1);
  color: var(--c-text-dim);
}
.gallery [data-full] { cursor: zoom-in; background: none; border: 0; padding: 0; width: 100%; }

/* --- Lightbox --- */
.lightbox {
  position: fixed;
  inset: 0;
  /* Te resety sa OBOWIAZKOWE. <dialog> ma w arkuszu przegladarki
     width/height: fit-content, margin: auto oraz max-width/max-height
     ograniczone do ~100% minus padding. Bez nich 'inset: 0' przegrywa
     z 'width: fit-content': okno dostaje szerokosc tresci i przykleja sie
     do lewej krawedzi, a overlay przestaje zaslaniac strone. */
  width: auto;
  height: auto;
  max-width: none;
  max-height: none;
  margin: 0;

  z-index: var(--z-lightbox);
  padding: var(--space-4);
  background: color-mix(in srgb, var(--c-bg) 94%, black);
  border: 0;
}

/* 'display' TYLKO na [open]. Przegladarka ukrywa zamkniety dialog regula
   dialog:not([open]) { display: none } - ale ta regula siedzi w arkuszu UA,
   a KAZDA regula autora bije arkusz UA, niezaleznie od specyficznosci.
   Gdyby 'display: grid' stalo na samym .lightbox, zamkniety dialog nadal
   by sie renderowal i - przy inset: 0 - przykrywal cala strone, przechwytujac
   klikniecia w cokolwiek pod spodem. */
.lightbox[open] {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: var(--space-3);
}

.lightbox::backdrop { background: rgb(0 0 0 / 0.7); }
.lightbox img { max-width: 100%; max-height: 82vh; object-fit: contain; border-radius: var(--radius); }
.lightbox__cap { color: var(--c-text-dim); font-size: var(--step--1); text-align: center; }
.lightbox__close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  /* Tlo jest konieczne: przycisk laduje na zrzucie, a te sa jasne.
     Sam .btn--ghost (przezroczysty, obwodka w kolorze obramowania)
     znika na bialym tle aplikacji. */
  background: var(--c-surface);
}
/* --- Stack --- */
/* Technologie w dwoch grupach: w przegladarce / na serwerze.
   Podzial nie jest ozdobny - pokazuje obie warstwy, a przy okazji rozwiazuje
   sierote, ktora przy jednej dlugiej liscie zostawala sama w drugim wierszu
   (9 + 1 przy 1280 px, 8 + 2 przy 900 px). Podzial jest tez zgodny z prawda:
   klucz do Gemini nigdy nie trafia do przegladarki, co case study Jadlospisu
   tlumaczy osobno. */
.stack { display: flex; flex-wrap: wrap; gap: var(--space-2); list-style: none; }
.stack__label {
  font-family: var(--f-mono);
  font-size: var(--step--1);
  font-weight: 400;
  color: var(--c-text-dim);
  margin-bottom: var(--space-2);
}
.stack__item {
  font-family: var(--f-mono);
  font-size: var(--step--1);
  color: var(--c-text);
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  padding: var(--space-1) var(--space-2);
}

/* --- Decyzja techniczna: sekcja nosna portfolio (§6 specu) --- */
.decision {
  border-left: 2px solid var(--c-accent);
  padding-left: var(--space-4);
  margin-block: var(--space-4);
}
.decision__q {
  font-family: var(--f-head);
  font-size: var(--step-1);
  margin-bottom: var(--space-2);
}
/* Rytm w layout.css lapie tylko BEZPOSREDNIE dzieci .section, a te akapity
   siedza glebiej - bez tego dwa akapity w jednym bloku decyzji stoja
   sklejone (zmierzone: 0 px). Dotyczylo to tez juz zatwierdzonego bloku
   o PIN-ie w case study Jadlospisu. */
.decision p + p { margin-top: var(--space-3); }

/* --- Formularz --- */
.form { display: grid; gap: var(--space-4); max-width: 36rem; }
/* Grid rozciaga KAZDE dziecko na cala szerokosc - bez tego przycisk
   "Wyslij" ma 36rem i czyta sie jak pasek, a nie jak przycisk. */
.form .btn { justify-self: start; }
.field { display: grid; gap: var(--space-2); }
.field label { font-size: var(--step--1); color: var(--c-text-dim); }
.field__opt { opacity: 0.7; }
.field input,
.field textarea {
  font: inherit;
  color: var(--c-text);
  background: var(--c-surface);
  /* Nie --c-border: granica pola to element interfejsu, prog 3:1 (SC 1.4.11) */
  border: 1px solid var(--c-border-strong);
  border-radius: var(--radius);
  padding: var(--space-2) var(--space-3);
}
.field input:focus,
.field textarea:focus { border-color: var(--c-accent); }
.field__err { color: var(--c-accent); font-size: var(--step--1); min-height: 1.2em; }
.field--invalid input,
.field--invalid textarea { border-color: var(--c-accent); }

.form__note {
  background: var(--c-surface);
  border-left: 2px solid var(--c-accent);
  padding: var(--space-3);
  border-radius: var(--radius);
  font-size: var(--step--1);
}
.form__status { min-height: 1.4em; font-size: var(--step--1); }
.form__status--ok { color: var(--c-accent); }

/* Honeypot poza ekranem, ale nie display:none - czesc botow to wykrywa */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
