@charset "UTF-8";

/* ==========================================================================
   patrykmikolajczyk.pl  ·  style.css
   Jeden plik, warstwy kaskady. Kolejność warstw ustala priorytet,
   niezależnie od specyficzności selektorów. Później = mocniejsze.
   ========================================================================== */

/* --- FONT: Geist (zmienny, self-hosted) ---------------------------------
   Geist to font zmienny: jeden plik niesie wszystkie grubości (100 do 900),
   dlatego deklarujemy zakres font-weight zamiast osobnych plików na wagę.
   Dwa podzbiory: latin oraz latin-ext (latin-ext zawiera polskie znaki).
   @font-face stoi poza warstwami kaskady, to celowe. */
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/geist-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/geist-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;
}

/* Geist Mono: krój o stałej szerokości znaków. Framer używa go do małych
   wersalikowych etykiet UI (nawigacja, WIĘCEJ/MNIEJ, etykiety pól). */
@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/geist-mono-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Geist Mono";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/geist-mono-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;
}

@layer reset, tokens, base, components, utilities;

/* ==========================================================================
   1. RESET  (w duchu resetu Josha Comeau, świadomy dostępności)
   ========================================================================== */
@layer reset {

  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  /* Zerujemy domyślne marginesy, odstępy dokładamy świadomie w base. */
  * {
    margin: 0;
  }

  html {
    -webkit-text-size-adjust: 100%;
    /* Płynne przewijanie do kotwic, ale tylko gdy użytkownik nie prosił o spokój. */
  }

  @media (prefers-reduced-motion: no-preference) {
    html {
      scroll-behavior: smooth;
    }
  }

  body {
    min-height: 100svh;
    line-height: 1.4; /* zbite wiersze jak na Framerze (tam 1.4, nagłówki 1.2) */
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
  }

  /* Media domyślnie blokowe, nie wystają poza kontener. */
  img,
  picture,
  video,
  canvas,
  svg {
    display: block;
    max-width: 100%;
    height: auto;
  }

  /* Pola formularzy dziedziczą krój pisma. */
  input,
  button,
  textarea,
  select {
    font: inherit;
    color: inherit;
  }

  /* Długie słowa łamią się zamiast rozpychać layout. */
  p,
  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    overflow-wrap: break-word;
  }

  /* Listy z rolą "list" tracą wypustki, ale zostają listami dla czytników. */
  ul[role="list"],
  ol[role="list"] {
    list-style: none;
    padding: 0;
  }

  /* Szanujemy prośbę o ograniczenie ruchu. */
  @media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
  }
}

/* ==========================================================================
   2. TOKENS  (jedno źródło prawdy: kolory, typografia, odstępy, kształty)
   Wartości ustalone (monochrom + Geist). Zmiany globalne robimy tutaj.
   ========================================================================== */
@layer tokens {
  :root {

    /* --- Kolory (monochromatyczne, jak na stronie z Framera) --- */
    --color-bg:          #ffffff;  /* tło strony, biel */
    --color-surface:     #ffffff;  /* karty, panele */
    --color-text:        #000000;  /* tekst główny, czerń */
    --color-text-muted:  #4f4f4f;  /* tekst drugorzędny, podpisy */
    --color-accent:      #000000;  /* akcent: linki, przyciski (czerń) */
    --color-accent-ink:  #4f4f4f;  /* przygaszony akcent na hover */
    --color-border:      #e7e7e7;  /* obrysy, linie */
    --color-focus:       #1d6feb;  /* pierścień focusu, wyraźny i kontrastowy */

    /* --- Typografia --- */
    --font-sans:
      "Geist", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica,
      Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
    --font-mono:
      "Geist Mono", ui-monospace, "SF Mono", "Cascadia Mono", Menlo,
      Consolas, monospace;
    --font-serif: Georgia, "Times New Roman", serif;

    /* Skala typografii płynna (clamp: min, preferowane, max).
       Skaluje się między ~320 px a ~1240 px szerokości okna. */
    --step--1: clamp(0.83rem, 0.79rem + 0.22vw, 0.94rem);
    --step-0:  clamp(1.00rem, 0.93rem + 0.34vw, 1.19rem);
    --step-1:  clamp(1.20rem, 1.09rem + 0.55vw, 1.50rem);
    --step-2:  clamp(1.44rem, 1.27rem + 0.83vw, 1.90rem);
    --step-3:  clamp(1.73rem, 1.48rem + 1.24vw, 2.40rem);
    --step-4:  clamp(2.07rem, 1.71rem + 1.80vw, 3.00rem);

    /* --- Skala odstępów --- */
    --space-3xs: 0.25rem;
    --space-2xs: 0.5rem;
    --space-xs:  0.75rem;
    --space-sm:  1rem;
    --space-md:  1.5rem;
    --space-lg:  2.5rem;
    --space-xl:  4rem;
    --space-2xl: 6rem;

    /* --- Zaokrąglenia --- */
    --radius-sm: 6px;
    --radius-md: 12px;
    --radius-lg: 20px;

    /* --- Layout --- */
    --measure: 65ch;              /* komfortowa szerokość kolumny tekstu */
    --content-width: 98%;         /* szerokość pasa treści względem okna */
    --gutter: var(--space-md);    /* wewnętrzny margines boczny pasa treści */
  }
}

