/* =========================================================
   TIVOLI — order.css
   "Zamów online" — ETAP 5. Loaded only on that page (see
   inc/enqueue.php), same conditional pattern as menu.css.
   ========================================================= */

.order-subcategory {
	margin-top: var(--space-xl);
}

.order-subcategory:first-child {
	margin-top: 0;
}

.order-subcategory__title {
	font-size: var(--fs-h4);
	margin-bottom: var(--space-md);
}

/* ETAP 17B (audyt 17A, ustalenie A2) — brakująca kompensacja pod
   sticky header + sticky quicknav przy skoku do kotwicy (np.
   "#napoje"), ten sam mechanizm i ta sama wartość co
   .menu-category w menu.css (89px nagłówek + ~69px quicknav +
   oddech), teraz że menu.css/menu.js są ładowane też na tej stronie. */
.order-section {
	scroll-margin-top: 170px;
}

/* ---------- Category quicknav — full-width 5-column layout (desktop only) ----------
   Użytkownik (2026-08): domyślny pasek z menu.css (.menu-quicknav__item —
   małe, lewostronne "pigułki" na przewijanej liście) zostaje bez zmian
   na /menu/ — .menu-quicknav--order (nadana wyłącznie w
   template-parts/order/order-quicknav.php, nigdy w menu-quicknav.php)
   to jedyny hak, więc menu.css i JS (assets/js/menu.js — przełączanie
   .is-active, płynne przewijanie) zostają całkowicie nietknięte, tylko
   layout/rozmiar na tej jednej stronie. Poniżej 900px wraca dokładnie
   do bazowego, poziomo przewijanego paska z menu.css — ten sam,
   sprawdzony wzorzec co na /menu/ (tam też 100% bezpieczny na wąskich
   ekranach), zamiast wymuszać 5 kolumn tam, gdzie realnie mogłyby być
   za ciasne dla "Zapiekanki". */
@media (min-width: 901px) {
	.menu-quicknav--order .menu-quicknav__list {
		display: grid;
		grid-template-columns: repeat(5, 1fr);
		gap: var(--space-xs);
		overflow-x: visible;
	}

	.menu-quicknav--order .menu-quicknav__item {
		justify-content: center;
		width: 100%;
		padding-block: 0.95em;
		font-size: 1.05rem;
	}
}

/* ---------- Banner (added-to-cart feedback) ---------- */
.order-banner {
	padding: var(--space-sm) var(--space-md);
	border-radius: var(--radius-sm);
	margin-bottom: var(--space-md);
	font-size: var(--fs-small);
}

/* ETAP 17E (§7-8) — was a single <p> with an inline underlined text
   link; now a flex row with the existing .btn system for a clearer,
   more tappable "Przejdź do koszyka" action, reusing .btn--primary
   .btn--sm exactly as used elsewhere on this page — no new button
   variant. */
.order-banner--success {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-sm);
	background: var(--color-green-100);
	color: var(--color-green-800);
}

.order-banner__text {
	margin: 0;
}

.order-banner--error {
	background: var(--color-red-soft);
	color: var(--color-red);
}

/* Odbiór + Dostawa ręcznie wyłączone jednocześnie, mimo trwających
   godzin zamówień online (użytkownik, 2026-09) — celowo neutralny ton,
   nigdy czerwony/alarmowy: to informacja, nie błąd, telefon nadal
   działa. Te same tokeny co reszta strony (tło kremowe, ciemna zieleń,
   subtelna ramka --color-cream-line), nigdy nowy kolor. */
.order-banner--notice {
	background: var(--color-cream-deep);
	color: var(--color-green-800);
	border: 1px solid var(--color-cream-line);
}

/* ETAP 17B (audyt 17A, ustalenie A4) — kontekst bieżącego zamówienia
   (lokal / sposób realizacji / orientacyjny czas), widoczny na tej
   stronie WYŁĄCZNIE gdy klient ma już oba wybory zapisane w sesji z
   wcześniejszej wizyty w checkoucie — dokładnie ta sama, niezmieniona
   reguła co poprzednio (page-zamow-online.php), teraz tylko z
   wyraźniejszą prezentacją zamiast pojedynczego akapitu w stylu
   .order-banner--info (usunięty, był używany wyłącznie tutaj). */
/* ---------- Siatka dostępności (audyt UX, 2026-08) — 4 kombinacje
   lokal x sposób realizacji, widoczne od razu na starcie strony.
   Zastępuje dawną .order-context (pokazującą tylko jedną, zapamiętaną z
   checkoutu kombinację). ---------- */
