/* VidFlow — Responsive Foundation (mobile-first)
   Breakpointy: 360 / 430 / 768 / 1024 / 1280
   Filozofia: utility classes + globalne fixy mobile (<768).
   Nie nadpisuje desktop ≥768px (hard guard: wszystkie reguły w @media max-width: 767.98px). */

/* ============================================================
   GLOBAL LAYOUT JITTER FIX (Faza 7b 2026-05-28)
   Reserve scrollbar gutter so content nie reflows gdy modal otwiera/zamyka,
   gdy dynamiczne treści zmieniają wysokość strony, lub gdy iframe (EULA)
   ładuje się asynchronicznie. overflow-y:scroll wymusza widoczność trackera
   na browserach które ignorują scrollbar-gutter (Safari <16, starsze WebKit).
   Bez tego CTAs i logo "skaczą" o ~15px gdy treść rośnie / kurczy się.
   ============================================================ */
html {
    scrollbar-gutter: stable;
    overflow-y: scroll;
}

/* ============================================================
   GLOBALNE FIXY MOBILE (<768px)
   ============================================================ */
@media (max-width: 767.98px) {
    /* Hard guard przeciw poziomemu scrollowi całej strony */
    html, body {
        overflow-x: hidden;
        max-width: 100vw;
    }

    /* Mobile-audit 2026-06-02: flex item w body (display:flex column) z domyślnym
       min-width: auto rozpychał main.container do intrinsic content width (924px+
       na iPhone 13 viewport 390). Override min-width:0 pozwala flex shrink poniżej
       content-min, max-width:100vw ucina hard. To NIE jest overflow-x:hidden trick
       (ukrywa pasek, nie zmienia layout) — to fix layoutu samego.

       Apple Safari + WebKit: bez tego scrollWidth > innerWidth nawet z
       overflow-x:hidden, bo overflow:hidden tylko clipuje wizualnie, content
       wciąż rozpycha layout. */
    body > main,
    body > main.container,
    .container {
        min-width: 0;
        max-width: 100vw;
    }

    /* Wide-content sections — page-level wrappers nie mogą rozpychać poza viewport.
       Children mają max-width: 100% żeby cascade działał, ale per-template overrides
       (np. img max-content) możliwe przez !important albo bardziej specyficzny selector. */
    main.container > *,
    .container > *,
    .page-home,
    .page-home > * {
        max-width: 100%;
        min-width: 0;
    }

    /* Media i tabele nigdy nie wypadają poza viewport */
    img, video, table, iframe, canvas, svg {
        max-width: 100%;
        height: auto;
    }

    /* Tabele bez scroll wrappera dostają kontrolowany overflow */
    table {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Modale i overlaye nie szersze/wyższe niż viewport */
    .confirm-overlay > *,
    .acct-modal,
    .research-modal-overlay > *,
    .modal,
    [role="dialog"] {
        max-width: calc(100vw - 32px) !important;
        max-height: calc(100vh - 64px) !important;
        overflow-y: auto;
    }

    /* Container padding mniejszy na mobile */
    .container {
        padding-left: var(--sp4);
        padding-right: var(--sp4);
    }

    /* Auth container (login/register/forgot-password): max-width 420 + width 100%
       teoretycznie OK, ale .auth-page jest flex z align-items:center co tworzy item
       z domyślnym min-width:auto. Symptom: body_sw 460-514 na 320/390/428 viewport.
       Override min-width:0 + dodatkowy max-width:100vw na samym .auth-page. */
    .auth-page,
    .auth-container,
    .auth-card {
        min-width: 0;
        max-width: 100vw;
    }

    /* Decoracyjne pseudo-elementy (gradient blobs) używają fixed-width 600px lub
       więcej co rozpycha document.scrollWidth na mobile (np. auth-page::before
       width:600 → scrollWidth 495 na iPhone 13 390). overflow:hidden na parent
       NIE clip ::before w scrollWidth measure. Cap pseudo na 100vw. */
    .auth-page::before,
    .page-home .hero::before {
        max-width: 100vw;
        max-height: 100vw;
    }
}

/* iOS dynamic viewport (notch + URL bar): replace 100vh with 100dvh dla auth-page
   żeby content nie był chowany pod home indicator bar. Progressive enhancement:
   pierwsza linia 100vh = fallback dla pre-iOS 15.4 / pre-Chrome 108, druga 100dvh
   nadpisuje na nowszych browsersach (CSS cascade odrzuca invalid value). */
.auth-page {
    min-height: 100vh;
    min-height: 100dvh;
}

/* ============================================================
   UTILITY CLASSES
   ============================================================ */

/* Pokaż tylko mobile (<768) — symetryczny pattern z .hide-mobile */
.show-mobile { display: none; }
@media (max-width: 767.98px) {
    .show-mobile { display: revert; }
}

/* Ukryj na mobile (<768) */
@media (max-width: 767.98px) {
    .hide-mobile { display: none !important; }
}

/* Stack-mobile: kolumna <768, oryginalny layout ≥768 */
@media (max-width: 767.98px) {
    .stack-mobile {
        flex-direction: column !important;
        align-items: stretch !important;
    }
    .stack-mobile > * {
        width: 100%;
    }
}

/* Horizontal scroll wrapper (chips, tabs) */
.scroll-x-mobile {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
}
.scroll-x-mobile::-webkit-scrollbar { height: 4px; }
.scroll-x-mobile::-webkit-scrollbar-thumb { background: var(--bdr2); border-radius: 2px; }
@media (max-width: 767.98px) {
    .scroll-x-mobile {
        scroll-snap-type: x proximity;
        flex-wrap: nowrap !important;
    }
    .scroll-x-mobile > * {
        flex: 0 0 auto;
        scroll-snap-align: start;
    }
}

/* Responsive grid: 1 col <768, 2 col 768-1023, 3 col ≥1024 */
.responsive-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--sp4);
}
@media (min-width: 768px) {
    .responsive-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
    .responsive-grid { grid-template-columns: repeat(3, 1fr); }
}