/* ==========================================================================
   3. BASE  (elementy gołe: body, nagłówki, linki, focus)
   ========================================================================== */
@layer base {

  body {
    font-family: var(--font-sans);
    font-size: var(--step-0);
    color: var(--color-text);
    background-color: var(--color-bg);
    /* Sticky footer: body na całą wysokość okna (min-height 100svh z resetu),
       a main się rozciąga, więc stopka zawsze ląduje na dole, nawet przy
       małej ilości treści. */
    display: flex;
    flex-direction: column;
  }

  main {
    flex: 1 0 auto;
  }

  /* Nagłówki: ciaśniejsza interlinia, lekko ujemny tracking. */
  h1,
  h2,
  h3 {
    line-height: 1.2;
    letter-spacing: -0.02em; /* lekko ściągnięte litery, jak na Framerze */
    font-weight: 400; /* jak na Framerze: nagłówki w wadze tekstu, różni je tylko wielkość */
    text-wrap: balance; /* ładniejsze łamanie tytułów tam, gdzie wspierane */
  }

  /* Powściągliwa skala: hero i tytuły sekcji w zbliżonej wielkości. */
  h1 { font-size: var(--step-3); }
  h2 { font-size: var(--step-3); }
  h3 { font-size: var(--step-1); }

  p {
    max-width: var(--measure);
  }

  a {
    color: var(--color-accent);
    text-decoration-thickness: 0.08em;
    text-underline-offset: 0.15em;
  }

  a:hover {
    color: var(--color-accent-ink);
  }

  /* Widoczny focus na wszystkim, co interaktywne. Tylko dla nawigacji
     klawiaturą (:focus-visible), nie przy kliknięciu myszą. */
  :focus-visible {
    outline: 3px solid var(--color-focus);
    outline-offset: 2px;
    border-radius: 2px;
  }

  /* Wybrane elementy nie wyciągają outline w róg, dostają go wokół całości. */
  a:focus-visible,
  button:focus-visible,
  summary:focus-visible {
    outline-offset: 3px;
  }
}

/* ==========================================================================
   4. COMPONENTS  (klocki interfejsu)
   ========================================================================== */