.order-availability-grid__title {
	font-family: var(--font-display);
	font-size: 1.05rem;
	font-weight: 700;
	color: var(--color-ink);
	margin-bottom: var(--space-sm);
}

.order-availability-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: var(--space-sm);
	margin-bottom: var(--space-lg);
}

@media (max-width: 900px) {
	.order-availability-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 480px) {
	.order-availability-grid {
		grid-template-columns: 1fr;
	}
}

.order-availability-card {
	display: flex;
	flex-direction: column;
	gap: var(--space-3xs);
	background: var(--color-white);
	border: 1.5px solid var(--color-cream-line);
	border-radius: var(--radius-md);
	padding: var(--space-sm) var(--space-md);
}

.order-availability-card--unavailable {
	opacity: 0.6;
}

.order-availability-card__location {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: 1rem;
	color: var(--color-ink);
}

.order-availability-card__channel {
	color: var(--color-text-muted);
	font-size: var(--fs-small);
}

.order-availability-card__hint {
	color: var(--color-text-muted);
	font-size: var(--fs-small);
	font-style: italic;
}

/* ETAP 17C — odznaka dostępny/tymczasowo niedostępny
   (tivoli_render_channel_status_badge(), inc/order-availability.php)
   przeniesiona z lokalnej kopii tutaj do współdzielonej
   .badge/.badge--tone-success/error w components.css (zawsze
   ładowanego na tej stronie) — ten sam wzorzec teraz też dla
   koszyka/checkoutu, patrz components.css. */

/* ---------- Informacja o alergenach ----------
   Ta sama karta wizualna co .order-availability-card wyżej (biały
   panel, subtelna ramka --color-cream-line, --radius-md) — spójny
   język wizualny na tej samej stronie, bez wymuszania tej samej
   klasy na semantycznie innej treści. Zawsze statyczny blok na dole
   strony (nigdy popup/modal), template-parts/order/allergen-notice.php. */
.allergen-notice {
	display: flex;
	align-items: flex-start;
	gap: var(--space-sm);
	background: var(--color-white);
	border: 1.5px solid var(--color-cream-line);
	border-radius: var(--radius-md);
	padding: var(--space-md);
	margin-top: var(--space-xl);
}

.allergen-notice__icon {
	flex-shrink: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.25rem;
	height: 2.25rem;
	border-radius: var(--radius-full);
	background: var(--color-gold-soft);
	color: var(--color-gold-deep);
}

.allergen-notice__icon svg {
	width: 1.25rem;
	height: 1.25rem;
}

.allergen-notice__body {
	min-width: 0; /* pozwala tekstowi się zawijać zamiast rozpychać flex-row poza szerokość karty */
}

.allergen-notice__title {
	font-family: var(--font-display);
	font-size: 1.05rem;
	font-weight: 700;
	color: var(--color-ink);
	margin: 0 0 var(--space-3xs);
}

.allergen-notice__text {
	color: var(--color-text-muted);
	font-size: var(--fs-small);
	line-height: 1.6;
	margin: 0;
}

@media (max-width: 600px) {
	.allergen-notice {
		padding: var(--space-sm);
		gap: var(--space-xs);
	}
}

/* ---------- Order card ---------- */
.order-card {
	position: relative;
	display: flex;
	flex-direction: column;
	background: var(--color-cream-soft);
	border-radius: var(--radius-lg);
	padding: var(--space-md);
	box-shadow: var(--shadow-sm);
	overflow: hidden;
	transition: box-shadow var(--dur-base) var(--ease-out);
}

.order-card:hover {
	box-shadow: var(--shadow-md);
}

/* ETAP 17E (§7) — brief visual confirmation on the card the customer
   just added, landed on via the anchor-preserving redirect (see
   order-pizza-card.php/order-product-card.php). Transform/opacity-free
   on purpose (border + background only) so it needs no reduced-motion
   override beyond the existing global animation-duration killswitch
   (animations.css) that already applies to every @keyframes rule. */
.order-card.is-just-added {
	border: 2px solid var(--color-green-700);
	animation: tivoli-order-card-added 2.4s var(--ease-out);
}

/* Cart-wide AJAX (audyt UX, 2026-08) — komunikat błędu przy dodawaniu do
   koszyka przez fetch(); zawsze wyrenderowany w DOM, chowany przez
   `hidden` (assets/js/order-cart-add.js zdejmuje/dodaje ten atrybut).
   Formularz bez JS nigdy go nie pokazuje. */
.order-card__ajax-feedback {
	margin: var(--space-2xs) 0 0;
	font-size: var(--fs-small);
	width: 100%;
}

.order-card__ajax-feedback--error {
	color: var(--color-red);
}