/* Sticky bottom CTA na mobile (Continue/Submit) */
@media (max-width: 767.98px) {
    .sticky-bottom-cta {
        position: sticky;
        bottom: 0;
        z-index: 50;
        padding: var(--sp3) var(--sp4);
        margin-left: calc(-1 * var(--sp4));
        margin-right: calc(-1 * var(--sp4));
        background: linear-gradient(180deg, transparent 0%, var(--bg) 30%);
        border-top: 1px solid var(--bdr);
        backdrop-filter: blur(8px);
    }
    .sticky-bottom-cta > * {
        width: 100%;
    }
    .sticky-bottom-cta .btn-primary,
    .sticky-bottom-cta button[type="submit"] {
        width: 100%;
        min-height: 48px;
    }
}

/* Full bleed mobile (karta wychodzi do krawędzi viewport) */
@media (max-width: 767.98px) {
    .full-bleed-mobile {
        margin-left: calc(-1 * var(--sp4));
        margin-right: calc(-1 * var(--sp4));
        border-radius: 0;
    }
}

/* Form stack mobile: każdy direct child = 100% width, grid columns reset */
@media (max-width: 767.98px) {
    .mobile-form-stack {
        display: flex !important;
        flex-direction: column !important;
        gap: var(--sp3);
    }
    .mobile-form-stack > * {
        width: 100% !important;
        grid-column: 1 / -1 !important;
        max-width: 100%;
    }
    .mobile-form-stack input,
    .mobile-form-stack textarea,
    .mobile-form-stack select {
        width: 100%;
        min-height: 44px; /* touch target */
        font-size: 16px;  /* iOS zoom prevention */
    }
}

/* ============================================================
   WIZARD (/projects/new) — mobile overrides (<768px)
   ============================================================ */
