/*
 * Making the whole system behave on a phone — iOS especially.
 *
 * Linked LAST on every page so it settles arguments with the older sheets
 * rather than being overridden by them. Everything here is scoped to touch
 * devices or narrow screens, so the desktop rendering is untouched.
 *
 * ─── the auto-zoom ──────────────────────────────────────────────────────────
 *
 * Safari on iOS zooms the page in whenever a focused input has a font smaller
 * than 16px, and there is no way to decline: `user-scalable=no` is ignored on
 * iOS 10+ and disabling zoom would fail WCAG anyway. 37 rules across five
 * stylesheets and 39 inline styles set 12–15px on form controls, which is why
 * tapping almost any field threw the layout sideways. The only real fix is to
 * make the fields 16px on touch devices; they are sized back down visually with
 * padding, not with font-size.
 *
 * ─── the jank ───────────────────────────────────────────────────────────────
 *
 * backdrop-filter is close to free on a desktop GPU and punishing on a phone:
 * every scroll frame re-blurs whatever sits behind the element. Forty of them
 * across the sheets is what makes a long list crawl. Dropped for a solid colour
 * below the tablet breakpoint.
 */

/* ══ 1. never let iOS zoom a form field ══════════════════════════════════ */
@media (hover: none) and (pointer: coarse) {
    input:not([type='checkbox']):not([type='radio']),
    select,
    textarea,
    .form-control,
    .form-input,
    .cashpay__input,
    .vp__select,
    .cbx__input,
    .arc__branch,
    .paypanel__tog {
        /* 16px is the threshold. max() keeps anything deliberately larger. */
        font-size: max(16px, 1rem) !important;
    }

    /* Held to the same rule wherever it was set inline. */
    input[style*='font-size'],
    select[style*='font-size'],
    textarea[style*='font-size'] {
        font-size: max(16px, 1rem) !important;
    }

    /* The fields were sized by their font. Give the height back with padding so
       they look as they did rather than suddenly becoming chunky. */
    input:not([type='checkbox']):not([type='radio']),
    select,
    textarea {
        padding-top: .55em;
        padding-bottom: .55em;
        line-height: 1.25;
    }
}

/* ══ 2. cheaper paint on a phone ═════════════════════════════════════════ */
@media (max-width: 991px) {
    /* A blur behind a scrolling list re-renders every frame. The colours below
       are the same surfaces these elements already had, minus the blur. */
    /* Everything, rather than a list of class names. Chasing them one at a
       time left blurs behind on pages nobody thought to check, and there is no
       element on a phone where a live backdrop blur is worth its frame cost. */
    * {
        backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
    }
}

/* ══ 3. touch behaviour ══════════════════════════════════════════════════ */
@media (hover: none) and (pointer: coarse) {
    /* Removes the 300ms wait Safari keeps for a possible double-tap-to-zoom.
       Every tap on this system felt sluggish because of it. */
    a, button, [role='button'], input[type='submit'], .btn,
    .accordion-button, .collapse-header, .sale-btn, .repair-amend__btn {
        touch-action: manipulation;
    }

    /* Momentum scrolling inside every list. */
    .modal-body, .collapse-content, .cp-list, .pl-report,
    #ordersList, #archivedSales, #archivedRepairs, .table-responsive {
        -webkit-overflow-scrolling: touch;
    }

    /* A sheet OVER the page keeps its scroll to itself: dragging the page
       behind an open modal is how people lose their place in it. */
    .modal-body {
        overscroll-behavior: contain;
    }

    /* A list that is part of the page does NOT. `contain` there means a swipe
       that reaches the end of the list is swallowed instead of passed on, so a
       thumb resting anywhere on a long list cannot move the page at all — the
       tab reads as stuck, and whatever sits above the list (a search box, a
       filter) becomes unreachable without finding a gap beside it. Reported by
       the owner on the PRODUCTS tab, 2026-09-29; these are the same shape. */
    .collapse-content, .cp-list, .pl-report,
    #ordersList, #archivedSales, #archivedRepairs, .table-responsive {
        overscroll-behavior: auto;
    }

    /* A tap target under 44px is hard to hit accurately — Apple's own floor. */
    .sale-btn, .repair-amend__btn, .paypanel__tog, .arc__btn, .btn-close {
        min-height: 44px;
    }

    /* The add-to-cart "+" sits in a tight product tile, and there are hundreds
       of them — growing it to 44px would reflow the whole grid. Instead the
       button keeps its size and an invisible overlay carries the extra reach,
       so the tile looks identical and the thumb still lands on it. */
    .plus-btn {
        position: relative;
    }
    .plus-btn::after {
        content: "";
        position: absolute;
        top: 50%;
        left: 50%;
        width: 44px;
        height: 44px;
        transform: translate(-50%, -50%);
    }
    /* Sold Out is not a target — leave it alone so it cannot steal a tap
       from the tile beside it. */
    .plus-btn.sold-out::after {
        display: none;
    }
}