.order-card__form button[type="submit"]:disabled,
.drink-order-row__form button[type="submit"]:disabled {
	opacity: 0.6;
	cursor: default;
}

@keyframes tivoli-order-card-added {
	0% { background-color: var(--color-green-100); }
	100% { background-color: var(--color-cream-soft); }
}

.order-card__media {
	position: relative;
	border-radius: var(--radius-md);
	overflow: hidden;
	aspect-ratio: 1 / 1;
	background: var(--color-green-900);
	margin-bottom: var(--space-md);
}

.order-card__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.order-card__media--contain {
	padding: 6%;
}

.order-card__media--contain img {
	object-fit: contain;
}

.order-card__media-empty {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	color: rgba(247, 242, 228, 0.35);
}

.order-card__media-empty svg {
	width: 2.5rem;
	height: 2.5rem;
}

.order-card__body {
	display: flex;
	flex-direction: column;
	gap: var(--space-2xs);
	flex: 1;
}

.order-card__top {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--space-sm);
}

.order-card__name {
	font-family: var(--font-display);
	font-size: 1.25rem;
	font-weight: 600;
}

.order-card__size {
	font-size: var(--fs-small);
	color: var(--color-text-muted);
	white-space: nowrap;
}

.order-card__desc {
	color: var(--color-text-muted);
	font-size: 0.9rem;
	line-height: 1.5;
	margin-bottom: var(--space-2xs);
}

.order-card__unavailable {
	margin-top: auto;
	color: var(--color-text-muted);
	font-size: var(--fs-small);
	font-style: italic;
}

.order-card__form {
	margin-top: auto;
	display: flex;
	flex-direction: column;
	gap: var(--space-sm);
}

/* ---------- Size picker ---------- */
.size-select {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--space-2xs);
	border: none;
	padding: 0;
	margin: 0;
}

.size-option {
	display: flex;
	align-items: center;
	gap: 0.5em;
	min-height: 44px;
	padding: 0.6em 0.7em;
	border: 1.5px solid var(--color-cream-line);
	border-radius: var(--radius-sm);
	background: var(--color-white);
	cursor: pointer;
	transition: border-color var(--dur-fast) var(--ease-out), border-width var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}

.size-option input {
	accent-color: var(--color-green-700);
	flex-shrink: 0;
	width: 1.2em;
	height: 1.2em;
}

/* ETAP 17E (§5) — was border-color + background only, both of which
   read as "just a colour change" at a glance. Selected now also gets
   a visibly thicker border (not just a darker one) plus bold text on
   both the label and price, so the state reads through border WEIGHT
   and text WEIGHT even for a viewer who can't distinguish the colour
   change — on top of the native radio circle, which was already the
   only true "indicator" before this. */
.size-option:has(input:checked) {
	border-width: 2px;
	border-color: var(--color-green-700);
	background: var(--color-green-100);
}

/* ETAP 17E (§16) — rings the whole label (not just the native radio's
   own default outline) when its input has keyboard focus, same
   on-brand ring as .menu-quicknav__item/.pizza-subnav__item. */
.size-option:has(input:focus-visible) {
	box-shadow: 0 0 0 3px var(--color-green-700);
}

.size-option__text {
	display: flex;
	flex-direction: column;
	line-height: 1.25;
}

.size-option__label {
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--color-ink);
}

.size-option:has(input:checked) .size-option__label {
	font-weight: 700;
}

.size-option__diameter {
	font-size: 0.72rem;
	color: var(--color-text-muted);
}

/* ETAP 17B (audyt 17A, ustalenie A3) — cena decyduje, ile klient
   zapłaci, więc dostaje ten sam traktowanie co każda inna cena w
   serwisie (Fraunces, waga 700 — patrz np. .product-card__price w
   menu.css), nie zwykły tekst body w rozmiarze etykiety jak wcześniej.
   Sam sposób liczenia ceny (WooCommerce, tivoli_get_live_prices_for_sku())
   pozostaje bez zmian — to wyłącznie prezentacja. */
.size-option__price {
	margin-left: auto;
	font-family: var(--font-display);
	font-weight: 700;
	font-size: 1.05rem;
	color: var(--color-green-700);
	white-space: nowrap;
}

@media (max-width: 400px) {
	/* Przy 1.05rem/700 cena + krótka etykieta bezpiecznie mieszczą się
	   obok siebie w jednej kolumnie na najwęższych telefonach — dwie
	   kolumny (2×~140px) mogłyby ścieśniać większą cenę. */
	.size-select {
		grid-template-columns: 1fr;
	}
}