@media (max-width: 767.98px) {
    /* Stepper poziomo scrollowany — natywny scrollbar ukryty wizualnie, scroll wciąż działa */
    .wizard-stepper {
        overflow-x: auto;
        flex-wrap: nowrap !important;
        /* Mobile-audit 2026-06-02: stepper był wider niż parent wizard-header
           (382 vs 288 na iPhone SE) bo flex item default min-width:auto = content min.
           Force max-width:100% + min-width:0 żeby overflow-x:auto faktycznie scroll-trapował. */
        max-width: 100%;
        min-width: 0;
        scroll-snap-type: x proximity;
        -webkit-overflow-scrolling: touch;
        gap: var(--sp2) !important;
        padding-bottom: var(--sp2);
        scrollbar-width: none;        /* Firefox */
        -ms-overflow-style: none;     /* IE10+ */
    }
    .wizard-stepper::-webkit-scrollbar {
        display: none;                /* Chrome/Safari/Opera */
    }
    .wizard-stepper > * {
        flex: 0 0 auto;
        scroll-snap-align: start;
    }

    /* Format cards (step 1) — mobile layout:
       - Niewybrana: row (mini-mockup pionowy/poziomy 9:16 lub 16:9 z lewej + nazwa/cena prawa)
       - Wybrana (.sel): rozwija się o opis, specs, platforms, tier-picker
       - Klik = selFormat() w new_project.js dodaje klasę .sel */
    .grid-short {
        flex-direction: column !important;
        gap: var(--sp2) !important;
        align-items: stretch !important;
    }
    .phone,
    .screen {
        flex: 1 1 100% !important;
        width: 100% !important;
        max-width: 100% !important;
        height: auto !important;
        min-height: 100px !important;
        aspect-ratio: auto !important;
        padding: var(--sp3) !important;
        box-sizing: border-box;
        display: flex !important;
        flex-direction: row !important;
        flex-wrap: wrap;
        align-items: center;
        gap: var(--sp3) !important;
    }
    /* Mini phone/screen mockup z lewej (9:16 dla SHORT, 16:9 dla LONG).
       Z labelką proporcji w środku — subtelny visual cue zamiast pustego placeholdera. */
    .phone-default {
        display: flex !important;
        position: relative !important;
        flex: 0 0 60px !important;
        width: 60px !important;
        height: 96px !important;
        background: linear-gradient(175deg, var(--elev), var(--bg)) !important;
        border: 1px solid rgba(var(--acc-rgb), 0.25) !important;
        border-radius: var(--radius-sm) !important;
        overflow: hidden;
        align-items: center;
        justify-content: center;
    }
    .phone-default::after {
        content: '9:16';
        font-family: var(--mono);
        font-size: var(--fs-xs);
        color: rgba(var(--acc-rgb), 0.8);
        letter-spacing: 0.05em;
        font-weight: 700;
        background: none;
        position: static;
        width: auto;
        height: auto;
        opacity: 1;
        top: auto;
        right: auto;
    }
    .screen-default {
        display: flex !important;
        position: relative !important;
        flex: 0 0 96px !important;
        width: 96px !important;
        height: 54px !important;
        background: linear-gradient(175deg, #141230, var(--bg)) !important;
        border: 1px solid rgba(59, 130, 246, 0.25) !important;
        border-radius: var(--radius-sm) !important;
        overflow: hidden;
        align-items: center;
        justify-content: center;
    }
    .screen-default::after {
        content: '16:9';
        font-family: var(--mono);
        font-size: var(--fs-xs);
        color: rgba(59, 130, 246, 0.8);
        letter-spacing: 0.05em;
        font-weight: 700;
        position: static;
        width: auto;
        height: auto;
        opacity: 1;
        background: none;
        top: auto;
        right: auto;
    }
    /* Ukrywamy CAŁĄ zawartość mockupu (zostaje tylko ramka+gradient = wskazówka proporcji 9:16/16:9) */
    .phone-default > *,
    .screen-default > *,
    .phone-glow,
    .screen-glow,
    .phone-bottom-mini,
    .screen-bottom-mini,
    .screen-name-mini,
    .screen-progress,
    .long-tier-picker {
        display: none !important;
    }
    /* Overlay = info po prawej stronie mockupu (flex-grow do końca karty) */
    .phone-overlay,
    .screen-overlay {
        position: static !important;
        opacity: 1 !important;
        background: transparent !important;
        padding: 0 !important;
        flex: 1 1 0 !important;
        min-width: 0 !important;
        display: flex !important;
        flex-direction: column !important;
        gap: var(--sp1) !important;
        justify-content: center !important;
        pointer-events: auto !important;
    }
    .ov-top {
        display: flex !important;
        flex-direction: column !important;
        gap: 2px;
    }
    .ov-bottom {
        display: flex !important;
        flex-direction: column !important;
        gap: var(--sp1);
    }
    .ov-name,
    .sov-name {
        font-size: var(--fs-xl) !important;
        margin: 0 !important;
        line-height: 1.2 !important;
    }
    /* Niewybrana karta: chowamy desc, badge, plats, tier-picker (kompakt).
       Specs (czas) widoczne w jednej linii pod nazwą — najważniejsza info. */
    .ov-desc,
    .ov-badge,
    .ov-plats,
    .sov-desc,
    .sov-badge,
    .sov-plats,
    .tier-picker,
    .long-tier-picker {
        display: none !important;
    }
    /* Specs (czas) — single line pod nazwą, mała czcionka */
    .ov-specs,
    .sov-specs {
        display: flex !important;
        flex-direction: row !important;
        flex-wrap: nowrap;
        gap: var(--sp2);
        font-size: var(--fs-xs) !important;
        color: var(--txt2);
        margin: 0 !important;
        overflow: hidden;
        white-space: nowrap;
    }
    .ov-specs .ov-spec:not(:first-child),
    .sov-specs .sov-spec:not(:first-child) {
        display: none !important;
    }
    .ov-spec,
    .sov-spec {
        font-size: var(--fs-xs) !important;
        gap: 2px;
        align-items: center;
    }
    .ov-spec-icon {
        font-size: var(--fs-xs) !important;
        width: auto !important;
        height: auto !important;
    }
    .ov-spec-val,
    .sov-spec b {
        font-weight: 600;
    }
    /* Screen (LONG) ma sov-left + sov-right strukturę zamiast ov-top/ov-bottom */
    .sov-left,
    .sov-right {
        display: flex !important;
        flex-direction: column !important;
        gap: var(--sp1);
    }
    .ov-price,
    .sov-price {
        display: flex !important;
        align-items: center;
        gap: var(--sp2);
    }
    .ov-price-label,
    .sov-price-label {
        font-size: var(--fs-sm);
        color: var(--txt2);
    }
    .ov-price-right,
    .sov-price-right {
        display: flex !important;
        gap: var(--sp2);
        align-items: center;
    }
    /* WYBRANA karta (.sel): rozwija TYLKO tier-picker (potrzebny do wyboru wariantu).
       Reszta (desc/specs/plats) zostaje schowana — to ozdoby desktop, na mobile szum. */
    .phone.sel,
    .screen.sel {
        align-items: flex-start;
    }
    /* WYBRANA karta: rozwija plats (platformy compact pillsy) + tier-picker (row) */
    .phone.sel .ov-plats,
    .screen.sel .sov-plats {
        display: flex !important;
        flex-wrap: wrap;
        gap: var(--sp1);
        flex-basis: 100%;
        margin-top: var(--sp1);
        font-size: var(--fs-xs);
    }
    .phone.sel .ov-plats .pl,
    .screen.sel .sov-plats .pl {
        font-size: var(--fs-xs) !important;
        padding: 2px var(--sp2) !important;
        gap: 3px;
    }
    .phone.sel .ov-plats .pl svg,
    .screen.sel .sov-plats .pl svg {
        width: 10px;
        height: 10px;
    }

    /* Tier picker compact — row layout zamiast vertical cards (mniej miejsca, łatwy wybór). */
    .phone.sel .tier-picker,
    .screen.sel .tier-picker,
    .screen.sel .long-tier-picker {
        display: flex !important;
        flex-direction: row !important;
        gap: var(--sp1);
        flex-basis: 100%;
        margin-top: var(--sp2);
    }
    .phone.sel .tier-picker .tier-opt,
    .screen.sel .tier-picker .tier-opt,
    .screen.sel .long-tier-picker .tier-opt {
        flex: 1 1 0;
        padding: var(--sp2) !important;
        text-align: center;
        min-width: 0;
    }
    /* Tier description (Szybki, sprawdzony... / Spojniejsza narracja...).
       iPhone 3506 feedback: bez opisu user nie wie ktory wybrac. Pokazujemy
       w kompaktowej formie (smaller font, 2-line clamp z ellipsis). */
    .phone.sel .tier-opt-desc,
    .screen.sel .tier-opt-desc {
        display: -webkit-box !important;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
        text-overflow: ellipsis;
        font-size: 10px !important;
        line-height: 1.3 !important;
        margin-top: 2px !important;
        color: var(--txt2);
        white-space: normal !important;
    }
    .phone.sel .tier-opt-name,
    .screen.sel .tier-opt-name {
        font-size: var(--fs-sm) !important;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* Wizard bottom bar mobile: 2-rzędowy layout zamiast flex-wrap chaos.
       Row 1: progress (Krok X z Y + step name + Boosted badge)
       Row 2: Wstecz | cena | Dalej (gradient CTA)
       .wizard-nav globalnie ukryty w style.css:1546 — aktywny CTA to .bottom-bar-wrap.
       iPhone iteracja 3: zwiekszylismy uzyteczna przestrzen — full bleed (margin:0),
       mniejszy padding (sp1/sp2), mniejszy font na progress => mniej ellipsis. */
    .bottom-bar-wrap {
        padding: 0 !important;
    }
    .bottom-bar-anchor {
        width: 100% !important;
        max-width: 100% !important;
        justify-content: stretch !important;
    }
    /* iPhone iteracja 5 user feedback: poprzedni 2-row layout dawal akcjom
       (Wstecz | cena | Dalej) caly drugi rzad full-width, a progress (Krok X z Y +
       step) tylko gorny rzad — user czul ze "pasek zajmuje 2/3, kroki tylko 1/3".
       Nowy layout: 1-row 4-col grid. Progress 1fr (rosnie do dostepnej szerokosci,
       czytelny font fs-sm). Wstecz + cena + Dalej auto (kompaktowo). */
    .bottom-bar {
        width: 100% !important;
        display: grid !important;
        grid-template-columns: auto 1fr auto auto !important;
        grid-template-areas: "back progress price next" !important;
        column-gap: var(--sp2) !important;
        row-gap: 0 !important;
        padding: var(--sp1) var(--sp2) !important;
        margin: 0 !important;
        align-items: center;
        box-sizing: border-box;
    }
    /* Hide chaos separators + duplicate info row */
    .bb-sep,
    .bb-info {
        display: none !important;
    }
    /* Progress: 1fr (rosnie do dostepnej szerokosci), font fs-sm (czytelne ale nie XL) */
    .bb-progress {
        grid-area: progress;
        min-width: 0 !important;
        flex-direction: column !important;
        align-items: flex-start !important;
        gap: 1px;
        font-size: var(--fs-xs) !important;
    }
    .bb-progress-text {
        flex: 0 1 auto;
        min-width: 0;
        font-size: var(--fs-sm) !important;
        font-weight: 600;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        max-width: 100%;
    }
    .bb-progress-step,
    .bb-progress-sections {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        font-size: var(--fs-xs) !important;
        max-width: 100%;
    }
    /* Wstecz: kompaktowa strzalka, bez "Wstecz" tekst, minimal padding */
    .bb-back {
        grid-area: back;
        font-size: 0 !important;
        padding: var(--sp1) !important;
        white-space: nowrap;
        min-width: 0 !important;
        min-height: 36px !important;
        line-height: 1;
    }
    .bb-back::before {
        content: '←';
        font-size: 18px;
        color: var(--txt2);
    }
    .bb-right {
        grid-area: next;
        display: contents !important;
    }
    .bb-price {
        grid-area: price;
        justify-self: end;
        align-self: center;
        margin: 0 !important;
    }
    .bb-price .mbt-pill,
    .bb-price .bb-pln {
        font-size: var(--fs-xs) !important;
        padding: 2px 6px !important;
    }
    .bb-btn {
        grid-area: next;
        min-height: 36px !important;
        padding: var(--sp1) var(--sp3) !important;
        font-size: var(--fs-sm) !important;
        white-space: nowrap;
    }

    /* Wszystkie wizard option grids → 1 kolumna na mobile */
    #surprise-topics-grid,
    .mode-grid,
    .mc-grid,
    .ton-grid,
    .reg-grid,
    .source-cards,
    .tempo-cards {
        grid-template-columns: 1fr !important;
        gap: var(--sp2) !important;
    }
    /* Karty wizard (option/source/tempo/filter/overlay): zawsze pełna szerokość */
    .src-card,
    .tempo-card,
    .filter-card,
    .overlay-card,
    .mc-card,
    .ton-card,
    .reg-card {
        max-width: 100% !important;
        width: auto !important;
        box-sizing: border-box;
    }

    /* Sections: mniejszy padding, hidden overflow tylko x */
    .step3-section {
        padding: var(--sp4) !important;
        margin-bottom: var(--sp3);
        overflow-x: hidden;
    }
    /* Bezpieczny anti-overflow: WSZYSTKIE direct children sekcji szerokość ≤ 100%.
       NIE używamy word-break ani max-width na -icon/-img/-info — to psuło text głosu/historii. */
    .step3-section > * {
        max-width: 100%;
        box-sizing: border-box;
    }
    /* Topic history sm-* — grid 2-col stays na desktop, 1-col na mobile bez wymuszania word-break */
    .sm-hist-group {
        grid-template-columns: 1fr !important;
        gap: var(--sp2) !important;
    }
    .sm-topic-card {
        max-width: 100% !important;
        box-sizing: border-box;
    }

    /* Stepper kompakt mobile: 28px circles zamiast 36+, font-size mniejszy */
    .wizard-stepper .step-circle,
    .wizard-stepper [class*="step-num"],
    .wizard-stepper [class*="step-circ"] {
        width: 28px !important;
        height: 28px !important;
        font-size: var(--fs-sm) !important;
    }
    .wizard-stepper [class*="step-label"],
    .wizard-stepper [class*="step-name"] {
        font-size: 10px !important;
        letter-spacing: 0.02em !important;
    }
    .wizard-stepper .step,
    .wizard-stepper [class*="step-item"] {
        gap: 2px !important;
    }

    /* Cost timeline już ma @media(max-width:900px) z relative+full width — OK na mobile */
    .cost-timeline {
        box-shadow: none;
    }

    /* === RESEARCH CARD (step 2 "Oprzyj film na badaniach") — toggle layout fix ===
       Template ma inline style display:flex z gap:16px (icon + content + toggle row).
       Na mobile za wąsko — stack vertical. Toggle/CTA do bottom right. */
    .research-card > div {
        flex-wrap: wrap !important;
        gap: var(--sp3) !important;
    }
    .research-card > div > div:nth-child(2) {
        flex: 1 1 65% !important;
        min-width: 0;
    }
    /* Toggle (label 56x30) lub Upgrade button: zachowuje rozmiar, idzie do prawej */
    .research-card label[style*="56px"],
    .research-card a[href="/buy-credits"] {
        margin-left: auto;
    }

    /* === HISTORIA TEMATÓW (Twoje wcześniejsze tematy) — JS-created grid 2-col → 1-col ===
       JS w new_project.js:1559 ustawia inline style grid-template-columns:repeat(2,1fr).
       !important w external CSS bije inline bez !important. */
    .sm-hist-group > div {
        grid-template-columns: 1fr !important;
    }

    /* === VOICE CARD (step 4 Głos) — flex-wrap żeby tagi schodziły pod info zamiast ściskać tekst ===
       Desktop: .voice-card flex row z .vc-play (56px) + .vc-info (flex 1) + .vc-tags (flex-shrink:0).
       Mobile: tags się wrap pod info, vc-play nieco mniejszy żeby zostawić więcej miejsca tekstowi. */
    .voice-card {
        flex-wrap: wrap !important;
        padding: var(--sp3) var(--sp4) !important;
    }
    .vc-play {
        width: 48px !important;
        height: 48px !important;
    }
    .vc-info {
        flex: 1 1 calc(100% - 64px) !important;
        min-width: 0 !important;
    }
    .vc-name {
        font-size: var(--fs-md) !important;
    }
    .vc-desc {
        overflow-wrap: normal;
        word-break: normal;
    }
    /* Tags row na mobile: flex-basis 100%, schodzi pod info — nie ściska tekstu */
    .vc-tags {
        flex-basis: 100% !important;
        margin-top: var(--sp1);
        flex-shrink: 1 !important;
        flex-wrap: wrap;
    }
    /* Waveform: ukryty na mobile (zajmuje miejsce + zbędna ozdoba) */
    .vc-waveform {
        display: none !important;
    }

    /* === UPLOAD DROPZONE (idea-upload-content "Wgraj plik") — simple mobile card ===
       Desktop: grid 2x2 z icon/fmts po prawej, ozdobne avatar 120x120.
       Mobile: zwykły flex-column card (ikona → tekst → chipy → info), bez grid quirks.
       Stabilny target #upload-dropzone (ID w template:2046). */
    .up-split-single .up-dropzone,
    #upload-dropzone {
        display: flex !important;
        flex-direction: column !important;
        align-items: center !important;
        justify-content: flex-start !important;
        width: 100% !important;
        max-width: 100% !important;
        padding: var(--sp4) var(--sp3) !important;
        gap: var(--sp3) !important;
        text-align: center !important;
        /* grid-template-* properties nie mają efektu gdy display:flex — usunięte jako dead code */
    }
    /* Icon — desktop avatar 120x120, mobile 72x72 (override `:has(.up-dz-icon-img)` !important) */
    .up-split-single .up-dz-icon,
    #upload-dropzone .up-dz-icon,
    .up-split-single .up-dz-icon:has(.up-dz-icon-img),
    #upload-dropzone .up-dz-icon:has(.up-dz-icon-img) {
        width: 72px !important;
        height: 72px !important;
        flex: 0 0 auto !important;
    }
    /* Tekst label/sub centered, full width */
    .up-split-single .up-dz-text,
    #upload-dropzone .up-dz-text,
    .up-split-single .up-dz-info,
    #upload-dropzone .up-dz-info {
        width: 100% !important;
        max-width: 100% !important;
        text-align: center !important;
    }
    .up-split-single .up-dz-label,
    #upload-dropzone .up-dz-label {
        text-align: center !important;
        font-size: var(--fs-lg) !important;
    }
    /* Chipy formatów — flex-wrap poziomo, max-width żeby się nie rozciągały */
    .up-split-single .up-dz-fmts,
    #upload-dropzone .up-dz-fmts {
        display: flex !important;
        flex-wrap: wrap !important;
        justify-content: center !important;
        align-items: center !important;
        gap: 6px !important;
        width: 100% !important;
        max-width: 280px !important;
    }
    .up-split-single .up-dz-fmt,
    #upload-dropzone .up-dz-fmt {
        flex: 0 0 auto !important;
        white-space: nowrap !important;
    }
    .up-split-single .up-dz-info,
    #upload-dropzone .up-dz-info {
        font-size: var(--fs-xs);
        line-height: 1.4;
    }
}