@layer components {

  /* --- Kontener / siatka szerokości --- */
  .wrap {
    width: var(--content-width);
    margin-inline: auto;
    padding-inline: var(--gutter);
  }

  /* --- Skip link: pierwszy w DOM, widoczny dopiero po focusie --- */
  .skip-link {
    position: absolute;
    left: var(--space-sm);
    top: var(--space-sm);
    z-index: 100;
    padding: var(--space-2xs) var(--space-sm);
    background: var(--color-text);
    color: var(--color-bg);
    border-radius: var(--radius-sm);
    text-decoration: none;
    transform: translateY(-150%);
    transition: transform 150ms ease;
  }

  .skip-link:focus {
    transform: translateY(0);
  }

  /* --- Nagłówek strony (banner) --- */
  .site-header {
    border-bottom: 1px solid var(--color-border);
  }

  .site-header__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    padding-block: var(--space-sm);
  }

  .site-logo {
    display: inline-grid;
    gap: 0.1em;
    color: var(--color-text);
    text-decoration: none;
    line-height: 1.2;
  }

  .site-logo__name {
    font-weight: 500;
    font-size: var(--step-0);
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }

  .site-logo__role {
    font-size: var(--step--1);
    color: var(--color-text-muted);
  }

  /* --- Nawigacja --- */
  .nav__list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs) var(--space-md);
    margin: 0;
  }

  .nav__list a {
    color: var(--color-text-muted);
    text-decoration: none;
    padding-block: var(--space-3xs);
    font-family: var(--font-mono); /* monospace, jak na Framerze */
    font-size: var(--step--1);
    text-transform: uppercase;
    letter-spacing: 0.08em;
  }

  .nav__list a:hover {
    color: var(--color-text);
  }

  /* Bieżąca strona zaznaczona wizualnie i programowo (aria-current). */
  .nav__list a[aria-current="page"] {
    color: var(--color-text);
    font-weight: 500;
  }

  /* --- Hero --- */
  .hero {
    padding-block: var(--space-lg) var(--space-2xl);
  }

  .hero__title {
    max-width: none; /* jedna linia na szerokim ekranie, jak na Framerze */
  }

  /* Blok wstępny: portret z lewej, akapit z prawej (jak na Framerze).
     Na wąskim ekranie kolumny układają się jedna pod drugą. */
  .hero__intro {
    display: grid;
    gap: var(--space-lg);
    margin-top: var(--space-lg);
  }

  @media (min-width: 48rem) {
    .hero__intro {
      grid-template-columns: minmax(0, 0.55fr) minmax(0, 1.45fr);
      gap: var(--space-xl);
      align-items: center; /* tekst wyśrodkowany w pionie względem zdjęcia */
    }
  }

  /* Pole-zastępnik na zdjęcie: szare tło z podpisem "Tu będzie zdjęcie".
     Wspólne dla hero i strony "O mnie". Gdy dojdzie zdjęcie, zamieniamy <div>
     na <img> z tą samą klasą wymiarów (.hero__media / .about-photo /
     .about-wide), a klasę .media-placeholder usuwamy. */
  .media-placeholder {
    display: grid;
    place-items: center;
    background: #f0f0ef;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    color: var(--color-text-muted);
    font-size: var(--step--1);
    text-align: center;
  }

  .hero__media {
    aspect-ratio: 4 / 5;
    max-width: 360px;
  }

  .hero__lead {
    max-width: var(--measure);
    font-size: var(--step-1);
    color: var(--color-text);
  }

  /* --- Przyciski ---
     Jeden prosty styl na wszystkie: obrysowany prostokąt z lekkim
     zaokrągleniem, czarny tekst, cienka ramka. Jak na Framerze.
     Klasy --primary, --ghost, --pill zostają w HTML, ale nie zmieniają
     wyglądu, dzięki czemu wszystkie guziki są spójne. */
  .button {
    display: inline-block;
    padding: 0.55rem 1.1rem;
    border: 1px solid var(--color-border);
    border-radius: 0; /* prostokąty, bez zaokrągleń */
    background: none;
    color: var(--color-text);
    font-size: var(--step--1);
    font-weight: 500;
    text-decoration: none;
    transition: border-color 150ms ease, color 150ms ease;
  }

  .button:hover {
    border-color: var(--color-text);
    color: var(--color-text);
  }

  /* --- Sekcje treści --- */
  .section {
    padding-block: var(--space-xl);
  }

  .section__title {
    margin-bottom: var(--space-lg);
  }

  /* Wiersz nagłówka sekcji: tytuł z lewej, akcja (pigułka) z prawej. */
  .section__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-sm);
    margin-bottom: var(--space-lg);
  }

  .section__head .section__title {
    margin-bottom: 0;
  }

  /* --- Harmonijka teaserów projektów (natywne <details>) ---
     Płaskie wiersze rozdzielone cienkimi liniami, bez ramek-kart. */
  .accordion {
    container-type: inline-size; /* komponenty mogą reagować na swój kontener */
    display: grid;
    gap: 0;
    border-top: 1px solid var(--color-border);
  }

  .teaser {
    border-bottom: 1px solid var(--color-border);
  }

  .teaser > summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    padding-block: var(--space-md);
    cursor: pointer;
    list-style: none; /* chowamy domyślny trójkąt (Firefox/inne) */
  }

  /* Chowamy domyślny marker w Safari/Chrome. */
  .teaser > summary::-webkit-details-marker {
    display: none;
  }

  .teaser__title {
    margin: 0;
    font-size: var(--step-1);
    font-weight: 400;
  }

  /* Efekt hover na tytule tylko gdy teaser jest zwinięty. Po otwarciu znika. */
  .teaser:not([open]):hover .teaser__title {
    color: var(--color-text-muted);
  }

  /* Przełącznik tekstowy: WIĘCEJ gdy zwinięte, MNIEJ gdy rozwinięte.
     Etykieta jest dekoracyjna (aria-hidden), bo czytnik ekranu i tak
     ogłasza stan zwinięcia natywnie na <summary>. */
  .teaser__toggle {
    flex: 0 0 auto;
    font-family: var(--font-mono); /* monospace, jak na Framerze */
    font-size: var(--step--1);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
  }

  .teaser__toggle::after {
    content: "Więcej";
  }

  .teaser[open] .teaser__toggle::after {
    content: "Mniej";
  }

  .teaser__body {
    padding: 0 0 var(--space-md);
    display: grid;
    gap: var(--space-md);
  }

  .teaser__body p {
    color: var(--color-text);
    max-width: none; /* tekst na pełną szerokość kontenera, jak na Framerze */
  }

  /* Link "Zobacz więcej →" w rozwiniętym teaserze: czarny, bez podkreślenia,
     podkreślenie dopiero na hover. Odrobinę mniejszy niż tekst opisu. */
  .teaser__more {
    font-size: var(--step--1);
  }

  .teaser__more a {
    color: var(--color-text);
    text-decoration: none;
  }

  .teaser__more a:hover {
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }

  /* --- Tekst "O mnie" --- */
  .prose {
    display: grid;
    gap: var(--space-md);
  }

  .prose p {
    max-width: none; /* pełna szerokość, jak w sekcji "O mnie" na Framerze */
  }

  /* Strona tekstowa (dostępność, prywatność): węższa, czytelna kolumna
     zamiast pełnej szerokości, bo to dużo tekstu do przeczytania. */
  .text-page {
    max-width: 42rem;
    display: grid;
    gap: var(--space-md);
  }

  .text-page h2 {
    margin-top: var(--space-md); /* wyraźniejszy odstęp przed sekcją */
  }

  .text-page ul {
    margin: 0;
    padding-left: 1.5em;
    display: grid;
    gap: var(--space-2xs);
  }

  /* --- Strona "O mnie": zdjęcia --- */

  /* Dwa zdjęcia obok siebie, na wąskim ekranie jedno pod drugim. */
  .about-gallery {
    display: grid;
    gap: var(--space-md);
    margin-block: var(--space-lg);
  }

  @media (min-width: 48rem) {
    .about-gallery {
      grid-template-columns: 1fr 1fr;
    }
  }

  .about-photo {
    aspect-ratio: 4 / 3;
  }

  /* Szerokie zdjęcie na całą szerokość pasa treści. */
  .about-wide {
    aspect-ratio: 16 / 7;
    margin-block: var(--space-lg);
  }

  /* Gdy pola-zastępniki zamienimy na <img>, zdjęcie ma wypełnić kadr. */
  img.hero__media,
  img.about-photo,
  img.about-wide {
    width: 100%;
    object-fit: cover;
  }

  /* --- Strona "O mnie": tabela doświadczenia --- */

  /* Etykieta "Doświadczenie" z lewej, lista stanowisk z prawej. */
  .experience__grid {
    display: grid;
    gap: var(--space-md);
  }

  @media (min-width: 48rem) {
    .experience__grid {
      grid-template-columns: minmax(0, 0.25fr) minmax(0, 0.75fr);
      gap: var(--space-xl);
    }
  }

  .experience__grid .section__title {
    margin-bottom: 0;
  }

  .experience__list {
    display: grid;
    margin: 0;
  }

  /* Jeden wiersz: organizacja, rola, okres. Na wąskim ekranie jedno pod
     drugim. Wiersze rozdzielone liniami. */
  .experience__item {
    display: grid;
    gap: var(--space-3xs) var(--space-md);
    padding-block: var(--space-sm);
    border-top: 1px solid var(--color-border);
  }

  .experience__item:last-child {
    border-bottom: 1px solid var(--color-border);
  }

  .experience__role,
  .experience__date {
    color: var(--color-text-muted);
    font-size: var(--step--1);
  }

  /* Na szerokim ekranie kolumny definiuje RAZ lista, a każdy wiersz przejmuje
     je przez subgrid. Dzięki temu organizacja, rola i okres trzymają pion pod
     sobą w każdym wierszu, jak kolumny w Excelu, niezależnie od długości tekstu
     i od wyrównania. */
  @media (min-width: 48rem) {
    .experience__list {
      grid-template-columns: minmax(0, 1.3fr) minmax(0, 1.2fr) max-content;
      column-gap: var(--space-md);
    }

    .experience__item {
      grid-column: 1 / -1;
      grid-template-columns: subgrid;
      align-items: baseline;
    }

    .experience__date {
      text-align: right;
    }
  }

  /* --- Strona "Kontakt" --- */
  /* Zdanie ramowe pod nagłówkiem korzysta ze wspólnej klasy .lead. */

  /* Duży, klikalny email jako główny element strony. */
  .contact__email {
    margin-top: var(--space-xl);
    max-width: none;
  }

  .contact__email a {
    font-size: var(--step-3);
    color: var(--color-text);
    text-decoration: none;
  }

  .contact__email a:hover {
    text-decoration: underline;
    text-underline-offset: 0.1em;
  }

  /* LinkedIn i lokalizacja: mała etykieta nad wartością, obok siebie. */
  .contact__meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-lg) var(--space-2xl);
    margin: 0;
    margin-top: var(--space-xl);
  }

  .contact__meta dt {
    font-family: var(--font-mono); /* monospace, jak na Framerze */
    font-size: var(--step--1);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
  }

  .contact__meta dd {
    margin: 0;
    margin-top: var(--space-3xs);
  }

  /* Wspólne zdanie wstępu pod nagłówkiem (Projekty, Kontakt, 404). */
  .lead {
    margin-top: var(--space-md);
    max-width: var(--measure);
    font-size: var(--step-1);
    color: var(--color-text-muted);
  }

  /* Odstęp nad przyciskiem powrotu na stronie 404. */
  .error__action {
    margin-top: var(--space-lg);
  }

  /* --- Strona "Projekty": lista projektów --- */

  .project-list {
    margin-top: var(--space-xl);
    border-top: 1px solid var(--color-border);
  }

  /* Cały wiersz jest klikalny (przez ::after na linku w nazwie), ale nazwą
     linku dla czytnika zostaje sama nazwa projektu. Opis i "Zobacz" są
     wizualne. */
  .project-item {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-2xs) var(--space-md);
    padding-block: var(--space-md);
    border-bottom: 1px solid var(--color-border);
  }

  .project-item__name {
    margin: 0;
    font-size: var(--step-1);
    font-weight: 400;
  }

  .project-item__name a {
    color: var(--color-text);
    text-decoration: none;
  }

  /* Rozciąga obszar kliknięcia na cały wiersz. */
  .project-item__name a::after {
    content: "";
    position: absolute;
    inset: 0;
  }

  .project-item:hover .project-item__name a {
    color: var(--color-text-muted);
  }

  /* Opis w osobnej linii, pełną szerokością (basis 100% wymusza zawinięcie
     pod nazwę i "Zobacz"). */
  .project-item__desc {
    flex: 1 1 100%;
    order: 3;
    margin: 0;
    max-width: none;
    color: var(--color-text-muted);
  }

  .project-item__more {
    font-family: var(--font-mono);
    font-size: var(--step--1);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
  }

  /* --- Case study (podstrona pojedynczego projektu) ---
     Lewy pasek z metadanymi, szeroka kolumna główna z treścią i grafikami.
     Na wąskim ekranie jedna kolumna: najpierw metadane, potem treść. */
  .case {
    display: grid;
    gap: var(--space-xl);
  }

  @media (min-width: 62rem) {
    .case {
      grid-template-columns: minmax(0, 0.28fr) minmax(0, 0.72fr);
      gap: var(--space-2xl);
      align-items: start;
    }
  }

  /* Metadane (Projekt, Rola, Organizacja, Lata). Na szerokim ekranie
     przyklejone przy przewijaniu długiej treści. */
  .case__meta {
    display: grid;
    gap: var(--space-md);
    margin: 0;
  }

  @media (min-width: 62rem) {
    .case__meta {
      position: sticky;
      top: var(--space-lg);
    }
  }

  .case__meta dt {
    font-family: var(--font-mono);
    font-size: var(--step--1);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
  }

  .case__meta dd {
    margin: 0;
    margin-top: var(--space-3xs);
  }

  /* Kolumna główna. */
  .case__main {
    display: grid;
    gap: var(--space-lg);
  }

  /* Duży akapit wprowadzający pod tytułem. */
  .case__lead {
    max-width: var(--measure);
    font-size: var(--step-2);
  }

  .case__main h2 {
    margin-top: var(--space-lg);
  }

  .case__main p {
    max-width: var(--measure);
  }

  /* Grafiki w case study. Placeholder korzysta z .media-placeholder,
     tu ustawiamy tylko proporcje kadru. */
  .case-image {
    aspect-ratio: 16 / 9;
  }

  /* Sekcja "Linki i materiały" na dole case study. Wiersze z linkami/plikami:
     etykieta z lewej, typ (LINK/PDF) monospace z prawej. */
  .case-links {
    list-style: none;
    margin: var(--space-md) 0 0;
    padding: 0;
    border-top: 1px solid var(--color-border);
  }

  .case-links li {
    border-bottom: 1px solid var(--color-border);
  }

  .case-links a {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-2xs) var(--space-md);
    padding-block: var(--space-sm);
    color: var(--color-text);
    text-decoration: none;
  }

  .case-links a:hover .case-links__label {
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }

  .case-links__type {
    font-family: var(--font-mono);
    font-size: var(--step--1);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
  }

  /* Nawigacja na dole case study (powrót do listy projektów). */
  .case-nav {
    margin-top: var(--space-2xl);
    padding-top: var(--space-md);
    border-top: 1px solid var(--color-border);
  }

  .case-nav a {
    font-family: var(--font-mono);
    font-size: var(--step--1);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
    text-decoration: none;
  }

  .case-nav a:hover {
    color: var(--color-text);
  }

  /* --- Stopka (contentinfo) --- */
  .site-footer {
    margin-top: var(--space-2xl);
    background: var(--color-surface);
  }

  .site-footer__inner {
    padding-block: var(--space-xl);
  }

  /* Duży, klikalny email jako główny element stopki (jak na Framerze). */
  .footer__email {
    max-width: none;
  }

  .footer__email a {
    font-size: var(--step-2);
    color: var(--color-text);
    text-decoration: none;
  }

  .footer__email a:hover {
    text-decoration: underline;
    text-underline-offset: 0.15em;
  }

  .footer__cta {
    margin-top: var(--space-2xs);
    color: var(--color-text-muted);
    max-width: none;
  }

  /* Dolny wiersz: copyright z lewej, linki na środku, "do góry" z prawej,
     rozdzielony cienką linią od reszty stopki. */
  .footer__bottom {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm) var(--space-md);
    margin-top: var(--space-xl);
    padding-top: var(--space-md);
    border-top: 1px solid var(--color-border);
    font-size: var(--step--1);
    color: var(--color-text-muted);
  }

  .footer__copy {
    margin: 0;
  }

  .footer__nav-list {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0;
    margin: 0;
  }

  /* Kropka rozdzielająca linki stopki, jak na Framerze. */
  .footer__nav-list li:not(:last-child)::after {
    content: "·";
    margin-inline: var(--space-sm);
    color: var(--color-text-muted);
  }

  .footer__nav-list a,
  .footer__top {
    color: var(--color-text-muted);
    text-decoration: none;
    white-space: nowrap;
  }

  .footer__nav-list a:hover,
  .footer__top:hover {
    color: var(--color-text);
    text-decoration: underline;
    text-underline-offset: 0.2em;
  }
}

/* ==========================================================================
   5. UTILITIES  (drobne pomocniki, najwyższy priorytet)
   ========================================================================== */
@layer utilities {

  /* Treść tylko dla czytników ekranu (np. etykiety nawigacji). */
  .visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  .flow > * + * {
    margin-top: var(--space-md);
  }
}