/* ---------- Wymagana opcja produktu ("Z wędliną" / "Batat Crunch") ----------
   Kafelki radio (audyt UI 2026-08 — poprzednio zwykły <select>), ten sam
   język wizualny co .size-select/.size-option (wybór rozmiaru pizzy)
   wyżej — celowo OSOBNA nazwa klasy, żeby nie kolidować z selektorami/JS
   specyficznymi dla rozmiaru pizzy (data-half-half-sizes itp.). Bez ceny/
   podpisu — tylko wyśrodkowana etykieta.

   Audyt kosmetyki (2026-08, poprawka): liczba kolumn = dokładna liczba
   opcji (--tivoli-option-count, ustawiane inline przez PHP), NIE
   auto-fit/minmax() — auto-fit potrafił przy pewnych szerokościach
   pośrednich zawinąć 3 kafelki jako 2+1 (jeden "osierocony", innej
   szerokości niż reszta rzędu). Jawna liczba kolumn + align-items: stretch
   gwarantuje identyczną szerokość I wysokość każdego kafelka w rzędzie na
   każdej szerokości ekranu — jedyne załamanie układu to celowy breakpoint
   niżej (1 kolumna), nigdy pośredni/nierówny stan. */
.option-select {
	--tivoli-option-count: 2;
	display: grid;
	grid-template-columns: repeat(var(--tivoli-option-count), 1fr);
	align-items: stretch;
	gap: var(--space-2xs);
	border: none;
	padding: 0;
	margin: 0;
}

@media (max-width: 340px) {
	/* Jedyne celowe załamanie układu — zamiast ściskać 3 kafelki coraz
	   węziej (ryzyko złamania tekstu), pełna szerokość, po jednym pod
	   drugim. Nigdy stanu pośredniego (np. 2+1) — każdy rząd zawsze ma
	   tyle samo, równych kolumn. */
	.option-select {
		grid-template-columns: 1fr;
	}
}

.option-tile {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.45em;
	min-height: 44px;
	padding: 0.6em 0.7em;
	border: 1.5px solid var(--color-cream-line);
	border-radius: var(--radius-sm);
	background: var(--color-white);
	cursor: pointer;
	text-align: center;
	line-height: 1.2;
	transition: border-color var(--dur-fast) var(--ease-out), border-width var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}

.option-tile input {
	accent-color: var(--color-green-700);
	flex-shrink: 0;
	width: 1.1em;
	height: 1.1em;
	margin: 0;
}

/* Ten sam wzorzec czytelności co .size-option:has(input:checked) wyżej —
   grubsza ramka (nie tylko ciemniejsza) + pogrubiony tekst, więc stan
   wybrany czyta się też bez rozróżniania koloru. */
.option-tile:has(input:checked) {
	border-width: 2px;
	border-color: var(--color-green-700);
	background: var(--color-green-100);
}

.option-tile:has(input:focus-visible) {
	box-shadow: 0 0 0 3px var(--color-green-700);
}

.option-tile__label {
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--color-ink);
}

.option-tile:has(input:checked) .option-tile__label {
	font-weight: 700;
}

/* ---------- "Stwórz Swoją" — wybór składników ---------- */
.pizza-builder {
	border: 1.5px solid var(--color-cream-line);
	border-radius: var(--radius-md);
	background: var(--color-cream-soft);
	overflow: hidden;
}

.pizza-builder__toggle {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: var(--space-2xs) var(--space-sm);
	width: 100%;
	min-height: 44px;
	padding: 0.7em 0.9em;
	background: none;
	border: none;
	cursor: pointer;
	text-align: left;
}

.pizza-builder__toggle-text {
	font-weight: 600;
	font-size: 0.9rem;
	color: var(--color-ink);
}

.pizza-builder__toggle-count {
	font-size: 0.78rem;
	font-weight: 600;
	color: var(--color-green-700);
	margin-left: auto;
}

.pizza-builder__chevron {
	width: 18px;
	height: 18px;
	flex-shrink: 0;
	color: var(--color-green-700);
	transition: transform var(--dur-fast) var(--ease-out);
}

.pizza-builder__toggle[aria-expanded="true"] .pizza-builder__chevron {
	transform: rotate(180deg);
}

.pizza-builder__panel {
	padding: 0 0.9em 0.9em;
	display: flex;
	flex-direction: column;
	gap: var(--space-xs);
}

.pizza-builder__base {
	font-size: 0.78rem;
	color: var(--color-text-muted);
}

.pizza-builder__grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--space-2xs);
}

@media (max-width: 480px) {
	.pizza-builder__grid {
		grid-template-columns: 1fr;
	}
}

