/**
 * Copyright (c) 2026 Estait Group LLC
 * All rights reserved.
 *
 * WEB-286 (epic WEB-285): shared compact layout for the ABBI app and admin
 * surfaces -- the [*_manager] shortcodes, the linkers, /stats, /schedule.
 * Loaded on EVERY blog (functions.php), unlike abbi-home.css which is
 * main-site only, so a tenant's /storefront gets the same phone layout as
 * /clients on the network main site.
 *
 * How "mobile" is decided: by viewport and input, in CSS. There is no
 * server-side user-agent branching (wp_is_mobile) because CloudFront caches
 * pages without the UA in the cache key -- a phone-rendered page would be
 * served to desktop and the reverse.
 *
 * The two compact breakpoints. Every rule in this file sits inside one of
 * them, so nothing here can change the desktop layout. js/theme.js mirrors
 * the same two queries as html.abbi-compact for behaviour-only switches;
 * keep the strings identical in both places.
 *
 *   phone            (max-width: 639px)
 *   phone-landscape  (max-height: 500px) and (orientation: landscape) and (pointer: coarse)
 *
 * phone-landscape exists because a phone held sideways is ~844px wide --
 * past the 839px desktop header breakpoint -- while only ~390px tall.
 *
 * Specificity. The managers print their own <style> in the page body
 * (".tm-table td { padding: 16px }"), and abbi-home.css re-skins them on the
 * main site at "body.abbi-site .abbi-admin .tm-table td". The prefix
 * :is(body.abbi-site .abbi-admin, body) takes the specificity of its most
 * specific argument, so it ties the abbi-home rules (and wins on load order:
 * this sheet depends on abbi-home where both load) and beats the inline
 * manager styles, while still matching on tenant blogs through plain `body`.
 */

/* ---- phone (upright) -------------------------------------------------- */

