/* ============================================================
   BodySpace — warstwa marki
   Wartości pobrane pomiarowo z bodyspace.eu (Playwright), nie z oka:
     tło body            rgb(26,26,28)                       = #1A1A1C
     szkło kontenerów    rgba(255,255,255,.06) + blur(18px) saturate(1.6), radius 28px
     szkło nawigacji     rgba(26,26,28,.8) + blur(40px), pigułka
     przycisk główny     #BA203F / tekst #FCFCFC / 1px #991A33 / pigułka / lowercase
     przycisk wtórny     rgba(252,252,252,.2) / pigułka / lowercase
     gradient nagłówka   linear-gradient(90deg in oklch, #BA203F, #FF6B81)
     font                "Inter Tight"
   ============================================================ */

:root {
  color-scheme: dark;   /* chroni pola i kontrolki systemowe przed jasnym motywem */

  /* rampa marki */
  --color-primary-50:  #fdf4f6;
  --color-primary-100: #f8d2da;
  --color-primary-300: #eea0b1;
  --color-primary-400: #cc435e;
  --color-primary-500: #ba203f;
  --color-primary-600: #991a33;
  --color-primary-700: #751427;
  --color-primary-800: #520e1c;

  /* powierzchnie ciemne */
  --bs-bg:          #1a1a1c;   /* tło globalne */
  --bs-bg-deep:     #070b10;
  --bs-glass:       rgba(255, 255, 255, .06);   /* #FFFFFF0F */
  --bs-glass-hi:    rgba(255, 255, 255, .10);
  --bs-glass-line:  rgba(255, 255, 255, .12);
  --bs-field-line:  rgba(255, 255, 255, .28);   /* obrys pól — WCAG 1.4.11 (3:1) */
  --bs-glass-blur:  blur(18px) saturate(1.6);
  --bs-radius:      28px;

  /* tekst na ciemnym */
  --bs-fg:          #fcfcfc;
  --bs-fg-dim:      rgba(252, 252, 252, .72);   /* było .60 — WCAG AA */
  --bs-fg-mute:     rgba(252, 252, 252, .65);   /* było .38 — WCAG AA */
  --bs-placeholder: rgba(252, 252, 252, .58);

  --bs-teal:        #1390af;
  --bs-pink:        #ff6b81;

  /* typografia marki (zmierzona na bodyspace.eu):
     Poppins  — nagłówki, etykiety, przyciski (ls 1.4px na dużych)
     Mulish   — akapity, opisy, podpisy, sublinie */
  --font-main:    "Poppins", ui-sans-serif, system-ui, sans-serif;
  --font-caption: "Mulish", ui-sans-serif, system-ui, sans-serif;
  --default-font-family: var(--font-main);
}

@layer base {
  html { background: var(--bs-bg); }
  body {
    font-family: var(--font-main);
    background: transparent;   /* tło niesie html — inaczej zamalowałoby dekoracje */
    color: var(--bs-fg);
    -webkit-font-smoothing: antialiased;
  }
  ::selection { background: rgba(186,32,63,.35); }

  /* jeden spójny wskaźnik fokusu dla wszystkiego, co interaktywne */
  :where(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid #ff6b81;
    outline-offset: 2px;
    border-radius: 6px;
  }

  /* autouzupełnianie Chrome nie może rozjaśnić pól */
  input:-webkit-autofill,
  input:-webkit-autofill:hover,
  input:-webkit-autofill:focus {
    -webkit-text-fill-color: #fcfcfc;
    -webkit-box-shadow: 0 0 0 1000px #26262a inset;
    caret-color: #fcfcfc;
    transition: background-color 9999s ease-in-out 0s;
  }
}