.topping-option {
	display: flex;
	align-items: center;
	gap: 0.5em;
	min-height: 44px;
	padding: 0.5em 0.7em;
	border: 1.5px solid var(--color-cream-line);
	border-radius: var(--radius-sm);
	background: var(--color-white);
	cursor: pointer;
	transition: border-color var(--dur-fast) var(--ease-out), border-width var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
}

.topping-option:has(input:checked) {
	border-width: 2px;
	border-color: var(--color-green-700);
	background: var(--color-green-100);
}

.topping-option:has(input:focus-visible) {
	box-shadow: 0 0 0 3px var(--color-green-700);
}

.topping-option:has(input:disabled:not(:checked)) {
	opacity: 0.45;
	cursor: not-allowed;
}

.topping-option input {
	accent-color: var(--color-green-700);
	flex-shrink: 0;
	width: 1.2em;
	height: 1.2em;
}

.topping-option__label {
	font-size: 0.85rem;
	font-weight: 500;
	color: var(--color-ink);
}

.topping-option:has(input:checked) .topping-option__label {
	font-weight: 700;
}

.pizza-builder__limit-note {
	font-size: 0.8rem;
	font-weight: 600;
	color: var(--color-green-700);
}

.pizza-builder__confirm {
	display: flex;
	align-items: flex-start;
	gap: 0.6em;
	padding: 0.75em 0.85em;
	background: var(--color-cream-deep);
	border-radius: var(--radius-sm);
	font-size: 0.8rem;
	color: var(--color-ink);
	cursor: pointer;
}

.pizza-builder__confirm input {
	accent-color: var(--color-green-700);
	flex-shrink: 0;
	width: 1.2em;
	height: 1.2em;
	margin-top: 0.15em;
}

/* ---------- Pizza pół na pół ---------- */
.half-half {
	border: 1.5px solid var(--color-cream-line);
	border-radius: var(--radius-md);
	background: var(--color-cream-soft);
	padding: 0.7em 0.9em;
}

.half-half__toggle {
	display: flex;
	align-items: center;
	gap: 0.6em;
	min-height: 44px;
	font-weight: 600;
	font-size: 0.9rem;
	color: var(--color-ink);
	cursor: pointer;
}

.half-half__toggle input {
	accent-color: var(--color-green-700);
	flex-shrink: 0;
	width: 1.2em;
	height: 1.2em;
}

/* Zwijanie/rozwijanie panelu drugiej połowy — czysty CSS (ten sam
   wzorzec :has() co .size-option/.topping-option wyżej), działa
   identycznie z JS (assets/js/half-half.js, wyłącznie podgląd ceny) i
   bez niego. */
.half-half__panel {
	display: none;
	flex-direction: column;
	gap: var(--space-xs);
	margin-top: var(--space-xs);
}

.half-half:has(input:checked) .half-half__panel {
	display: flex;
}

.half-half__first {
	font-size: 0.85rem;
	color: var(--color-text-muted);
}

.half-half__second {
	display: flex;
	flex-direction: column;
	gap: 0.3em;
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--color-ink);
}

.half-half__second select {
	min-height: 44px;
	padding: 0.5em 0.6em;
	border: 1.5px solid var(--color-cream-line);
	border-radius: var(--radius-sm);
	background: var(--color-white);
	font-size: 0.85rem;
	font-weight: 400;
}

.half-half__price {
	font-size: 0.85rem;
	color: var(--color-green-700);
}

/* Warzywo do połowy Kebab (użytkownik, 2026-08) — celowo NIE reużywa
   klas .pizza-extras__kebab* niżej: te są ukrywane przez
   :has(input[name="polnapol"]:checked) (pół na pół nigdy nie ma
   dodatków/warzywa CAŁEJ pizzy), a to pole ma robić dokładnie
   odwrotnie — pokazywać się, gdy "Pół na pół" jest zaznaczone. Te same
   wartości wizualne (padding/border/font), inna nazwa klasy. */
.half-half__kebab-vegetable {
	display: flex;
	flex-direction: column;
	gap: 0.3em;
	margin-top: var(--space-xs);
}

/* Wariant "second" jest chowany/pokazywany przez atrybut `hidden`
   (assets/js/half-half.js, updateSecondHalfKebabVegetable()) — bez tej
   reguły `display: flex` wyżej zawsze wygrywałoby z domyślnym stylem
   przeglądarki dla [hidden] i pole zostawałoby widoczne bez względu na
   to, którą pizzę klient wybierze jako drugą połowę. */
.half-half__kebab-vegetable[hidden] {
	display: none;
}