/* ============================================================
   BUY CREDITS (/buy-credits) — mobile overrides (<768px)
   ============================================================ */
@media (max-width: 767.98px) {
    /* Grids pakietów / planów subskrypcji / porównań: 1 kolumna */
    .cost-cards,
    .packs-grid,
    .compare-grid,
    .plans-grid {
        grid-template-columns: 1fr !important;
        gap: var(--sp3) !important;
    }

    /* Mode/segment/cycle togglery: wrap + full width */
    .mode-toggle,
    .sub-toggles,
    .sub-toggle {
        flex-wrap: wrap;
        gap: var(--sp2);
    }
    .mode-toggle > *,
    .sub-toggle > * {
        flex: 1 1 auto;
        min-height: 44px;
    }

    /* Forms (cancel pending change, plan CTA): stack */
    .sub-pending-cancel-form,
    .plan-cta-form {
        display: flex;
        flex-direction: column;
        gap: var(--sp2);
    }
    .plan-cta-form input,
    .plan-cta-form select,
    .plan-cta-form button {
        width: 100%;
        min-height: 44px;
    }
}

/* ============================================================
   PIPELINE STATUS (/projects/<id>) — mobile overrides (<768px)
   iPhone 3511 feedback: karty "rozjechane", "splaszczone", "wychodza poza ekran".
   Strategia: overflow:hidden + max-width:100% + mniejsze padding + flex-wrap header.
   ============================================================ */