@layer components {

  /* ---- dekoracje gradientowe (te same pliki co na bodyspace.eu) ---- */
  /* warstwa przypięta do okna — dekoracje nigdy nie rozpychają układu */
  .bs-grad-layer {
    position: fixed; inset: 0; overflow: hidden;
    pointer-events: none; z-index: 0;
  }
  .bs-content { position: relative; z-index: 1; }
  .bs-grad {
    position: absolute;
    pointer-events: none; user-select: none;
    width: 900px; height: 900px; max-width: none;   /* własna wysokość — brak webp nie zwija warstwy */
    transform: rotate(-41deg);
    /* maska wygasza krawędzie — bez niej gradient urywa się twardo przy brzegu okna */
    mask-image: radial-gradient(closest-side, #000 30%, transparent 100%);
    -webkit-mask-image: radial-gradient(closest-side, #000 30%, transparent 100%);
  }
  /* na wąskich ekranach dekoracje mają być ledwie wyczuwalne */
  @media (max-width: 640px) {
    .bs-grad { width: 620px; opacity: .35 !important; }
  }
  .bs-grad img { width: 100%; height: 100%; object-fit: cover; }

  /* ---- szkło ---- */
  .glass {
    /* podkład przyciemniający — gradienty przechodzące pod kartą rozjaśniały ją
       i zbijały kontrast tekstu poniżej AA */
    background: linear-gradient(rgba(26,26,28,.5), rgba(26,26,28,.5)), var(--bs-glass);
    backdrop-filter: var(--bs-glass-blur);
    -webkit-backdrop-filter: var(--bs-glass-blur);
    border-radius: var(--bs-radius);
    border: 1px solid var(--bs-glass-line);
  }
  .glass-soft {
    background: rgba(255,255,255,.04);
    backdrop-filter: blur(14px) saturate(1.4);
    -webkit-backdrop-filter: blur(14px) saturate(1.4);
    border-radius: 18px;
    border: 1px solid rgba(255,255,255,.07);
  }
  .glass-nav {
    background: rgba(26,26,28,.8);
    backdrop-filter: blur(40px);
    -webkit-backdrop-filter: blur(40px);
    border-radius: 9999px;
  }

  /* ---- typografia ---- */
  h1, h2, h3, h4, h5, h6 { font-family: var(--font-main); }
  .display { letter-spacing: 1.4px; }              /* sygnatura marki na dużych nagłówkach */
  .subline, .caption, .hint, .muted-text {
    font-family: var(--font-caption);
  }
  .subline { font-size: 1rem; line-height: 1.625; letter-spacing: .1px; color: var(--bs-fg-dim); }
  .caption { font-size: .875rem; font-weight: 500; }
  p.body-text { font-family: var(--font-caption); line-height: 1.5; }

  /* ---- nagłówek z gradientem marki ---- */
  .heading-bs {
    background: linear-gradient(90deg in oklch, #ba203f 0%, #ff6b81 100%);
    -webkit-background-clip: text; background-clip: text;
    color: transparent;
  }

  /* ---- przyciski (1:1 z bodyspace.eu) ---- */
  .b {
    display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
    border-radius: 9999px;
    font-family: var(--font-main);
    font-size: 15px; font-weight: 500; line-height: 1.2;
    text-transform: lowercase; letter-spacing: normal;
    /* Rozmiar TU, nie w wariantach — jeden przycisk = jedna wysokość na całej
       aplikacji. min-height trzyma równy rząd nawet, gdy treść jest krótka
       („+ dodaj") i daje sensowne pole dotyku. */
    padding: 11px 22px; min-height: 44px;
    cursor: pointer; border: 1px solid transparent;
    transition: background .18s ease, border-color .18s ease, transform .18s ease;
  }
  /* Warianty różnią się WYŁĄCZNIE kolorem — rozmiar jest jeden, wspólny (z `.b`).
     Wcześniej każdy wariant miał własny padding i font-size, więc w jednym pasku
     stały przyciski o wysokości 34/41/49/53 px i w dwóch rozmiarach pisma.
     Waga wizualna to zadanie koloru; wielkość to osobna oś (`.b-lg`). */
  .b-primary {
    background: #ba203f; color: #fcfcfc;
    border-color: #991a33;
  }
  .b-primary:hover { background: #a81c38; }
  .b-secondary {
    background: rgba(252,252,252,.2); color: #fcfcfc;
    border-color: transparent;
  }
  .b-secondary:hover { background: rgba(252,252,252,.28); }
  .b-quiet {
    background: rgba(255,255,255,.03); color: var(--bs-fg-dim);
    border-color: rgba(255,255,255,.1);
  }
  .b-quiet:hover { color: var(--bs-fg); border-color: rgba(255,255,255,.2); }
  /* Jedyny wariant, który świadomie zmienia rozmiar — duży przycisk logowania. */
  .b-lg { padding: 14px 32px; font-size: 16px; min-height: 52px; }
  .b-full { width: 100%; }

  /* ---- pola formularza na ciemnym ---- */
  .fld {
    /* Ta sama wysokość co `.b` (44 px) — pole i stojący obok niego przycisk
       muszą tworzyć jedną linię. Wcześniej pole miało 52 px i rozciągało
       przycisk we flexie, przez co ten sam przycisk miał inną wysokość
       na różnych ekranach. */
    width: 100%; padding: .625rem 1rem; min-height: 44px; font-size: .9375rem;
    /* Ta sama wysokość linii co w `.b` — bez tego pole wychodzi 44,5 px
       i rozciąga sąsiadujący przycisk do 45 px. */
    line-height: 1.2;
    color: var(--bs-fg);
    background: rgba(255,255,255,.04);
    border: 1px solid var(--bs-field-line);
    border-radius: 14px;
    transition: border-color .18s, background .18s, box-shadow .18s;
  }
  /* Pole wielolinijkowe rośnie od swojej liczby wierszy — min-height nie ma go
     spłaszczać do jednej linii. */
  textarea.fld { min-height: 0; padding: .75rem 1rem; }

  /* Pola liczbowe: strzałki w górę/dół precz. Przeglądarka rezerwuje na nie
     miejsce W ŚRODKU pola — przy wąskiej kolumnie wypychały treść poza widok.
     Do wpisywania ilości i ceny są zbędne, klawiatura wystarcza. */
  input[type=number].fld { appearance: textfield; -moz-appearance: textfield; }
  input[type=number].fld::-webkit-outer-spin-button,
  input[type=number].fld::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
  /* Ciasne kolumny (ilość) dostają węższy odstęp — 2 × 16 px nie mieści się
     w polu, które ma prawo być wąskie. */
  .fld-waskie { padding-left: .5rem; padding-right: .5rem; min-width: 3rem; text-align: center; }

  /* Listy wyboru dostają WŁASNĄ strzałkę zamiast natywnej. Przeglądarka rysuje
     swoją w obszarze paddingu, tuż przy krawędzi pola, i nie da się jej odsunąć —
     wygląda na przyklejoną do obrysu. Po `appearance:none` odstęp jest nasz
     (1rem od prawej), a strzałka wygląda tak samo w każdej przeglądarce.
     `padding-right` musi zostawić miejsce na strzałkę, żeby długa nazwa
     pozycji katalogu nie wchodziła pod nią. */
  select.fld {
    appearance: none; -webkit-appearance: none; -moz-appearance: none;
    padding-right: 2.75rem;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23fcfcfc' stroke-opacity='.72' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    background-size: 12px 8px;
  }
  select.fld:hover { background-color: rgba(255,255,255,.06); }
  /* Lista rozwinięta rysuje się natywnie — bez tego pozycje bywają białym
     tekstem na białym tle w niektórych przeglądarkach. */
  select.fld option { background: #26262a; color: var(--bs-fg); }
  .fld::placeholder { color: var(--bs-placeholder); }
  /* pola mają własny obrys, więc NIE dokładamy zewnętrznej obwódki —
     inaczej powstają dwa pierścienie. Jeden obrys + miękka poświata. */
  .fld:focus-visible {
    outline: none;
    border-color: #ff6b81;
    background: rgba(255,255,255,.07);
    box-shadow: 0 0 0 3px rgba(255,107,129,.22);
  }
  /* stan błędu walidacji */
  .fld[aria-invalid="true"], .fld:user-invalid {
    border-color: #ff6b81;
    background: rgba(186,32,63,.12);
  }
  .fld option { background: #1a1a1c; color: var(--bs-fg); }
  .lbl { display:block; font-family: var(--font-main); font-size:.8125rem; font-weight:500; color:var(--bs-fg-dim); margin-bottom:.5rem; }
  .hint { font-family: var(--font-caption); font-size:.75rem; color:var(--bs-fg-mute); margin-top:.375rem; }
  /* minimalne cele dotykowe 24×24 (WCAG 2.5.8) */
  .tap { display:inline-flex; align-items:center; justify-content:center; min-width:24px; min-height:24px; padding:4px 6px; }
  .err { font-family: var(--font-caption); font-size:.8125rem; color:#ff6b81; margin-top:.5rem; }

  /* ---- statusy oferty ---- */
  .status {
    display:inline-flex; align-items:center; gap:.375rem;
    padding:.25rem .625rem; border-radius:9999px;
    font-size:.75rem; font-weight:500; white-space:nowrap;
    border:1px solid transparent;
  }
  .status::before { content:""; width:.375rem; height:.375rem; border-radius:9999px; background:currentColor; }
  .status-szkic         { background:rgba(255,255,255,.06); color:rgba(252,252,252,.6); border-color:rgba(255,255,255,.1); }
  .status-wyslana       { background:rgba(19,144,175,.15); color:#66d3ee; border-color:rgba(19,144,175,.3); }
  .status-otwarta       { background:rgba(131,231,238,.14); color:#83e7ee; border-color:rgba(131,231,238,.28); }
  .status-zaakceptowana { background:rgba(198,245,111,.14); color:#c6f56f; border-color:rgba(198,245,111,.28); }
  .status-wygasla       { background:rgba(186,32,63,.16); color:#ff6b81; border-color:rgba(186,32,63,.35); }

  /* ---- pasek zaangażowania ---- */
  .spark { display:inline-flex; align-items:flex-end; gap:2px; height:14px; }
  .spark i { width:3px; background:#83e7ee; border-radius:1px; display:block; opacity:.8; }

  /* ---- tabela ---- */
  .tbl { width:100%; border-collapse:collapse; }
  /* 🔴 Tabela pozycji nie może się ściskać w nieskończoność. Zgłoszenie
     2026-08-10: na laptopie 1366 px kolumna „Ilość" schodziła do 49 px, a że
     odstęp w polu zjada 32 px, na cyfrę zostawało 15 px — wpisana ilość
     ZNIKAŁA z ekranu, choć siedziała w polu. Zmierzone, nie zgadnięte.
     Poniżej tej szerokości otoczka `.overflow-x-auto` przewija w poziomie,
     zamiast miażdżyć kolumny. */
  /* Tabela pozycji: „Cena po rabacie" nie jest już polem, tylko liczbą, więc
     potrzebuje mniej miejsca niż przy dwóch polach do wpisywania. 38 rem mieści
     się w kreatorze na 13-calowym ekranie BEZ przewijania w poziomie. */
  .tbl { min-width: 38rem; }
  .tbl th {
    text-align:left; font-size:.6875rem; font-weight:600; letter-spacing:.06em;
    text-transform:uppercase; color:var(--bs-fg-mute); padding:.875rem 1rem;
    font-family: var(--font-main);
    border-bottom:1px solid rgba(255,255,255,.08);
  }
  .tbl td { font-family: var(--font-caption); padding:1rem; border-bottom:1px solid rgba(255,255,255,.05); font-size:.875rem; color:rgba(252,252,252,.82); }
  .tbl tbody tr:hover { background:rgba(255,255,255,.03); }

  /* ---- nawigacja boczna ---- */
  .nav-i {
    display:flex; align-items:center; gap:.75rem; padding:.75rem 1rem;
    border-radius:9999px; font-size:.9375rem; color:var(--bs-fg-dim); text-decoration:none;
    transition:background .18s, color .18s;
  }
  .nav-i:hover { background:rgba(255,255,255,.06); color:var(--bs-fg); }
  .nav-i.on { background:#ba203f; border:1px solid #991a33; color:#fcfcfc; }

  /* ---- własne pole wyboru (natywne było szarym kwadratem) ---- */
  .chk {
    appearance: none; -webkit-appearance: none;
    width: 20px; height: 20px; border-radius: 6px; flex-shrink: 0;
    border: 1px solid var(--bs-field-line);
    background: rgba(255,255,255,.04);
    display: inline-grid; place-content: center; cursor: pointer;
    transition: background .15s, border-color .15s;
  }
  .chk::before {
    content: ""; width: 11px; height: 11px; transform: scale(0);
    transition: transform .12s ease-out;
    box-shadow: inset 1em 1em #fcfcfc;
    clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
  }
  .chk:checked { background: #ba203f; border-color: #991a33; }
  .chk:checked::before { transform: scale(1); }

  /* ---- pasek filtrów (lista rozmów) ----
     Jeden rząd pól tej samej wysokości co przycisk (44 px). Pola SĄ już opisane
     pierwszą pozycją listy („Wszystkie numery"), więc nie dokładamy nad nimi
     drobnych podpisów — to one robiły z paska drabinkę. Opis dla czytnika
     ekranu siedzi w `aria-label`. */
  .filtry { display: flex; flex-wrap: wrap; align-items: center; gap: .625rem; }
  /* `.fld` jest z natury na całą szerokość (formularze w kolumnie).
     W pasku pola stoją obok siebie i mają się zwężać do swojej treści. */
  .filtry .fld { width: auto; }
  .filtry select.fld { max-width: 12.5rem; text-overflow: ellipsis; }
  .filtry-szukaj { position: relative; flex: 1 1 13rem; min-width: 0; max-width: 21rem; }
  .filtry-szukaj .fld { width: 100%; padding-left: 2.75rem; }
  .filtry-szukaj svg {
    position: absolute; left: 1rem; top: 50%; transform: translateY(-50%);
    color: var(--bs-fg-mute); pointer-events: none;
  }
  /* Krzyżyk czyszczenia pola `type=search` w WebKicie jest jasny i kwadratowy —
     na ciemnym tle wygląda jak usterka. Czyszczenie mamy własne, obok. */
  .filtry input[type=search]::-webkit-search-cancel-button { -webkit-appearance: none; }
  .filtry-wynik { color: var(--bs-fg-mute); margin-top: .875rem; }
  .filtry-wynik strong { color: var(--bs-fg-dim); font-weight: 600; }
  .filtry-wyczysc { color: #ff6b81; text-decoration: none; margin-left: .5rem; }
  .filtry-wyczysc:hover { text-decoration: underline; }
  @media (max-width: 640px) {
    /* Na telefonie pasek staje się kolumną: cztery listy obok siebie zwężają się
       do nieczytelnych kikutów. */
    .filtry > * { width: 100%; }
    .filtry .fld, .filtry select.fld, .filtry-szukaj { max-width: none; width: 100%; }
  }

  /* ---- przełącznik widoku (segmentowy) ---- */
  .seg { display:inline-flex; padding:4px; border-radius:9999px;
         background:rgba(255,255,255,.05); border:1px solid var(--bs-glass-line); }
  .seg-btn { font-family:var(--font-main); font-size:.875rem; font-weight:500;
             padding:.5rem 1.125rem; border-radius:9999px; color:var(--bs-fg-dim);
             cursor:pointer; border:1px solid transparent; transition:background .18s,color .18s; }
  .seg-btn:hover { color:var(--bs-fg); }
  .seg-btn[aria-selected="true"] { background:#ba203f; border-color:#991a33; color:#fcfcfc; }

  /* ---- metryki nagłówkowe (liczba nad podpisem) ---- */
  .metric-v { font-family:var(--font-main); font-size:1.75rem; font-weight:600; line-height:1.1; }
  .metric-k { font-family:var(--font-caption); font-size:.8125rem; color:var(--bs-fg-mute); margin-top:.25rem; }

  /* ---- tablica kanban ---- */
  .kan-board { display:grid; grid-auto-flow:column; grid-auto-columns:minmax(248px,1fr);
               gap:1rem; overflow-x:auto; padding-bottom:.5rem; align-items:start; }
  /* 🔴 Na 13-calowym laptopie pięć kolumn po 248 px NIE MIEŚCI SIĘ: przy 1280 px
     widać trzy, przy 1366 — cztery. „Zaakceptowana" i „Odrzucona" chowały się za
     paskiem przewijania wewnątrz tablicy, którego nikt nie szuka (zgłoszenie
     2026-08-12: „dziewczyny pracują na 13-calowych laptopach i nic tam nie widzą").
     Poniżej 1500 px kolumny dzielą się szerokością po równo — węższe, ale WSZYSTKIE. */
  @media (max-width: 1500px) {
    .kan-board { grid-auto-columns: minmax(0, 1fr); }
    .kan-col { padding: .75rem; }
    .kan-card { padding: .7rem .75rem; }
  }
  /* Poniżej 1024 px menu boczne i tak znika, więc tablica ma całą szerokość —
     ale pięć kolumn na tablecie byłoby już nieczytelne, wraca przewijanie. */
  @media (max-width: 1023px) {
    .kan-board { grid-auto-columns: minmax(210px, 1fr); }
  }
  .kan-col { background:rgba(255,255,255,.035); border:1px solid var(--bs-glass-line);
             border-radius:var(--bs-radius); padding:1rem; min-height:340px;
             display:flex; flex-direction:column; gap:.75rem; transition:background .18s, border-color .18s; }
  .kan-col.drag-over { background:rgba(186,32,63,.10); border-color:#ba203f; }
  .kan-head { display:flex; align-items:center; gap:.5rem; padding:0 .25rem .25rem; }
  .kan-title { font-family:var(--font-main); font-size:.875rem; font-weight:500; }
  .kan-count { font-family:var(--font-caption); font-size:.75rem; color:var(--bs-fg-mute);
               background:rgba(255,255,255,.07); border-radius:9999px; padding:.05rem .5rem; }

  .kan-card { background:linear-gradient(rgba(26,26,28,.5),rgba(26,26,28,.5)), rgba(255,255,255,.07);
              border:1px solid var(--bs-glass-line); border-radius:18px; padding:1rem;
              cursor:grab; transition:border-color .18s, transform .12s; }
  .kan-card:hover { border-color:rgba(255,255,255,.24); }
  .kan-card:active { cursor:grabbing; }
  .kan-card.dragging { opacity:.45; transform:scale(.98); }
  .kan-card-t { font-family:var(--font-main); font-weight:500; font-size:.9375rem; }
  .kan-card-m { font-family:var(--font-caption); font-size:.75rem; color:var(--bs-fg-mute); margin-top:.3rem; line-height:1.5; }
  .kan-empty { font-family:var(--font-caption); font-size:.8125rem; color:var(--bs-fg-mute);
               border:1px dashed rgba(255,255,255,.14); border-radius:16px;
               padding:1.25rem; text-align:center; }
  .sig { display:inline-flex; align-items:center; gap:.3rem; font-family:var(--font-caption);
         font-size:.6875rem; padding:.2rem .6rem; border-radius:9999px;
         background:rgba(131,231,238,.14); color:#83e7ee; border:1px solid rgba(131,231,238,.28); }
  .sig-warn { background:rgba(186,32,63,.16); color:#ff6b81; border-color:rgba(186,32,63,.35); }

  /* ---- panel boczny jako szkło ---- */
  .side {
    background: linear-gradient(rgba(26,26,28,.55), rgba(26,26,28,.55)), rgba(255,255,255,.05);
    backdrop-filter: blur(18px) saturate(1.6);
    -webkit-backdrop-filter: blur(18px) saturate(1.6);
    border: 1px solid var(--bs-glass-line);
    border-radius: var(--bs-radius);
  }

  /* ---- karta statystyki ---- */
  .stat { padding: 1.125rem 1.25rem; }
  .stat-k { font-family: var(--font-caption); font-size:.75rem; text-transform:uppercase;
            letter-spacing:.06em; color:var(--bs-fg-mute); }
  .stat-v { font-family: var(--font-main); font-size:1.75rem; font-weight:600; margin-top:.375rem; }

  /* logo BodySpace to czarny SVG — na ciemnym tle odwracamy */
  .logo-invert { filter: invert(1); }   /* brightness(2) wypalał krawędzie */

  @media print { .no-print { display:none !important; } }
}

  /* ---- 13-calowy laptop: odzyskujemy szerokość dla treści ---- */
  /* Menu i prawa szpalta są stałej szerokości, więc na 1280 px zjadały 560 px
     z 1280 — na formularz zostawało ~620 px i tabela pozycji musiała się
     przewijać. Poniżej 1500 px oba pasy są węższe, a odstępy w kartach mniejsze.
     Zmierzone przed i po; nic nie chowamy, tylko zaciskamy. */
  @media (max-width: 1500px) {
    .glass { padding: 1.25rem !important; }
  }

  /* ---- Układ kreatora: jedno źródło prawdy ----------------------------- */
  /* 🔴 Poprzednia wersja miała `@media (max-width:1500px)` BEZ dolnej granicy,
     więc wymuszała dwie kolumny aż do zera — na 414 px formularz dostawał 86 px
     i aplikacja przestawała być używalna (audyt 2026-08-12, potwierdzone
     pomiarem). Reguła mobile-first z progami rosnącymi nie ma jak się rozjechać.
     `minmax(0,1fr)` jest OBOWIĄZKOWE: bez niego kolumna nie zejdzie poniżej
     szerokości tabeli pozycji i wypchnie stronę poza ekran. */
  .ukl-kreator { grid-template-columns: 1fr; }
  .ukl-kreator > * { min-width: 0; }
  @media (min-width: 1024px) { .ukl-kreator { grid-template-columns: minmax(0,1fr) 280px; } }
  @media (min-width: 1500px) { .ukl-kreator { grid-template-columns: minmax(0,1fr) 320px; } }

  /* ---- Pola formularzy na dotyku --------------------------------------- */
  /* Safari na iOS sam przybliża stronę przy wejściu w pole mniejsze niż 16 px
     i już z tego przybliżenia nie wraca. Na myszy zostaje 15 px, bo tam problem
     nie istnieje, a gęstość formularza na 13-calowym laptopie ma znaczenie. */
  .fld { font-size: 1rem; }
  @media (pointer: fine) { .fld { font-size: .9375rem; } }

  /* ---- Cele dotykowe --------------------------------------------------- */
  /* Ikona zostaje mała, ale obszar kliknięcia rośnie do 44x44 (WCAG 2.5.5).
     Kosz i „x" w katalogu KASUJĄ — na telefonie bez najechania kursorem nie ma
     żadnego bufora przed pomyłką. */
  /* `.del` to „x" kasujące pozycję KATALOGU — najgroźniejszy mały przycisk
     w aplikacji. Klasę pominąłem przy pierwszym przejściu (szukałem `.kat-usun`,
     której nie ma), więc na telefonie dalej miał 28 px. */
  .kosz, .del { position: relative; }
  .kosz::after, .del::after {
    content: ""; position: absolute; top: 50%; left: 50%;
    width: 44px; height: 44px; transform: translate(-50%, -50%);
  }

  /* Napisy na przyciskach nie łamią się w środku pigułki — „pobierz pdf (szkic)"
     robił się owalną plamą na dwie linie. Zawija się CAŁY pasek, nie napis. */
  .b { white-space: nowrap; }

  /* Dekoracyjny gradient nie może rozpychać strony: 1058 px w oknie 414 px.
     Kotwiczymy do okna i wycinamy — poza tym nie bierze udziału w układzie. */
  .bs-grad { pointer-events: none; max-width: 100vw; overflow: hidden; }
  .bs-grad > img { max-width: none; }

  /* ---- Menu jako poziomy pasek poniżej 1024 px ------------------------- */
  /* Panel ma być używalny na telefonie do zalogowania się i sprawdzenia
     czegoś (decyzja właściciela 2026-08-12) — a nie było jak nawigować ANI
     się wylogować, bo `.side` znikało bez zamiennika. */
  @media (max-width: 1023px) {
    .bs-content { flex-direction: column; }
    .side {
      width: 100% !important; height: auto !important; position: static !important;
      flex-direction: row; align-items: center; gap: .4rem;
      overflow-x: auto; overflow-y: hidden; padding: .6rem .75rem !important;
      -webkit-overflow-scrolling: touch; scrollbar-width: none;
    }
    .side::-webkit-scrollbar { display: none; }
    .side .tylko-szeroko { display: none; }
    /* Sekcje menu tracą pionowe odstępy i kreski — w poziomie nic nie oddzielają. */
    .side nav, .side > div { display: flex; flex-direction: row; align-items: center;
      gap: .4rem; margin: 0 !important; padding: 0 !important; border: 0 !important; }
    .side form { margin: 0; }
    .nav-i { white-space: nowrap; margin: 0 !important; padding: .6rem .9rem !important;
             min-height: 44px; display: flex; align-items: center; }
  }

  /* ---- Zwijanie menu bocznego ------------------------------------------ */
  /* Zastąpiło wymuszone zwężanie do 200 px poniżej 1500 px: menu ma pełne
     240 px i czytelne etykiety, a kto potrzebuje miejsca na 13-calowym
     ekranie, zwija je jednym kliknięciem. Wybór pamięta przeglądarka. */
  .zwin { display: grid; place-items: center; width: 32px; height: 32px; flex: none;
          border-radius: 10px; color: var(--bs-fg-mute); background: transparent;
          border: 1px solid transparent; cursor: pointer; position: relative;
          transition: background .18s, color .18s, border-color .18s; }
  .zwin:hover { background: var(--bs-glass); color: var(--bs-fg); border-color: var(--bs-glass-line); }
  /* Obszar kliknięcia 44x44 przy 32-pikselowej ikonie (WCAG 2.5.5). */
  .zwin::after { content: ""; position: absolute; top: 50%; left: 50%;
                 width: 44px; height: 44px; transform: translate(-50%, -50%); }
  .side { transition: width .2s ease; }

  /* Ikona przy każdej pozycji — jedyne, co zostaje po zwinięciu. */
  .nav-i { display: flex; align-items: center; gap: .65rem; }
  .nav-ikona { flex: none; opacity: .85; }
  .nav-i.on .nav-ikona { opacity: 1; }

  .menu-zwiniete .side { width: 60px !important; padding: .75rem .5rem !important; }
  /* Wszystko, co jest samym tekstem, znika razem z szerokością: logo, podpis
     sekcji „Administracja", imię i rola. Zostają ikony i awatar — po nim widać,
     kto jest zalogowany, a to jedyna informacja warta 60 pikseli. */
  .menu-zwiniete .znika-po-zwinieciu,
  .menu-zwiniete .tylko-szeroko { display: none !important; }
  .menu-zwiniete .blok-uzytkownika { justify-content: center; padding: 0 !important; }
  .menu-zwiniete .naglowek-menu { justify-content: center; margin-bottom: 1.25rem; }
  .menu-zwiniete .zwin svg { transform: rotate(180deg); }
  /* 🔴 Napis CHOWAMY, ale zostawiamy w drzewie — `display:none` odebrałby
     odnośnikowi nazwę i czytnik ekranu przeczytałby siedem pustych przycisków.
     Podpowiedź pod kursorem niesie `title`. */
  .menu-zwiniete .nav-tekst {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
  }
  .menu-zwiniete .nav-i { justify-content: center; padding: .7rem 0 !important;
                          min-height: 44px; position: relative; }
  .menu-zwiniete .side nav, .menu-zwiniete .side > div { align-items: center; }
  /* Kreska działowa zostaje — bez niej siedem ikon zlewa się w jeden ciąg. */
  .menu-zwiniete .side > div:not(:first-child) { width: 100%; padding-top: .75rem !important; }

  /* Na wąskim ekranie menu jest poziomym paskiem — nie ma czego zwijać. */
  @media (max-width: 1023px) {
    .zwin, .naglowek-menu { display: none; }
    .menu-zwiniete .side { width: 100% !important; padding: .6rem .75rem !important; }
    .menu-zwiniete .side nav, .menu-zwiniete .side > div:not(:first-child) { display: flex !important; }
  }

  /* ---- Cena startowa na karcie katalogu -------------------------------- */
  .cena-start { margin-top: .6rem; }
  .cena-start .lbl { display: block; margin-bottom: .3rem; }
  .cena-wiersz { display: flex; align-items: center; gap: .4rem; margin-top: .3rem; }
  .cena-wiersz input { flex: 1; min-width: 0; min-height: 36px;
                       padding: .35rem .55rem; font-size: .875rem; }
  .cena-wal { flex: none; width: 2.4rem; font-family: var(--font-caption);
              font-size: .75rem; color: var(--bs-fg-mute); }
  .cena-start .stan { min-height: 1em; margin: .35rem 0 0; font-size: .6875rem; }
  .cena-start .hint { min-height: 1em; }

/* ── Licznik nowych zamówień przy „Order Form" (od 29.09.2026) ───────────
   Jedyny sygnał dla handlowca, gdy formularz nie ma deala w CRM. Przy
   zwiniętym menu zostają same ikony — licznik przechodzi wtedy w kropkę
   na ikonie, bo liczba nie zmieściłaby się w 18 pikselach. */
.nav-licznik {
  margin-left: auto; min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: 99px; background: #ba203f; color: #fff;
  font-size: 11px; font-weight: 700; line-height: 20px; text-align: center;
  font-variant-numeric: tabular-nums;
}
.menu-zwiniete .nav-licznik {
  position: absolute; top: 6px; right: 6px; min-width: 9px; height: 9px;
  padding: 0; font-size: 0; margin: 0; border: 2px solid var(--bs-bg);
}
.menu-zwiniete .nav-i { position: relative; }