@media (max-width: 639px) {
    /* Page gutter: 32px a side leaves ~311px of a 375px phone. A phone held
       sideways (844 wide) keeps the desktop gutter. */
    body.abbi-site .abbi-container {
        padding: 0 16px;
    }

    :is(body.abbi-site .abbi-admin, body) .tm-manager {
        padding-left: 0;
        padding-right: 0;
    }

    :is(body.abbi-site .abbi-admin, body) .tm-header {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
    }

    :is(body.abbi-site .abbi-admin, body) .tm-header-actions {
        justify-content: flex-end;
        flex-wrap: wrap;
    }

    /* Stats (WEB-289): two tiles a row on an upright phone, with the value
       at 22px so an 8-digit count or a 6-decimal cost fits a ~125px tile on
       a 360px phone instead of splitting mid-number. */
    :is(body.abbi-site .abbi-admin, body) .tm-stats .tm-stat-tiles {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    :is(body.abbi-site .abbi-admin, body) .tm-stats .tm-stat-tile__value {
        font-size: 22px;
    }
}

/* ---- phone, upright or sideways --------------------------------------- */

@media (max-width: 639px), (max-height: 500px) and (orientation: landscape) and (pointer: coarse) {
    /* Tables become one card per row (WEB-288). theme.js copies each header's
       text onto its cells as data-label, printed here as the field caption;
       the first cell is the card's title and the Actions cell a row of
       buttons. A phone held sideways is still a phone -- the rule is vertical
       -- so the cards apply there too (an 8-column table does not fit 844px). */
    :is(body.abbi-site .abbi-admin, body) .tm-table-container {
        overflow-x: visible;
    }

    :is(body.abbi-site .abbi-admin, body) .tm-table thead {
        display: none;
    }

    :is(body.abbi-site .abbi-admin, body) .tm-table,
    :is(body.abbi-site .abbi-admin, body) .tm-table tbody {
        display: block;
        width: 100%;
    }

    :is(body.abbi-site .abbi-admin, body) .tm-table tbody tr {
        display: block;
        height: auto;
        padding: 12px 16px;
    }

    :is(body.abbi-site .abbi-admin, body) .tm-table td {
        display: block;
        padding: 6px 0;
        overflow-wrap: anywhere;
    }

    :is(body.abbi-site .abbi-admin, body) .tm-table td[data-label]::before {
        content: attr(data-label);
        display: block;
        font-size: 12px;
        font-weight: 600;
        opacity: 0.7;
    }

    :is(body.abbi-site .abbi-admin, body) .tm-table .tm-col-optional {
        display: none;
    }

    :is(body.abbi-site .abbi-admin, body) .tm-table tbody td:first-child {
        font-size: 1.05rem;
        padding-top: 0;
    }

    :is(body.abbi-site .abbi-admin, body) .tm-table tbody td:first-child::before {
        display: none;
    }

    /* Row actions: buttons that wrap onto as many lines as they need, each
       label on one line. overflow-wrap is reset here because the `anywhere`
       above shrinks a button's min-content to one character, so flex-wrap
       never wraps and "Delete" breaks as De/let/e. The anchors' inline
       display:inline-block (clients renderer) needs !important to become
       inline-flex so their label centres like the buttons'. */
    :is(body.abbi-site .abbi-admin, body) .tm-table td.tm-col-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        padding-top: 10px;
        overflow-wrap: normal;
    }

    :is(body.abbi-site .abbi-admin, body) .tm-table td.tm-col-actions::before {
        display: none;
    }

    :is(body.abbi-site .abbi-admin, body) .tm-table td.tm-col-actions > :is(a, button) {
        box-sizing: border-box;
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
        flex: 1 1 auto;
        min-height: 44px;
        margin: 0 !important;
        white-space: nowrap;
    }

    /* Stats (WEB-289): its rows are mostly numbers, so a stats card reads
       as label-left / value-right lines rather than a caption over each
       value -- the same data in half the height. The first cell stays the
       card title. */
    :is(body.abbi-site .abbi-admin, body) .tm-stats .tm-table td[data-label] {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 12px;
        text-align: right;
    }

    :is(body.abbi-site .abbi-admin, body) .tm-stats .tm-table td[data-label]::before {
        flex: 0 0 auto;
        text-align: left;
    }

    /* A cell holding more than one line -- a failed run's status and its
       reason, a spend source and its cost basis -- stays caption-over-value;
       as flex items its parts would scatter across the row. */
    :is(body.abbi-site .abbi-admin, body) .tm-stats .tm-table tbody td:first-child,
    :is(body.abbi-site .abbi-admin, body) .tm-stats .tm-table td[data-label]:has(br) {
        display: block;
        text-align: left;
    }

    /* The per-day chart keeps its own sideways scroll; the fade on the right
       edge says there is more of it. */
    :is(body.abbi-site .abbi-admin, body) .tm-stats .tm-bars {
        -webkit-mask-image: linear-gradient(to right, black calc(100% - 24px), transparent);
        mask-image: linear-gradient(to right, black calc(100% - 24px), transparent);
    }

    /* A spacer the width of the fade (20px + the 4px gap) at the end, so at
       the end of the scroll -- or with nothing to scroll -- the fade covers
       empty space, not today's bar. */
    :is(body.abbi-site .abbi-admin, body) .tm-stats .tm-bars::after {
        content: '';
        flex: 0 0 20px;
    }

    /* Each bar as wide as its "09-14" label, so the labels do not overprint
       -- 30 days then scroll sideways instead of squeezing to 14px apiece. */
    :is(body.abbi-site .abbi-admin, body) .tm-stats .tm-bar {
        flex: 1 0 32px;
        min-width: 32px;
    }

    /* Add / edit modals take the whole screen. border-box, or height:100%
       plus the padding pushes the heading and the Save row off the screen. */
    :is(body.abbi-site .abbi-admin, body) .tm-modal-content {
        box-sizing: border-box;
        width: 100%;
        max-width: none;
        height: 100%;
        max-height: none;
        border-radius: 0;
        padding: 20px 16px calc(20px + env(safe-area-inset-bottom));
    }

    /* Touch targets: 44px minimum on the surfaces this epic has laid out --
       the manager tables and the transfer lists. Chat, /schedule and
       /connections size their own controls and get their pass in WEB-290;
       tenant page content is the agents' and is left alone. */
    /* border-box: an <a class="tm-button"> is content-box, so a bare 44px
       min-height plus its padding and border made the /clients Users and
       Products links 62px -- and flex stretched their neighbours to match. */
    :is(.tm-manager, .tl-container) :is(button, .button, .tm-button, .mdc-button, input[type="submit"], select) {
        box-sizing: border-box;
        min-height: 44px;
    }

    :is(.tm-manager, .tl-container) input[type="checkbox"] {
        width: 22px;
        height: 22px;
    }

    /* A bar of primary actions pinned to the bottom of the viewport. Static
       (an ordinary block) above these breakpoints. */
    .abbi-sticky-actions {
        position: sticky;
        bottom: 0;
        z-index: 5;
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
        background: var(--abbi-surface, #fff);
        border-top: 1px solid var(--abbi-border, #e0e0e0);
    }

    .abbi-sticky-actions > * {
        flex: 1 1 auto;
    }

    /* Transfer list (WEB-287): client_users_linker / client_products_linker,
       .tl-* markup. Desktop and tablet keep the 1fr auto 1fr row -- Available,
       buttons, Linked, left to right. A phone stacks the same three top to
       bottom: source list, Link/Unlink, target list. Each list is capped at
       about a third of the screen and scrolls in its own box, so the page
       never grows by the length of a list and the buttons stay within a
       short scroll of both. `body` lifts these over the linkers' own inline
       .tl-* rules (0,1,0). */
    body .tl-container {
        padding: 0;
    }

    body .tl-container > h2 {
        padding-right: 56px;
        font-size: 1.25rem;
        overflow-wrap: anywhere;
    }

    body .tl-close-button {
        top: 0;
        right: 0;
        width: 44px;
        height: 44px;
    }

    body .tl-grid {
        grid-template-columns: minmax(0, 1fr);
        gap: 12px;
    }

    body .tl-list {
        max-height: 35vh;
        max-height: 35dvh;
    }

    body .tl-item {
        min-height: 44px;
    }

    body .tl-buttons {
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: center;
        padding: 0;
    }

    body .tl-buttons .tl-button {
        flex: 1 1 0;
        justify-content: center;
        min-height: 44px;
    }

    body .tl-link-role {
        flex: 1 0 100%;
        justify-content: center;
    }

    /* 16px keeps iOS from zooming the page when the select is tapped. */
    body .tl-link-role select,
    body .tl-role-select {
        font-size: 16px;
    }

    body .tl-icon-h {
        display: none;
    }

    body .tl-icon-v {
        display: inline-block;
    }
}