.half-half__kebab-vegetable-label {
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--color-ink);
}

.half-half__kebab-vegetable select {
	min-height: 44px;
	padding: 0.5em 0.6em;
	border: 1.5px solid var(--color-cream-line);
	border-radius: var(--radius-sm);
	background: var(--color-white);
	font-size: 0.85rem;
}

/* ---------- Dodatkowe składniki (płatne dodatki) ---------- */
.pizza-extras__kebab {
	display: flex;
	flex-direction: column;
	gap: 0.3em;
	margin-top: var(--space-xs);
}

.pizza-extras__kebab-label {
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--color-ink);
}

.pizza-extras__kebab select {
	min-height: 44px;
	padding: 0.5em 0.6em;
	border: 1.5px solid var(--color-cream-line);
	border-radius: var(--radius-sm);
	background: var(--color-white);
	font-size: 0.85rem;
}

/*
 * Audyt UX 2026-08 — zwinięta domyślnie za natywnym <details>/<summary>
 * (mniej ciężka wizualnie niż zawsze-rozwinięta lista; ten sam podział
 * na "toggle" + "panel" co .pizza-builder wyżej, tyle że bez JS na samo
 * otwieranie/zamykanie — przeglądarka robi to sama).
 */
.pizza-extras {
	border: 1.5px solid var(--color-cream-line);
	border-radius: var(--radius-md);
	background: var(--color-cream-soft);
	margin-top: var(--space-xs);
	overflow: hidden;
}

.pizza-extras__toggle {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: var(--space-2xs) var(--space-sm);
	width: 100%;
	min-height: 44px;
	padding: 0.7em 0.9em;
	cursor: pointer;
	list-style: none;
}

.pizza-extras__toggle::-webkit-details-marker {
	display: none;
}

.pizza-extras__toggle-text {
	font-weight: 600;
	font-size: 0.9rem;
	color: var(--color-ink);
}

.pizza-extras__toggle-count {
	font-size: 0.78rem;
	font-weight: 600;
	color: var(--color-green-700);
	margin-left: auto;
}

.pizza-extras__chevron {
	width: 18px;
	height: 18px;
	flex-shrink: 0;
	color: var(--color-green-700);
	transition: transform var(--dur-fast) var(--ease-out);
}

.pizza-extras[open] .pizza-extras__chevron {
	transform: rotate(180deg);
}

.pizza-extras__panel {
	padding: 0 0.9em 0.9em;
	display: flex;
	flex-direction: column;
	gap: var(--space-xs);
}

/* Audyt UX 2026-08 (poprawka #2) — auto-fit/minmax zamiast sztywnego
   repeat(2, 1fr): dwie kolumny zostają dokładnie wtedy, gdy kafelek ma
   realnie dość miejsca (min. 140px — empirycznie zmierzone razem ze
   zmniejszonym paddingiem/gapem/checkboxem/fontem niżej: prawdziwe
   minimum to 130px, żeby zmieściło się bez zawijania najdłuższe
   pojedyncze słowo w whiteliście, "konserwowy" z "Ogórek
   konserwowy" — 140px zostawia 10px zapasu) na nazwę bez łamania
   słowa w środku; gdy karta jest węższa (np. wąskie okno przeglądarki
   w okolicy przełomu siatki kart z 2 na 3 kolumny, ok. 1024-1300px),
   lista sama, płynnie przechodzi na 1 kolumnę — bez dodatkowego
   media-query, niezależnie od tego, w ilu kolumnach renderują się
   same karty pizzy. minmax(max(140px, calc((100% - gap)/2 - 1px)),
   1fr) to standardowa technika ograniczenia auto-fit do MAKSYMALNIE
   2 kolumn (bez niej auto-fit dokładałby 3+ kolumny na bardzo
   szerokiej karcie, np. gdy siatka kart ma tylko 1 kolumnę na wąskim
   viewport — sama karta wtedy jest pełnej szerokości i dałaby miejsce
   na więcej niż 2 kafelki); "-1px" to margines na zaokrąglenia
   subpikselowe przeglądarki dokładnie na granicy 2/1 kolumny. Poniższy
   @media 480px zostaje jako jawna, zawsze pewna dolna granica dla
   telefonów (auto-fit i tak już by to zrobił, to tylko druga linia
   obrony). */
.pizza-extras__list {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(max(140px, calc((100% - var(--space-2xs)) / 2 - 1px)), 1fr));
	gap: var(--space-2xs);
}

@media (max-width: 480px) {
	.pizza-extras__list {
		grid-template-columns: 1fr;
	}
}