@media (max-width: 767.98px) {
    /* Step cards: anti-overflow guard — wszystko zostaje w viewport */
    .step-cards,
    .step-card {
        max-width: 100% !important;
        box-sizing: border-box;
    }
    .step-card {
        overflow: hidden;
    }
    /* Header: mniejszy padding + flex-wrap dla badge/time rzucanych pod tekst */
    .step-header,
    .card-done .step-header {
        padding: 10px 12px !important;
        gap: 8px !important;
        flex-wrap: wrap;
    }
    .step-header-content {
        flex: 1 1 calc(100% - 100px);
        min-width: 0;
        overflow: hidden;
    }
    .step-header-right {
        flex: 0 0 auto;
    }
    /* Done state: mniejsze padding body + done-avatar 64px max (desktop 120+) */
    .card-done .step-body {
        padding: 12px 16px 16px !important;
        gap: 12px !important;
    }
    .card-done .done-layout {
        flex: 1 1 100% !important;
        min-width: 0;
    }
    .card-done .done-avatar,
    .card-done .done-avatar img,
    .step-character,
    .step-character img,
    .step-character svg {
        max-width: 80px !important;
        height: auto !important;
    }
    /* "ZROBIONE" watermark — mniejsze i bliżej krawedzi, nie wycieka poza viewport */
    .step-card.card-done::after {
        font-size: 14px !important;
        right: 12px !important;
        top: 8px !important;
        letter-spacing: 2px !important;
    }
    /* tx-wrap.pilot-scene (running pilot) padding:20px! — za duzo na 360px */
    .step-card .tx-wrap.pilot-scene {
        padding: 12px !important;
    }
    /* Scene container i workspace running: 100% width, brak horiz overflow */
    .scene-container,
    .scene-workspace,
    .scene-hero-area,
    .scene-status-row,
    .scene-status-panel,
    .scene-bottom-bar,
    .scene-download-card,
    .scene-url-bar {
        max-width: 100% !important;
        box-sizing: border-box;
        overflow: hidden;
    }
    /* Persona-trivia card (Pisarz/Lektor avatar+trivia): 100% width */
    .persona-trivia,
    .pt-header,
    .pt-header-link {
        max-width: 100% !important;
        box-sizing: border-box;
    }
    /* Step icon (sic) — zostaje 32x32, ale flex-shrink:0 explicit żeby nie zostalo
       splaszczone gdy flex-wrap zmieni layout headera */
    .sic {
        flex: 0 0 32px !important;
    }
    /* Stc tytul — nie wymuszaj fixed width, pozwol flexowi obliczyc */
    .stc {
        min-width: 0;
        word-break: break-word;
    }
}