/* ══ 4. 100vh is wrong on iOS ════════════════════════════════════════════ */
/* Safari counts the address bar in 100vh, so a "full height" panel is always
   taller than the screen and pushes content under the chrome. dvh follows the
   bar as it hides; the vh line stays first as the fallback. */
@supports (height: 100dvh) {
    .modal, .pay-modal, .booking-modal, .full-height, .vh-100 {
        min-height: 100dvh;
    }
}

/* ══ 5. nothing may push the page sideways ═══════════════════════════════ */
@media (max-width: 767px) {
    /* `clip`, not `hidden`, and the order matters.
     *
     * `overflow-x: hidden` makes the element a SCROLL CONTAINER on both axes,
     * and a `position: sticky` child is pinned to its nearest scrolling
     * ancestor — which here is a body that never scrolls, because the page
     * scrolls on <html>. So every sticky bar on the shop front silently did
     * nothing: the search wrapper was declared sticky and still scrolled clean
     * off the top. `clip` cuts the overflow off WITHOUT making a scroll
     * container, so sticky works and nothing can push the page sideways.
     *
     * `hidden` stays first as the fallback: a browser too old for `clip` drops
     * that line and keeps exactly today's behaviour. */
    html, body { overflow-x: hidden; overflow-x: clip; max-width: 100%; }

    /* Wide things scroll inside themselves rather than widening the document —
       a horizontal page scroll on a phone makes everything feel broken. */
    table, pre, .table-responsive, .cart-table, .summary-table {
        display: block;
        max-width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    img, video, canvas, svg { max-width: 100%; height: auto; }

    /* Grids that were fixed at three or four columns become one. */
    .paypanel__grid, .wallet-grid, .user-card__grid, .field-row {
        grid-template-columns: 1fr !important;
    }
}

/* ══ 6. respect a phone set to reduce motion ═════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
}


/* ══ 7. the real reason a phone struggles here ═══════════════════════════
 *
 * These pages are long. A service rep's screen renders 657 product cards and
 * 664 engineer rows into a single document — near 35,000 elements — and a
 * phone has to lay out and paint every one before it can show the first.
 * That is the freezing: not a slow stylesheet, a very large page.
 *
 * `content-visibility: auto` lets the browser skip layout and paint for
 * anything scrolled out of view, and do that work only as it comes near. The
 * markup does not change and nothing is removed — the page simply stops paying
 * for what nobody is looking at.
 *
 * `contain-intrinsic-size` is the placeholder height used while an item is
 * skipped. Without it the scrollbar would jump about as items are measured for
 * real; the values are the rough rendered heights of each kind of row.
 */
/* Removed 2026-09-25. The placeholder heights were guesses, and a page laid
 * out from guesses stops short of its real bottom on a phone until a sideways
 * drag makes the browser measure the rest (owner: "doesn't scroll down
 * completely... until the page is scrolled from side"). The lists are a
 * fraction of what they were - the cards are fetched on tap now - so nothing
 * needs skipping. */