/* Audyt UX 2026-08 — grid zamiast flex: kolumna nazwy (minmax(0,1fr))
   może się zawijać do kilku linii, a kolumna ceny (auto) zawsze
   dostaje dokładnie tyle miejsca ile potrzebuje jej treść i nigdy nie
   jest ściskana przez sąsiada — w przeciwieństwie do flexa, gdzie długa
   nazwa (np. "Mięso wołowo-wieprzowe") potrafiła wypchnąć/ścisnąć cenę
   poza kafelek. Padding/gap lekko zmniejszone (poprawka #2, 2026-08)
   względem pierwszej wersji, żeby zostawić więcej miejsca kolumnie
   nazwy przy 2 kolumnach na typowych szerokościach desktopu. */
.pizza-extras__item {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: center;
	gap: 0.2em;
	min-height: 44px;
	padding: 0.45em 0.2em;
	border: 1.5px solid var(--color-cream-line);
	border-radius: var(--radius-sm);
	background: var(--color-white);
	cursor: pointer;
	transition: border-color var(--dur-fast) var(--ease-out), border-width var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}

.pizza-extras__item:has(input:checked) {
	border-width: 2px;
	border-color: var(--color-green-700);
	background: var(--color-green-100);
}

.pizza-extras__item:has(input:focus-visible) {
	box-shadow: 0 0 0 3px var(--color-green-700);
}

.pizza-extras__item input {
	accent-color: var(--color-green-700);
	width: 0.95em;
	height: 0.95em;
}

/* minmax(0,1fr) na kolumnie nadrzędnej pozwala tekstowi się zawijać
   zamiast rozpychać grid poza szerokość kafelka (ten sam wzorzec co
   .allergen-notice__body wyżej) — dłuższe nazwy (np. "Ogórek
   konserwowy") przechodzą do 2 linii zamiast ściskać cenę. Celowo BEZ
   overflow-wrap: anywhere (audyt UX 2026-08, poprawka #2 — pierwsza
   wersja z "anywhere" łamała słowa w środku, np. "Papryk/a" — źle
   wizualnie). Łamanie tylko na spacjach/myślnikach (domyślne
   zachowanie przeglądarki, sprawdzone: hyphens:auto nic tu nie daje —
   Chromium nie ma słownika dzielenia wyrazów dla polskiego);
   auto-fit/minmax(140px,…) na .pizza-extras__list wyżej gwarantuje,
   że kolumna nazwy ma zawsze dość miejsca na najdłuższe pojedyncze
   słowo w whiteliście (np. "konserwowy"), więc to bezpieczne. */
.pizza-extras__item-label {
	font-size: 0.78rem;
	font-weight: 500;
	color: var(--color-ink);
	line-height: 1.25;
}

.pizza-extras__item:has(input:checked) .pizza-extras__item-label {
	font-weight: 700;
}

/* Kolumna "auto" w .pizza-extras__item nigdy nie jest ściskana przez
   sąsiednią kolumnę nazwy — szerokość zawsze dopasowana do treści ceny,
   nigdy mniejsza. white-space: nowrap dodatkowo pilnuje, żeby "+7 zł"
   nie złamało się na dwie linie. */
.pizza-extras__item-price {
	font-size: 0.7rem;
	font-weight: 600;
	color: var(--color-green-700);
	white-space: nowrap;
	justify-self: end;
}

.pizza-extras__summary {
	font-size: 0.8rem;
	color: var(--color-ink);
	padding: 0.6em 0.7em;
	background: var(--color-cream-deep);
	border-radius: var(--radius-sm);
}

/* Dodatkowe składniki NIE dotyczą pół na pół (decyzja użytkownika,
   2026-08) — ten sam :has() wzorzec co pokazywanie/chowanie
   .half-half__panel wyżej: gdy klient zaznaczy "Pół na pół" na TEJ
   samej karcie, sekcja dodatków (i wybór warzywa Kebaba, jeśli to karta
   Kebaba) znika, zero JS potrzebne. Czysto kosmetyczne — serwer i tak
   nigdy nie czyta/nie nalicza dodatków dla pozycji pół na pół
   (inc/cart.php), niezależnie od tego, co ten formularz pokazał. */
.order-card__form:has(input[name="polnapol"]:checked) .pizza-extras,
.order-card__form:has(input[name="polnapol"]:checked) .pizza-extras__kebab {
	display: none;
}

/* ---------- Qty + add-to-cart row ---------- */
.order-card__row {
	display: flex;
	align-items: center;
	gap: var(--space-2xs);
}