/* ============================================================
   HISTORY (/history) — mobile overrides (<768px)
   ============================================================ */
@media (max-width: 767.98px) {
    /* Hero stats row: 1 kolumna stack na mobile */
    .h-hero-stat {
        display: block;
        margin-bottom: var(--sp2);
    }

    /* Toolbar rows: full width + flex column dla searchbar */
    .vf-toolbar-row {
        flex-wrap: wrap !important;
        gap: var(--sp2) !important;
    }
    .vf-toolbar-search-row {
        flex-direction: column;
        align-items: stretch;
    }
    .vf-search {
        width: 100% !important;
    }
    .vf-search input {
        width: 100%;
        font-size: 16px;
    }

    /* Filter tabs: scroll-x horizontal (zachowuje active state) */
    .vf-tabs {
        overflow-x: auto;
        flex-wrap: nowrap !important;
        scroll-snap-type: x proximity;
        -webkit-overflow-scrolling: touch;
        gap: var(--sp1) !important;
        padding-bottom: var(--sp2);
    }
    .vf-tabs > .vf-tab {
        flex: 0 0 auto;
        scroll-snap-align: start;
        white-space: nowrap;
    }

    /* Sort dropdowny: full width row */
    .vf-toolbar-filters-row .vf-sort {
        flex: 1 1 auto;
        min-width: 0;
        font-size: 16px;
    }

    /* Skeleton cards: stack 1 kolumna (uses generic _history_card grid)*/
    .skel {
        width: 100%;
    }
}

/* ============================================================
   TOUCH TARGETS (<768px)
   ============================================================ */
@media (max-width: 767.98px) {
    /* Buttony i linki w nav: min 44px wysokość (Apple HIG).
       Wykluczenia: lang-switcher (intentionally small pill), vfPlayer controls
       (vfp-btn 32x32 okragle, vfp-close 30x30, vfp-overlay-btn 64x64 — min-height:44
       splaszczalo je bo zostawalo width fixed). iPhone 3502 feedback.
       Plus pt-dot (persona-trivia pagination dots 28x4 — min-height:44 robil grube
       prostokaty zamiast cienkich paskow). iPhone 3517 iteracja 2.
       Plus pt-btn (persona-trivia prev/next strzalki 32x32 okragle — min-height:44
       splaszczalo do owalu). iPhone 3517 iteracja 3. */
    .btn,
    button:not(.lang-switcher-btn):not(.vfp-btn):not(.vfp-close):not(.vfp-overlay-btn):not(.pt-dot):not(.pt-btn),
    .nav-btn {
        min-height: 44px;
    }
    /* iPhone 3517 iter 3: persona-trivia controls pasek za szeroki — zmniejsz
       prev/next strzalki z 32 do 28 + mniejszy padding w pt-controls */
    .pt-btn {
        width: 28px !important;
        height: 28px !important;
        font-size: var(--fs-sm) !important;
    }
    .pt-controls {
        padding: var(--sp1) var(--sp2) !important;
    }
    /* Inputy nie powinny wymuszać zoom na iOS (16px = no zoom) */
    input[type="text"],
    input[type="email"],
    input[type="password"],
    input[type="tel"],
    input[type="number"],
    input[type="search"],
    textarea,
    select {
        font-size: 16px;
    }

    /* iPhone 3517 feedback: slider mial "szerokie prostokaty zamiast paskow"
       — iOS Safari ignoruje appearance:none jesli NIE jest na wszystkich
       trzech (input + ::-webkit-slider-runnable-track + ::-webkit-slider-thumb)
       i renderuje natywny gruby thumb. Force-reset globalnie dla wszystkich
       input[type=range] na mobile. */
    input[type="range"] {
        -webkit-appearance: none !important;
        appearance: none !important;
        background: transparent;
    }
    input[type="range"]::-webkit-slider-thumb {
        -webkit-appearance: none !important;
        appearance: none !important;
    }
    input[type="range"]::-webkit-slider-runnable-track {
        -webkit-appearance: none !important;
        appearance: none !important;
    }
}

/* ============================================================
   MULTI-SELECT CHECKBOXES — touch-friendly visibility (<768px)
   iPhone 3522/3523 feedback: history checkbox niewidoczny na mobile bo opacity:0
   default + opacity:1 tylko :hover. Touch devices nie maja hover => checkbox
   nigdy nie pokazuje sie. Library ten sam problem ale tap-show przez browser.
   Fix: @media (hover: none) opacity:1 zawsze + zwiekszony rozmiar dla touch.
   ============================================================ */
@media (hover: none) and (max-width: 767.98px) {
    .h-card-check,
    .lib-player-check,
    .proj-check {
        opacity: 1 !important;
        width: 32px !important;
        height: 32px !important;
        aspect-ratio: 1 / 1 !important;   /* iPhone 3522 iter 2: history widac prostokat zamiast kwadrat — wymuszony 1:1 */
        border-width: 2px !important;
        box-sizing: border-box !important;
    }
    /* Selected check mark scale up dla wiekszego checkbox */
    .card.selected .h-card-check::after,
    .lib-card.selected .lib-player-check::after {
        line-height: 28px !important;
        font-size: 18px !important;
    }
}

/* ============================================================
   ACCOUNT STORAGE MODAL — Dokup miejsce (<768px)
   iPhone 3524 feedback: modal .rb-modal/.rb-addon-modal ma fixed width 520/600px
   => na 360px wystaje za viewport, content sie ucina. Plus .rb-addon-tiers
   grid-template-columns: 1fr 1fr 1fr (3 cols) — pakiety obok siebie.
   Fix: mobile-first override width + tiers 1 col stack.
   ============================================================ */
@media (max-width: 767.98px) {
    .rb-modal,
    .rb-addon-modal {
        width: calc(100vw - 24px) !important;
        max-width: calc(100vw - 24px) !important;
        max-height: calc(100vh - 48px) !important;
    }
    .rb-modal-body {
        overflow-y: auto !important;
        -webkit-overflow-scrolling: touch;
    }
    /* Tiers: 3 cols -> 1 col stack na mobile (kazdy pakiet pelnej szerokosci) */
    .rb-addon-tiers {
        grid-template-columns: 1fr !important;
        gap: var(--sp2) !important;
    }
    /* Cycle toggle (Miesiecznie/Rocznie) flex-wrap zeby sie nie cisnal */
    .rb-addon-cycle {
        flex-wrap: wrap;
        max-width: 100%;
    }
    /* Footer buttons stack column */
    .rb-modal-footer {
        flex-direction: column;
        gap: var(--sp2);
    }
    .rb-modal-btn {
        width: 100%;
    }
}

/* ============================================================
   PIPELINE SCENES MOBILE (status page /projects/{id})
   2026-06-03: follow-up do PR #732. Pisarz (.ps-*) i transkryptor (.tx-*)
   maja inline <style> z `grid-template-columns: 1fr 1fr` (stage + monitor)
   bez mobile media query — na iPhone portrait kontent prawej kolumny
   (EDYTOR SCENARIUSZA panel + bloki + research metrics) wyciekal poza viewport.
   Anchor: user smoke 2026-06-03 23:32 na vidflow.boostitup.pl/projects/{id}
   widget pisarz scene + phases timeline + stats grid (Model/Bloki/Linie/Slowa/Reguly).
   Inne sceny (broll, lektor, monter, muzyk, napisy, ekstraktor, ekstraktor_momentow)
   uzywaja shared pipeline-scenes.css ktory ma juz @media (max-width: 760px)
   override dla 2-col layoutow.
   ============================================================ */