.qty-field input {
	width: 4.2em;
	min-height: 44px;
	padding: 0.6em 0.5em;
	border: 1.5px solid var(--color-cream-line);
	border-radius: var(--radius-sm);
	background: var(--color-white);
	text-align: center;
}

.qty-field--sm input {
	width: 3.6em;
	padding: 0.45em 0.4em;
}

/* ETAP 17E (§6) — .btn--sm's own global padding (components.css,
   ETAP 17C) renders under the 44px touch-target guideline; scoped fix
   here (this exact context only) rather than changing .btn--sm itself,
   which is used in places outside this purchase flow. */
.order-card__row .btn {
	flex: 1;
	min-height: 44px;
	white-space: nowrap;
}

.order-card__price {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: 1.05rem;
	color: var(--color-green-700);
	white-space: nowrap;
}

/* ---------- Napoje (compact rows with add-to-cart) ---------- */
.drink-order-grid {
	display: flex;
	flex-direction: column;
	gap: var(--space-2xs);
}

.drink-order-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-sm);
	padding: var(--space-sm) var(--space-md);
	background: var(--color-cream-soft);
	border-radius: var(--radius-sm);
}

.drink-order-row__name {
	font-weight: 500;
	flex: 1;
	min-width: 180px;
}

.drink-order-row__price {
	font-family: var(--font-display);
	font-weight: 600;
	color: var(--color-green-700);
	white-space: nowrap;
}

.drink-order-row__form {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--space-2xs);
}

.drink-order-row__unavailable {
	color: var(--color-text-muted);
	font-size: var(--fs-small);
	font-style: italic;
}

/* Wybór wariantu napoju (inc/drinks.php, użytkownik 2026-08) — audyt UI
   2026-08: poprzednio zwykły <select> (.drink-order-row__variant, usunięty
   niżej), teraz współdzielony komponent .option-select/.option-tile (patrz
   wyżej, sekcja "Wymagana opcja produktu") — te same kafelki co "Z
   wędliną"/"Batat Crunch", zero duplikacji wyglądu. .drink-order-row__form
   jest poziomym flexem (nazwa+cena+wybór+ilość+przycisk w jednym gęstym
   wierszu) — .option-select dostaje pełną szerokość wiersza zamiast kurczyć
   się do minimalnej treści obok stepera ilości/przycisku, żeby kafelki
   miały gdzie oddychać i nigdy nie ryzykowały nierównego zawinięcia. */
.drink-order-row__form .option-select {
	flex-basis: 100%;
}

/* Zestaw Coca-Cola (4 warianty) — jedyny w motywie przypadek z 4 opcjami:
   generyczny fallback .option-select (@340px -> 1 kolumna) zostawiłby 4
   kafelki ściśnięte w jednym rzędzie aż do bardzo wąskich ekranów. Zamiast
   tego: jawny układ 2×2 poniżej 600px — nigdy 3+1, nigdy nierówne
   szerokości, tekst "Coca-Cola Zero" (najdłuższa etykieta w komponencie) ma
   dość miejsca. data-tivoli-option-count (obok --tivoli-option-count) to
   generyczny hak w markupie, nieprzywiązany do napojów — każdy przyszły
   4-opcjowy produkt korzysta z tej samej reguły. Selektor z atrybutem jest
   specyficzniejszy niż sam .option-select, więc wygrywa z regułą @340px
   niezależnie od kolejności w pliku. Lipton (3 warianty) celowo bez zmian —
   już sprawdzone zachowanie (3 kolumny -> 1 kolumna @340px) w pełni
   wystarcza.

   min-height na kafelkach (nie tylko na .option-select) jest tu celowo: CSS
   Grid z auto-rows liczy wysokość KAŻDEGO rzędu z osobna z jego własnej
   zawartości — "Coca-Cola Zero" (jedyna etykieta w całym komponencie, która
   może się zawinąć do 2 linii przy 2 kolumnach) inaczej rozciągnęłaby tylko
   swój własny rząd (align-items: stretch działa per-rząd), a drugi rząd
   (Fanta/Sprite) zostałby niższy — górny i dolny rząd 2×2 różniłyby się
   wysokością. Wspólny min-height na wszystkich 4 kafelkach naraz gwarantuje
   identyczną wysokość całego bloku 2×2, niezależnie od tego, który kafelek
   faktycznie się zawinął. */
@media (max-width: 600px) {
	.option-select[data-tivoli-option-count="4"] {
		grid-template-columns: repeat(2, 1fr);
	}

	.option-select[data-tivoli-option-count="4"] .option-tile {
		min-height: 60px;
	}
}

@media (max-width: 480px) {
	.drink-order-row__name {
		min-width: 100%;
	}
}