@media (max-width: 767.98px) {
    /* Outer wrapper — mniejszy padding zeby zostalo realne miejsce na kontent */
    .ps-wrap,
    .tx-wrap {
        padding: 16px 8px;
        max-width: 100%;
    }

    /* Stage + monitor → stack pionowo. min-height auto zeby empty avatar nie
       generowal 380px puste przestrzeni. Avatar z aspect-ratio nadal renderuje
       sie poprawnie bo .ps-stage/.tx-stage uzywa aspect-ratio i object-fit. */
    .ps-main,
    .tx-main {
        grid-template-columns: 1fr;
        min-height: auto;
    }

    /* Avatar stage na portrait: ograniczyc wysokosc zeby uzytkownik widzial
       monitor + phases + stats bez dlugiego scrolla.
       Hotfix 2026-06-03: poprzedni `aspect-ratio: 16/10 + min-height: 240px`
       wymuszal width 240*1.6 = 384px co przekraczalo iPhone SE 320 viewport
       (own Playwright proof: +73px overflow on .tx-stage iPhone SE). Usuwam
       aspect-ratio + nadaje width:100% zeby stage NIGDY nie wyciekal poza
       parent. Wysokosc rzadzona przez min-height/max-height tylko, image
       wewnatrz uzywa object-fit:cover. */
    .ps-stage,
    .tx-stage {
        width: 100%;
        max-width: 100%;
        min-width: 0;
        max-height: 50vh;
        min-height: 180px;
        aspect-ratio: auto;
    }
    .ps-stage-img,
    .tx-stage-img {
        width: 100%;
        max-width: 100%;
        object-fit: cover;
    }

    /* Monitor panel border — bylo left-border (z desktopu split 50/50),
       zmiana na top-border bo stack pionowy. */
    .ps-monitor,
    .tx-monitor {
        border-left: none;
        border-top: 1px solid rgba(217, 70, 239, 0.15);
        padding: 12px;
    }

    /* Phases timeline — broll ma dlugie nazwy ("Przygotowanie zapytan",
       "Skanowanie stockow", "Selekcja klipow"). Hotfix: stack 1-col pionowo
       na mobile (zamiast 30%-3-col ktore powodowalo overlap textow na 320-390).
       .tx-phase-sub hidden zeby kompaktowac. */
    .ps-phases,
    .tx-phases {
        flex-direction: column;
        flex-wrap: nowrap;
        padding: 10px 8px;
        gap: 4px;
    }
    .ps-phase,
    .tx-phase {
        flex: 0 0 auto;
        width: 100%;
        min-width: 0;
        padding: 6px 10px;
        font-size: var(--fs-xs);
    }
    .ps-phase-name,
    .tx-phase-name {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        min-width: 0;
    }
    .ps-phase-sub,
    .tx-phase-sub {
        display: none;
    }

    /* Stats bar — broll ma 6 stats, pisarz 5. Hotfix compact mode:
       pokaz tylko 3 najwazniejsze (Zapytan/Znalezione/Wybrane lub
       Model/Bloki/Linie). Reszta `display: none` na mobile (lokalne
       szczegoly dostepne na desktop, mobile to glance-view).
       Letter-spacing zmniejszony do 1px (z 2px) zeby dlugie labele
       jak "ZNALEZIONE" sie zmiescily.

       Kazda scena ma stats w deterministycznym order — pierwsze 3 to
       core metrics. .ps-stat:nth-child(n+4) / .tx-stat:nth-child(n+4)
       ukryte. */
    .ps-stats,
    .tx-stats {
        grid-template-columns: repeat(3, 1fr);
    }
    .ps-stat,
    .tx-stat {
        padding: 8px 6px;
    }
    .ps-stat-label,
    .tx-stat-label {
        letter-spacing: 1px;
        font-size: 10px;
    }
    .ps-stat:nth-child(3),
    .tx-stat:nth-child(3) {
        border-right: none;
    }
    .ps-stat:nth-child(n+4),
    .tx-stat:nth-child(n+4) {
        display: none;
    }

    /* Block grid (#pisarz-script-blocks, b-roll lookups) — dlugie zapytania
       typu "linia 251 - phone hands screen touch smartphone hand using technology"
       NIE moga rozpychac karty. Ellipsis na single-line items, wrap na multi-line. */
    .ps-block-grid,
    .tx-block-grid {
        max-height: 200px;
        overflow-x: hidden;
        word-break: break-word;
        overflow-wrap: break-word;
    }
    .ps-block-grid > *,
    .tx-block-grid > * {
        max-width: 100%;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* Research items (Reguly/Zdjecia/Fakty/Cytaty) — flex-wrap juz jest,
       gap mniejszy zeby zmiescilo sie w wezszej szerokosci */
    .ps-research,
    .tx-research {
        gap: 8px;
        padding: 8px 10px;
    }
}

/* Bardzo waskie viewports (iPhone SE 320px) — dalszy compact:
   stats redukcja do 2 col + jeszcze mniejszy letter-spacing. */
@media (max-width: 380px) {
    .ps-stats,
    .tx-stats {
        grid-template-columns: repeat(2, 1fr);
    }
    .ps-stat-label,
    .tx-stat-label {
        letter-spacing: 0.5px;
        font-size: 9px;
    }
    .ps-stat:nth-child(2),
    .tx-stat:nth-child(2) {
        border-right: none;
    }
    .ps-stat:nth-child(3),
    .tx-stat:nth-child(3) {
        border-top: 1px dashed rgba(155, 151, 184, 0.15);
        border-right: none;
        grid-column: 1 / -1;
    }
    /* :nth-child(n+4) juz `display: none` z parent media query */
}
