/* ================================================================
   Phones and small tablets (2026-10-30)

   Loaded after every other eager sheet, so each rule here overrides
   a known rule elsewhere at the same or higher specificity. Two
   widths only:
     <= 768px  the sidebar is gone and the bottom bar is the nav
               (main.css draws that switch at the same width);
     <= 560px  a phone held upright.
   Page sheets that load later (Finance) carry their own phone rules.
   ================================================================ */

/* The cafe name in the top bar is for phones; elsewhere the sidebar has it. */
.top-bar-brand {
    display: none;
}

@media (max-width: 768px) {

    /* ---------------------------------------------------------------
       ROOM FOR THE PHONE'S STATUS BAR (2026-11-01)

       index.html asks for the whole screen (viewport-fit=cover) and a
       see-through status bar, so the app installed on an iPhone drew
       right up under the notch or Dynamic Island and the top bar sat
       behind it. env() gives the height to keep clear. It is 0 in a
       browser tab, on Android, and on an iPhone that already keeps the
       page below the bar, so nothing moves there.

       The room goes on the app frame, not on the top bar: on a phone
       the whole page column scrolls, so a padded top bar scrolls away
       and the page slides up behind the island. As a border it is
       painted in the top bar's colour and the frame's height stays
       right. What sits outside the frame keeps clear with the rules
       under it. Phone widths only: nothing here reaches a desktop.
       --------------------------------------------------------------- */

    :root {
        --safe-top: env(safe-area-inset-top, 0px);
    }

    #app {
        border-block-start: var(--safe-top) solid var(--ds-surface);
    }

    /* The sign-in screen has no top bar; it is the page colour up there. */
    html[data-auth="out"] #app {
        border-block-start-color: var(--ds-canvas);
    }

    .toast-container {
        top: calc(24px + var(--safe-top));
    }

    /* Panels as tall as the screen. */
    .oview,
    .cprof,
    .clients-drawer,
    .modal-overlay.is-drawer .modal.modal-drawer {
        padding-block-start: var(--safe-top);
    }

    /* This sheet loads after this one and sets its own padding. */
    .brain-drawer .brain-drawer-panel {
        padding-block-start: calc(28px + var(--safe-top));
    }

    .imgcrop-overlay {
        padding-block-start: calc(var(--ds-space-4) + var(--safe-top));
    }

    .imgcrop-panel {
        max-height: calc(100vh - 32px - var(--safe-top));
    }

    /* The first-run wizard reaches the top of the screen too. */
    .ob-panel {
        padding-block-start: var(--safe-top);
    }

    /* In Arabic, main.css's `body[dir="rtl"] .main-content` put back the
       sidebar's 72px after its phone rule took it away, so every page
       stopped 72px short of the right edge with a blank strip there. */
    body[dir="rtl"] .main-content {
        margin-inline-start: 0;
    }

    /* ---------------------------------------------------------------
       1. TOP BAR

       The date and time broke into four lines and ran into the page
       title; the search showed a Ctrl+K key a phone does not have.
       The phone's own status bar already shows the time, so the
       clock goes; the search keeps its icon and opens the same
       search sheet.
       --------------------------------------------------------------- */

    #topBar.top-bar,
    body[data-page] #topBar {
        height: 52px;
        min-height: 52px;
        padding-inline: 12px;
        gap: 8px;
    }

    #topBar .datetime-block {
        display: none;
    }

    #topBar .top-bar-brand {
        display: block;
        flex: 1 1 auto;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-size: 16px;
        font-weight: 700;
        letter-spacing: -0.01em;
        color: var(--ds-text-primary);
    }

    /* The search sits with the other icons at the end of the bar. */
    #topBar .top-bar-actions {
        margin-inline-start: 0;
    }

    #topBar .top-bar-search {
        flex: 0 0 auto;
        width: 40px;
        height: 40px;
        padding: 0;
        justify-content: center;
        border-radius: var(--ds-radius-md);
    }

    #topBar .top-bar-search > span {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
    }

    #topBar .top-bar-search svg {
        width: 18px;
        height: 18px;
    }

    #topBar .top-bar-actions {
        gap: 4px;
    }

    #topBar .icon-btn {
        width: 40px;
        height: 40px;
        min-width: 40px;
        min-height: 40px;
    }

    #topBar .topbar-user-btn {
        width: auto;
        padding-inline: 0;
    }

    #topBar .topbar-user-btn > svg {
        display: none;
    }

    #topBar .topbar-user-btn .ds-avatar {
        width: 36px;
        height: 36px;
        font-size: 13px;
    }

    /* ---------------------------------------------------------------
       2. PAGE HEADER

       Title on its own line; whatever the page puts beside it (period
       tabs, a primary button, Export) drops under it at full width.
       A row of tabs that is wider than the phone scrolls sideways
       instead of being cut off at the edge.
       --------------------------------------------------------------- */

    .main-content .page-header,
    .main-content .ds-page-header {
        flex-wrap: wrap;
        align-items: flex-end;
        row-gap: 10px;
        column-gap: 12px;
        padding-inline: 16px;
        padding-block: 12px 4px;
    }

    .main-content .ds-page-header-main {
        flex: 1 1 200px;
        min-width: 0;
        gap: 2px;
    }

    .main-content .ds-page-header-title {
        font-size: 24px;
        line-height: 1.15;
    }

    .main-content .ds-page-header-subtitle {
        font-size: 13px;
        line-height: 1.4;
    }

    .main-content .ds-page-header-actions {
        flex: 0 1 auto;
        min-width: 0;
        max-width: 100%;
        flex-wrap: wrap;
        gap: 8px;
    }

    .main-content .ds-page-header-actions:empty {
        display: none;
    }

    /* Tabs and segmented controls in the header take their own row and
       scroll inside it. */
    .main-content .ds-page-header-actions:has(> .ds-tabs, > .dash-controls) {
        flex: 1 1 100%;
    }

    .main-content .ds-page-header-actions > .ds-tabs {
        flex: 1 1 auto;
        min-width: 0;
        max-width: 100%;
        overflow-x: auto;
        scrollbar-width: none;
        flex-wrap: nowrap;
    }

    .main-content .ds-page-header-actions > .ds-tabs::-webkit-scrollbar {
        display: none;
    }

    .main-content .ds-page-header-actions .ds-btn {
        min-height: 44px;
    }

    /* ---------------------------------------------------------------
       3. BOTTOM BAR

       It sat at z-index 9000, above every dialog's dimmed backdrop,
       so a modal or side panel left the bar bright and tappable
       under it. It now sits under the overlays and over the page.
       "More" is a <button>, the others are links: the button kept
       its own line-height and its label sat 2px lower.
       --------------------------------------------------------------- */

    .mobile-bottom-nav {
        z-index: 150;
        box-shadow: 0 -1px 0 var(--ds-border), 0 -6px 16px rgba(30, 27, 57, 0.06);
        border-top: 0;
    }

    .mbn-item {
        min-width: 0;
        gap: 4px;
        padding: 6px 2px;
        font-family: inherit;
        font-size: 11px;
        line-height: 1.2;
        letter-spacing: 0;
        border: 0;
        background: transparent;
        appearance: none;
        -webkit-appearance: none;
        cursor: pointer;
        -webkit-tap-highlight-color: transparent;
    }

    .mbn-item span {
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .mbn-item svg {
        width: 22px;
        height: 22px;
        flex-shrink: 0;
    }

    .mbn-item.active {
        color: var(--ds-primary);
    }

    .mbn-item.active::after {
        background: var(--ds-primary);
        left: 28%;
        right: 28%;
    }

    .mbn-item.active svg {
        transform: none;
    }

    .mbn-item[hidden],
    .mbn-item.is-mbn-overflow {
        display: none !important;
    }

    body.mobile-more-open .mbn-item#mbnMoreBtn {
        color: var(--ds-primary);
    }

    /* The "More" sheet: a grid of 3, labels allowed two lines. */
    .mobile-more-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .mobile-more-item {
        min-width: 0;
        text-align: center;
    }

    .mobile-more-item span {
        overflow-wrap: anywhere;
        line-height: 1.25;
    }

    /* ---------------------------------------------------------------
       4. TILL (POS)
       --------------------------------------------------------------- */

    /* Order tabs: the open sale gets the room. All orders and New sale
       keep their names for screen readers and show only their icons. */
    .pos-counter-screen .order-tabs-bar {
        gap: 6px;
        padding-inline: 8px;
    }

    .pos-counter-screen .order-tabs-bar .tab-actions {
        gap: 6px;
        flex-shrink: 0;
    }

    .pos-counter-screen .tab-actions .pos-labelled-btn {
        width: 44px;
        min-width: 44px;
        height: 44px;
        padding: 0;
        justify-content: center;
    }

    .pos-counter-screen .tab-actions .pos-labelled-btn > span {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
    }

    /* Category rail: a finger swipes it, so the arrow buttons go and
       the cut edge fades to say there is more. */
    .pos-counter-screen .pos-cat-rail-btn {
        display: none !important;
    }

    .pos-counter-screen .pos-categories.is-rail .pos-cat-track {
        -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
        mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
    }

    [dir="rtl"] .pos-counter-screen .pos-categories.is-rail .pos-cat-track {
        -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 24px), transparent);
        mask-image: linear-gradient(to left, #000 calc(100% - 24px), transparent);
    }

    .pos-counter-screen .pos-categories.is-rail.is-rail-end .pos-cat-track {
        -webkit-mask-image: none;
        mask-image: none;
    }
}

@media (max-width: 560px) {

    /* ---------------------------------------------------------------
       4b. TILL on a phone
       --------------------------------------------------------------- */

    /* Search and the Photos / Compact switch share one row. */
    .pos-counter-screen .pos-products-toolbar {
        gap: 8px;
        padding-inline: 12px;
    }

    .pos-counter-screen .pos-products-toolbar .search-bar {
        min-width: 0;
    }

    .pos-counter-screen #searchInput {
        text-overflow: ellipsis;
        min-height: 44px;
    }

    .pos-counter-screen .pos-density-opt {
        padding-inline: 10px;
        font-size: 13px;
    }

    .pos-counter-screen .pos-categories {
        padding-inline: 12px;
    }

    /* Three tiles a row instead of two: twelve items on screen, not
       four. */
    .pos-counter-screen .pos-product-grid {
        padding: 6px 12px 12px;
    }

    .pos-counter-screen .pos-menu-section-grid,
    .pos-counter-screen .pos-product-grid:not(:has(.pos-menu-section)) {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 8px;
    }

    .pos-counter-screen .pos-products-panel[data-density="compact"] .pos-menu-section-grid,
    .pos-counter-screen .pos-products-panel[data-density="compact"] .pos-product-grid:not(:has(.pos-menu-section)) {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    /* Collapsed tray. The total sat at 32px beside a Charge button with
       a 220px floor, and the two overlapped on a phone. Charge already
       carries the amount, so the row keeps the item count and gives
       Charge the rest of the width. */
    .pos-counter-screen .pos-order-panel:not(.is-tray-open) .pos-order-footer {
        grid-template-columns: auto minmax(0, 1fr);
        gap: 12px;
        padding: 0 12px 10px;
    }

    .pos-counter-screen .pos-order-panel:not(.is-tray-open) .total-row .value {
        display: none;
    }

    .pos-counter-screen .pos-order-panel:not(.is-tray-open) .total-row .label {
        font-size: 0;
    }

    .pos-counter-screen .pos-order-panel:not(.is-tray-open) .total-row .total-item-count {
        display: block;
        margin: 0;
        font-size: 14px;
        font-weight: 600;
        color: var(--ds-text-secondary);
        white-space: nowrap;
    }

    .pos-counter-screen .pos-order-panel:not(.is-tray-open) .pos-charge-btn {
        min-width: 0;
        width: 100%;
        min-height: 52px;
    }

    .pos-counter-screen .pos-cart-handle {
        min-height: 32px;
    }
}

@media (max-width: 560px) {

    /* Tile text at phone size: the name and its favourite star fit one
       line in a third of the screen, instead of the star sitting alone
       above the name. */
    .pos-counter-screen .pos-product-card:not(.is-text-only) .product-name {
        padding: 6px 2px 0;
        font-size: 13px;
        line-height: 1.25;
        min-height: calc(2.5em + 6px);
    }

    .pos-counter-screen .pos-product-card:not(.is-text-only) .product-price {
        padding: 2px 2px 4px;
        font-size: 13px;
    }

    .pos-counter-screen .pos-product-card .product-qty {
        top: 2px;
        inset-inline-end: 2px;
        min-width: 26px;
        height: 26px;
        padding-inline: 6px;
        font-size: 13px;
    }

    /* Open tray. The order took three fifths of the screen and its header
       and footer alone were taller than that, so the lines -- the reason
       to open it -- got no height at all, and the buttons under Charge
       went under the bottom bar. On a phone it takes three quarters and
       scrolls as one list, with Charge held at the bottom edge. */
    .pos-counter-screen .pos-terminal:has(.pos-order-panel.is-tray-open) {
        grid-template-rows: minmax(0, 1fr) minmax(0, 3fr);
    }

    .pos-counter-screen .pos-order-panel.is-tray-open > #orderPanel {
        overflow-y: auto;
        overscroll-behavior: contain;
    }

    .pos-counter-screen .pos-order-panel.is-tray-open #orderPanel > * {
        flex: none;
    }

    .pos-counter-screen .pos-order-panel.is-tray-open #orderItems {
        flex: none;
        min-height: 0;
        overflow: visible;
    }

    .pos-counter-screen .pos-order-panel.is-tray-open .pos-order-footer {
        display: contents;
    }

    .pos-counter-screen .pos-order-panel.is-tray-open .pos-order-footer > * {
        margin-inline: 16px;
    }

    .pos-counter-screen .pos-order-panel.is-tray-open .pos-order-footer > .pos-charge-btn {
        position: sticky;
        bottom: 8px;
        z-index: 2;
        margin-block: 8px;
        box-shadow: 0 0 0 8px var(--ds-surface);
    }

    .pos-counter-screen .pos-order-panel.is-tray-open .pos-order-footer > :last-child {
        margin-bottom: 12px;
    }

    .pos-counter-screen .pos-order-panel.is-tray-open .pos-order-header {
        padding: 8px 16px 8px;
    }

    /* ---------------------------------------------------------------
       5. DIALOGS

       A box in the middle of a phone left a strip of page above and
       below it and put its buttons out of thumb reach. On a phone every
       dialog rises from the bottom edge as a sheet, and its buttons
       share the full width (two to a row when they fit, otherwise one
       each). Side panels take the whole screen.
       --------------------------------------------------------------- */

    .modal-overlay {
        align-items: flex-end;
        padding: 0;
    }

    .modal-overlay .modal,
    .modal-overlay .modal.modal-lg,
    .modal-overlay .modal.modal-sm {
        width: 100% !important;
        max-width: 100% !important;
        margin: 0 !important;
        max-height: calc(100dvh - 16px - var(--safe-top)) !important;
        border-radius: 20px 20px 0 0;
        transform: translateY(24px);
    }

    .modal-overlay.active .modal {
        transform: none;
    }

    .modal-overlay .modal-header {
        padding: 14px 16px 12px;
    }

    .modal-overlay .modal-title {
        min-width: 0;
        overflow-wrap: anywhere;
    }

    .modal-overlay .modal-body {
        padding: 16px;
    }

    .modal-overlay .modal-footer {
        gap: 8px;
        padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
    }

    .modal-overlay .modal-footer > button,
    .modal-overlay .modal-footer > .btn,
    .modal-overlay .modal-footer > .ds-btn {
        flex: 1 1 auto;
        justify-content: center;
        min-height: 48px;
        margin: 0;
    }

    .modal-overlay.is-drawer .modal.modal-drawer {
        width: 100% !important;
        height: 100%;
        max-height: none !important;
        border-radius: 0;
        transform: none;
    }

    .top-dialog-overlay {
        align-items: flex-end;
        padding: 0;
    }

    .top-dialog {
        max-width: none;
        border-radius: 20px 20px 0 0;
        padding: 20px 16px calc(16px + env(safe-area-inset-bottom, 0px));
    }
}

@media (max-width: 768px) {

    /* ---------------------------------------------------------------
       6. ROWS OF TABS

       A row of tabs wider than the screen scrolls sideways under a
       finger. The grey scrollbar under it (Team, Settings, Finance)
       read as a stray line; the fade in section 12 says there is
       more. Tabs keep their names on one line.
       --------------------------------------------------------------- */

    .ds-tabs,
    .team-tab-strip,
    .settings-tab-strip,
    .orders-period {
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
    }

    .ds-tabs::-webkit-scrollbar,
    .team-tab-strip::-webkit-scrollbar,
    .settings-tab-strip::-webkit-scrollbar,
    .orders-period::-webkit-scrollbar {
        display: none;
    }

    .ds-tabs > .ds-tab,
    .orders-period > .orders-period-btn {
        flex: 0 0 auto;
        white-space: nowrap;
    }

    /* Inventory's four tabs: "Stock Overview" and "Movement History"
       broke onto two lines and the row ran 76px off the screen. */
    .inventory-page > .inventory-tabs {
        max-width: 100%;
    }

    /* ---------------------------------------------------------------
       7. TILL: open-order tabs

       The bar was 40px and the tab inside it 44px, so every tab lost
       its bottom border.
       --------------------------------------------------------------- */

    .pos-counter-screen .order-tabs-bar {
        height: auto;
        min-height: 56px;
        padding-block: 6px;
    }

    .pos-counter-screen .order-tabs-bar .order-tabs-scroll {
        height: auto;
    }

    /* ---------------------------------------------------------------
       8. TABLES

       One column under 1100px, but the column still had a fixed share
       of a screen-high page: the map took its 260px minimum and the
       status chips under it were drawn over by the next card. On a
       phone the page scrolls and each part keeps its own height.
       --------------------------------------------------------------- */

    .tbl-main {
        flex: none;
        min-height: auto;
    }

    .tbl-canvas-col {
        min-height: auto;
    }

    .tbl-canvas-wrap {
        flex: none;
        height: clamp(300px, 52vh, 480px);
    }

    /* ---------------------------------------------------------------
       9. SHIFTS: the four buttons on the open shift, two to a row and
       the same width, instead of four widths in a ragged wrap.
       --------------------------------------------------------------- */

    .shift-live-actions {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        flex: 1 1 100%;
    }

    .shift-live-actions .ds-btn {
        width: 100%;
        justify-content: center;
    }

    /* ---------------------------------------------------------------
       10. MORE SHEET: every tile the same height, whether its name
       takes one line ("Products") or two ("Customer Invoices").
       --------------------------------------------------------------- */

    .mobile-more-grid {
        grid-auto-rows: 1fr;
    }

    .mobile-more-sheet {
        padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
        max-height: calc(100dvh - 48px - var(--safe-top));
        overflow-y: auto;
    }
}

@media (max-width: 560px) {

    /* Inventory: the alert card on its own row, the other three as two
       short cards and one wide one, instead of four screen-wide cards
       that pushed the stock list a whole screen down. */
    .inventory-stat-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
    }

    .inventory-stat-grid > :first-child,
    .inventory-stat-grid > :nth-child(even):last-child {
        grid-column: 1 / -1;
    }

    .inventory-stat-grid .ds-stat-card {
        padding: 14px 16px;
        gap: 6px;
    }
}

@media (max-width: 768px) {

    /* ---------------------------------------------------------------
       11. ONE SCROLL PER PAGE

       The title, tabs and buttons above every page stayed pinned while
       only the list under them scrolled: on Orders that was 230px of a
       844px phone that never moved. Tables and Floor plan did not
       scroll at all, so everything under the map was out of reach. On
       a phone the whole column scrolls -- top bar, title and page --
       and the bottom bar stays. The till and the kitchen screen keep
       their fixed layouts: both are built to fill one screen.
       --------------------------------------------------------------- */

    body:not([data-page="pos"]):not([data-page="kds"]) .main-content {
        overflow-x: hidden;
        overflow-y: auto;
        overscroll-behavior-y: contain;
    }

    body:not([data-page="pos"]):not([data-page="kds"]) .main-content .page-content {
        flex: none;
        min-height: auto;
        overflow: visible;
        scrollbar-gutter: auto;
    }

    body:not([data-page="pos"]):not([data-page="kds"]) .main-content .page-header,
    body:not([data-page="pos"]):not([data-page="kds"]) #topBar {
        flex-shrink: 0;
    }

    /* Inventory's list area had its own scroll inside the page; with the
       page scrolling it grows instead. */
    .inventory-page > #invTabBody {
        flex: none;
        overflow: visible;
    }
}

/* -------------------------------------------------------------------
   12. ROWS OF TABS FADE AT THE EDGE THAT HAS MORE

   A tab row wider than the phone ended in a tab cut through the middle
   ("Mover", "Own", "Lo"), which reads as a layout bug, not as "swipe
   for more". The row now fades out at whichever end has more to show
   and stops fading once you reach that end. Driven by the row's own
   scroll position; a row that fits does not scroll, so it never fades.
   Browsers without scroll-driven animations keep the plain cut-off.
   ------------------------------------------------------------------- */

@property --tabs-fade-start {
    syntax: '<length>';
    inherits: false;
    initial-value: 0px;
}

@property --tabs-fade-end {
    syntax: '<length>';
    inherits: false;
    initial-value: 0px;
}

@keyframes tabs-fade {
    0% { --tabs-fade-start: 0px; --tabs-fade-end: 32px; }
    8% { --tabs-fade-start: 32px; }
    92% { --tabs-fade-end: 32px; }
    100% { --tabs-fade-start: 32px; --tabs-fade-end: 0px; }
}

@media (max-width: 768px) {
    .ds-tabs,
    .team-tab-strip,
    .settings-tab-strip,
    .orders-period,
    .fin-tabs {
        -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--tabs-fade-start), #000 calc(100% - var(--tabs-fade-end)), transparent);
        mask-image: linear-gradient(to right, transparent, #000 var(--tabs-fade-start), #000 calc(100% - var(--tabs-fade-end)), transparent);
        animation: tabs-fade linear both;
        animation-timeline: scroll(self inline);
    }

    [dir="rtl"] .ds-tabs,
    [dir="rtl"] .team-tab-strip,
    [dir="rtl"] .settings-tab-strip,
    [dir="rtl"] .orders-period,
    [dir="rtl"] .fin-tabs {
        -webkit-mask-image: linear-gradient(to left, transparent, #000 var(--tabs-fade-start), #000 calc(100% - var(--tabs-fade-end)), transparent);
        mask-image: linear-gradient(to left, transparent, #000 var(--tabs-fade-start), #000 calc(100% - var(--tabs-fade-end)), transparent);
    }

    /* ---------------------------------------------------------------
       13. CLIENTS: the "..." button sits beside the name, top right,
       instead of alone on a third line with the card's empty middle
       above it.
       --------------------------------------------------------------- */

    .clients-mobile-card {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        column-gap: 12px;
        align-items: start;
    }

    .clients-mobile-card > * {
        grid-column: 1;
        min-width: 0;
    }

    .clients-mobile-card > :last-child {
        grid-column: 2;
        grid-row: 1 / span 2;
        margin-block-start: 0 !important;
    }

    /* Tables in Grid view: the map's fixed height cut the grid off after
       the fifth row and gave it a scroll of its own. */
    .tbl-canvas-wrap:has(> .tbl-grid) {
        height: auto;
    }
}

@media (max-width: 560px) {

    /* ---------------------------------------------------------------
       14. FILTER ROWS (Products, Inventory, Invoices, Clients)

       Every filter was a screen-wide row of its own: Inventory stacked
       search, three lists and Export into 300px before the first item.
       Search keeps its own row; the rest sit two to a row, and an odd
       one out at the end takes the whole row.
       --------------------------------------------------------------- */

    .ds-toolbar:not(.orders-toolbar) {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        align-items: center;
        gap: 8px;
    }

    .ds-toolbar:not(.orders-toolbar) > * {
        width: 100%;
        min-width: 0;
        max-width: none;
    }

    .ds-toolbar:not(.orders-toolbar) > .page-search,
    .ds-toolbar:not(.orders-toolbar) > .clients-search,
    .ds-toolbar:not(.orders-toolbar) > .ds-toolbar-search,
    .ds-toolbar:not(.orders-toolbar) > :nth-child(even):last-child {
        grid-column: 1 / -1;
    }

    .ds-toolbar .ds-select,
    .ds-toolbar .ds-btn {
        min-width: 0;
        justify-content: center;
    }

    /* A long hint ends in "..." instead of stopping mid-word at the edge
       ("Search by order number or"). */
    .ds-toolbar .ds-input {
        text-overflow: ellipsis;
    }

    /* ---------------------------------------------------------------
       15. ORDERS: Export beside the Orders / Voids switch as an icon,
       instead of a lone button on a row of its own above the list.
       --------------------------------------------------------------- */

    .main-content .ds-page-header-actions:has(> .ds-tabs) {
        flex-wrap: nowrap;
    }

    .main-content .ds-page-header-actions:has(> .ds-tabs) > .ds-btn:has(> svg) {
        flex: none;
        width: 44px;
        padding: 0;
        justify-content: center;
    }

    .main-content .ds-page-header-actions:has(> .ds-tabs) > .ds-btn:has(> svg) > span {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
    }

    /* ---------------------------------------------------------------
       16. INVENTORY STOCK LIST AS CARDS

       An eight-column table on a 390px phone: the stock figure, the one
       number this screen is for, was cut in half at the edge and the
       rest was a sideways scroll. Each item is a short card -- name and
       stock on top, the status under, Receive and Adjust last. Category,
       unit cost and value stay on the wide screen (the category filter
       is above the list, the total value is the card above that).
       --------------------------------------------------------------- */

    .inventory-table-wrap .ds-table:has(.inventory-thumb-well),
    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) tbody {
        display: block;
    }

    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) thead {
        display: none;
    }

    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) tbody tr {
        display: grid;
        grid-template-columns: 44px minmax(0, 1fr) auto;
        grid-template-areas:
            "thumb name stock"
            "thumb status status"
            ". acts acts";
        column-gap: 12px;
        row-gap: 4px;
        align-items: center;
        height: auto;
        padding: 12px 16px;
        border-bottom: 1px solid var(--ds-border-subtle, var(--ds-border));
        border-inline-start: 3px solid transparent;
    }

    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) tbody tr.is-low {
        border-inline-start-color: var(--ds-warning);
    }

    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) tbody tr.is-out,
    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) tbody tr.is-negative {
        border-inline-start-color: var(--ds-danger);
    }

    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) tbody td {
        display: block;
        width: auto !important;
        min-width: 0;
        min-height: 0;
        padding: 0;
        border: 0;
        box-shadow: none !important;
    }

    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) tbody td:nth-child(1) { grid-area: thumb; align-self: start; }
    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) tbody td:nth-child(2) { grid-area: name; }
    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) tbody td:nth-child(4) { grid-area: stock; white-space: nowrap; }
    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) tbody td:nth-child(3),
    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) tbody td:nth-child(5),
    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) tbody td:nth-child(6) { display: none; }
    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) tbody td:nth-child(7) { grid-area: status; justify-self: start; }

    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) tbody td:nth-child(8) {
        grid-area: acts;
        display: flex;
        gap: 8px;
        padding-block-start: 6px;
    }

    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) tbody td:nth-child(8) .ds-btn {
        min-height: 40px;
    }

    .inventory-table-wrap .ds-table:has(.inventory-thumb-well) .inventory-thumb-well {
        width: 44px;
        height: 44px;
    }

    /* "17 Made to order - not counted here" wraps under the count and
       kept the indent that spaced it from the count on one line. */
    .inventory-made-note {
        margin-inline-start: 0;
    }

    /* ---------------------------------------------------------------
       17. PRODUCTS IN CARDS: two to a row. At one a row each card was a
       screen-wide photo, about one product per screen of scrolling.
       --------------------------------------------------------------- */

    .products-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
    }

    .products-grid-card {
        min-width: 0;
        padding: 8px;
    }

    .products-grid-card-meta {
        flex-wrap: wrap;
        row-gap: 2px;
    }

    .products-grid-card-actions .ds-btn {
        flex: 1 1 0;
        min-width: 0;
        min-height: 40px;
        justify-content: center;
    }

    /* ---------------------------------------------------------------
       18. FLOOR PLAN EDITOR TOOLBAR

       The dividers between tool groups were drawn at the start of
       wrapped rows as stray grey lines, Bar Stool sat alone on a row,
       and "Saved" took a row of its own. In rows now: the two tools,
       the five shapes, templates, undo / redo / add, then snap with the
       save state at the end.
       --------------------------------------------------------------- */

    .floor-plan-page .fp-toolbar {
        padding: 12px;
        row-gap: 10px;
    }

    .floor-plan-page .fp-toolbar-divider {
        display: none;
    }

    .floor-plan-page .fp-toolbar > .fp-tools { order: 1; flex: 1 1 100%; flex-wrap: nowrap; }
    .floor-plan-page .fp-toolbar > .fp-palette { order: 2; flex: 1 1 100%; }
    .floor-plan-page .fp-toolbar > .fp-templates { order: 3; flex: 1 1 100%; }
    .floor-plan-page .fp-toolbar > .fp-toolbar-group:has(#fpUndoBtn) { order: 4; flex: 1 1 100%; flex-wrap: nowrap; }
    .floor-plan-page .fp-toolbar > .fp-toolbar-group:has(#fpSnapToggle) { order: 5; }
    .floor-plan-page .fp-toolbar > .fp-save-indicator { order: 6; margin-inline-start: auto; }
    .floor-plan-page .fp-toolbar > .fp-place-hint { order: 7; flex: 1 1 100%; }

    .floor-plan-page .fp-tools > .fp-tool {
        flex: 1 1 0;
        justify-content: center;
    }

    .floor-plan-page #fpAddTableBtn {
        flex: 1 1 auto;
    }

    /* The zoom buttons lie in a row along the bottom of the map, and the
       floor is fitted above them (floor_plan.js _fitToScreen). As a
       column they covered the tables in the bottom-left corner. */
    .floor-plan-page .fp-zoom-controls {
        flex-direction: row;
        align-items: center;
    }

    .floor-plan-page .fp-palette {
        display: grid;
        grid-template-columns: repeat(5, minmax(0, 1fr));
        gap: 6px;
    }

    /* Every shape tile the same height, the names on one line: the round
       and stool tiles came out taller and shorter than the rest. */
    .floor-plan-page .fp-palette-item {
        min-width: 0;
        padding: 6px 2px;
        font-size: 11px;
        align-self: stretch;
    }

    .floor-plan-page .fp-palette-shape {
        flex: none;
        margin-block: auto;
    }

    .floor-plan-page .fp-palette-item > span:last-child {
        max-width: 100%;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
    }

    .floor-plan-page .fp-templates #fpTemplateSelect {
        flex: 1 1 auto;
        min-width: 0;
        max-width: none;
    }

    /* The floor is wider than it is tall: a 60vh box left 150px of empty
       floor above and below it. */
    .floor-plan-page .fp-stage-outer {
        height: clamp(300px, 86vw, 420px);
    }
}

@media (max-width: 768px) {

    /* ---------------------------------------------------------------
       19. TILL: the open order's colour dot

       With no colour picked it was a light grey dot on a lavender tab,
       a smudge beside the order's name. A ring now says "pick a colour
       here"; a picked colour shows inside the ring.
       --------------------------------------------------------------- */

    .pos-counter-screen .order-tab-color-dot {
        width: 12px;
        height: 12px;
        border: 1.5px solid var(--ds-border-strong);
    }
}

@media (max-width: 560px) {

    /* ---------------------------------------------------------------
       20. DASHBOARD: RECENT ORDERS AS ROWS THAT FIT

       A 520px table in a 300px card: Time and Amount were off the right
       edge behind a sideways scroll. Each order is two lines now --
       number and amount, then where, items, status and time.
       --------------------------------------------------------------- */

    .dash-recent {
        min-width: 0;
    }

    .dash-recent thead {
        display: none;
    }

    .dash-recent,
    .dash-recent tbody {
        display: block;
    }

    .dash-recent tbody tr {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        grid-template-areas:
            "who amt"
            "items status"
            "items time";
        column-gap: 12px;
        row-gap: 2px;
        align-items: center;
        padding-block: 10px;
        border-bottom: 1px solid var(--dash-line);
    }

    .dash-recent tbody tr:last-child {
        border-bottom: 0;
    }

    .dash-recent tbody td {
        display: block;
        padding: 0;
        border: 0;
        min-width: 0;
    }

    .dash-recent tbody td:nth-child(1) { grid-area: who; }
    .dash-recent tbody td:nth-child(2) { grid-area: items; white-space: normal; align-self: start; }
    .dash-recent tbody td:nth-child(3) { grid-area: status; justify-self: end; }
    .dash-recent tbody td:nth-child(4) { grid-area: time; justify-self: end; font-size: 12.5px; }
    .dash-recent tbody td:nth-child(5) { grid-area: amt; }

    /* ---------------------------------------------------------------
       21. SHIFTS: ONE CARD PER SHIFT

       On a phone a long list of shifts has to answer two questions at a
       glance: where does one shift end, and did its drawer match. So each
       day gets a coloured band, its shifts sit on a grey tray, and each
       shift is its own white card with the drawer in a strip at its foot:

           Karam                            841,000 IQD
           [Morning] 08:00 AM - 05:00 PM
           --------------------------------------------
           Orders 58              Short 5,000 IQD     >

       The strip and the card's edge turn red for a short drawer and green
       for an over or a shift still open. The whole card opens the shift,
       which still has its length and id. The day's date and total stay in
       view while its shifts scroll by.

       This is the same table desktop uses, moved about from here, so
       nothing in this section can reach a wider screen. The cells are
       found by place, because the sales column comes and goes with See
       sales, and Simple day has one drawer column to Detailed's two:
         1 shift, 2 cashier, 3 time, 4 duration, 5 orders, last = View
         sales:         the 6th, unless that is the one before View
         drawer:        .sessions-variance
         left for next: the one before View, when not .sessions-variance
       --------------------------------------------------------------- */

    /* overflow: clip keeps the round corners and, unlike hidden, lets the
       day heading stick. */
    .sessions-page > .ds-card:has(#sessionsTable) {
        padding-inline: 0;
        padding-block-end: 0;
        overflow: clip;
    }

    .sessions-page > .ds-card:has(#sessionsTable) > .orders-card-head {
        padding-inline: 12px;
        padding-block-end: 12px;
    }

    .sessions-day,
    .sessions-day + .sessions-day {
        margin-block-start: 0;
    }

    /* The tray: white cards only stand apart on something darker. */
    .sessions-day {
        background: var(--ds-border);
    }

    .sessions-history-wrap {
        overflow: visible;
        padding: 8px 8px 16px;
        border: 0;
        border-radius: 0;
    }

    /* The day: its date and Print, then the count and the total, in the
       cafe's own colour. Its edges line up with the text on the cards. */
    .sessions-day-head {
        position: sticky;
        top: 0;
        z-index: 2;
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto 20px;
        grid-template-areas:
            "date date print"
            "meta total total";
        align-items: center;
        gap: 0 12px;
        margin: 0;
        padding-block: 8px;
        padding-inline: 20px;
        background: color-mix(in srgb, var(--ds-primary) 16%, var(--ds-surface));
        color: color-mix(in srgb, var(--ds-primary) 60%, #000);
    }

    .sessions-day-title {
        display: contents;
    }

    .sessions-day-title strong {
        grid-area: date;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-size: 15px;
        color: inherit;
    }

    .sessions-day-title span {
        grid-area: meta;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        color: inherit;
    }

    .sessions-day-total {
        grid-area: total;
        justify-self: end;
        font-size: 15px;
        font-weight: 700;
        white-space: nowrap;
        color: inherit;
    }

    /* Print is a small printer now, with a finger-sized tap area around it.
       Its name stays in the button for screen readers. */
    .sessions-day-head > .ds-btn {
        grid-area: print;
        justify-self: end;
        position: relative;
        width: 20px;
        height: 20px;
        min-width: 0;
        min-height: 0;
        padding: 0;
        border: 0;
        background: transparent;
        box-shadow: none;
        font-size: 0;
        color: inherit;
    }

    .sessions-day-head > .ds-btn::before {
        content: "";
        position: absolute;
        inset: 1px;
        background: currentColor;
        -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9V3h12v6'/%3E%3Cpath d='M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2'/%3E%3Cpath d='M6 14h12v7H6z'/%3E%3C/svg%3E") center / contain no-repeat;
        mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9V3h12v6'/%3E%3Cpath d='M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2'/%3E%3Cpath d='M6 14h12v7H6z'/%3E%3C/svg%3E") center / contain no-repeat;
    }

    .sessions-day-head > .ds-btn::after {
        content: "";
        position: absolute;
        inset: -12px;
    }

    /* The cards. Row 1 name and sales, row 2 shift and time, row 3 what
       only some shifts have, row 4 the strip. z-index keeps a card's own
       layers inside it, under the sticky day heading. */
    .sessions-day-table,
    .sessions-day-table tbody {
        display: block;
    }

    .sessions-day-table thead {
        display: none;
    }

    .sessions-day-table tbody tr {
        position: relative;
        z-index: 0;
        display: grid;
        grid-template-columns: auto minmax(0, 1fr) auto;
        align-items: center;
        gap: 4px 8px;
        margin-block-end: 8px;
        padding: 12px 12px 0;
        overflow: hidden;
        background: var(--ds-surface);
        border: 1px solid var(--ds-border-strong);
        border-radius: var(--ds-radius-md);
        box-shadow: 0 1px 2px rgba(30, 27, 57, 0.08);
    }

    .sessions-day-table tbody tr:last-child {
        margin-block-end: 0;
    }

    /* The strip, painted behind the cells that sit on it. */
    .sessions-day-table tbody tr::after {
        content: "";
        grid-column: 1 / -1;
        grid-row: 4;
        height: 40px;
        margin-block-start: 4px;
        margin-inline: -12px;
        background: var(--ds-surface-alt);
        border-block-start: 1px solid var(--ds-border-strong);
    }

    .sessions-day-table tbody tr:has(td.is-short) {
        border-color: color-mix(in srgb, var(--ds-danger) 45%, var(--ds-surface));
    }

    .sessions-day-table tbody tr:has(td.is-short)::after {
        background: var(--ds-danger-tint);
        border-block-start-color: color-mix(in srgb, var(--ds-danger) 25%, var(--ds-surface));
    }

    .sessions-day-table tbody tr.is-open,
    .sessions-day-table tbody tr:has(td.is-over) {
        border-color: color-mix(in srgb, var(--ds-success) 45%, var(--ds-surface));
    }

    .sessions-day-table tbody tr.is-open::after,
    .sessions-day-table tbody tr:has(td.is-over)::after {
        background: var(--ds-success-tint);
        border-block-start-color: color-mix(in srgb, var(--ds-success) 25%, var(--ds-surface));
    }

    .sessions-day-table tbody td {
        display: block;
        min-width: 0;
        min-height: 0;
        padding: 0;
        border: 0;
        background: transparent !important;
        font-size: 13px;
        line-height: 20px;
        color: var(--ds-text-primary);
        white-space: nowrap;
    }

    .sessions-day-table tbody td[data-label]::before {
        content: none;
    }

    /* Its chips join the card themselves. */
    .sessions-day-table tbody td:nth-child(1) {
        display: contents;
    }

    .sessions-day-table .sessions-shift-chip {
        grid-column: 1;
        grid-row: 2;
        display: block;
        max-width: 120px;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .sessions-day-table .sessions-pending-chip {
        grid-column: 1 / -1;
        grid-row: 3;
        justify-self: end;
        margin-inline-start: 0;
    }

    .sessions-day-table .sessions-shift-id {
        display: none;
    }

    .sessions-day-table tbody td:nth-child(2) {
        grid-column: 1 / 3;
        grid-row: 1;
        overflow: hidden;
        text-overflow: ellipsis;
        font-size: 16px;
        line-height: 24px;
        font-weight: 700;
    }

    .sessions-day-table tbody td:nth-child(3) {
        grid-column: 2 / -1;
        grid-row: 2;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .sessions-day-table tbody td:nth-child(4) {
        display: none;
    }

    .sessions-day-table tbody td:nth-child(6):not(:nth-last-child(2)) {
        grid-column: 3;
        grid-row: 1;
        font-size: 16px;
        line-height: 24px;
        font-weight: 700;
    }

    /* On the strip: the orders at one end, the drawer at the other. */
    .sessions-day-table tbody td:nth-child(5),
    .sessions-day-table tbody td.sessions-variance {
        z-index: 1;
        grid-column: 1 / -1;
        grid-row: 4;
        margin-block-start: 4px;
    }

    .sessions-day-table tbody td:nth-child(5) {
        justify-self: start;
    }

    .sessions-day-table tbody td.sessions-variance {
        justify-self: end;
        margin-inline-end: 16px; /* leaves the arrow room */
        font-weight: 600;
    }

    /* .ds-tabular runs left to right even in Arabic, for bare numbers. So
       the arrow's room goes on by side, and Simple day's drawer, which is
       words and a figure, reads as Arabic. */
    body[dir="rtl"] .sessions-day-table tbody td.sessions-variance {
        margin-inline: 0;
        margin-left: 16px;
    }

    body[dir="rtl"] .sessions-day-table tbody td.sessions-variance:nth-last-child(2) {
        direction: rtl;
    }

    .sessions-day-table tbody td:nth-child(5)::before,
    .sessions-day-table tbody td.sessions-variance:not(:nth-last-child(2))::before,
    .sessions-day-table tbody td:not(.sessions-variance):not(:nth-child(5)):nth-last-child(2)::before {
        content: attr(data-label) " ";
        font-weight: 400;
        color: var(--ds-text-secondary);
    }

    .sessions-day-table tbody td.is-short {
        color: var(--ds-danger-text);
        font-weight: 700;
    }

    .sessions-day-table tbody td.is-over {
        color: var(--ds-success-text);
        font-weight: 700;
    }

    /* An open shift has no drawer figure yet. */
    .sessions-day-table tr.is-open td.sessions-variance,
    .sessions-day-table tr.is-open td:not(:nth-child(5)):nth-last-child(2) {
        display: none;
    }

    .sessions-day-table tbody td:not(.sessions-variance):not(:nth-child(5)):nth-last-child(2) {
        grid-column: 1 / -1;
        grid-row: 3;
        justify-self: start;
    }

    /* View fills the card, so the whole shift is the button. Its word stays
       in the button for screen readers. */
    .sessions-day-table tbody td:last-child {
        display: contents;
    }

    .sessions-day-table tbody td:last-child .ds-btn {
        position: absolute;
        z-index: 2;
        inset: 0;
        width: 100%;
        height: 100%;
        min-height: 0;
        margin: 0;
        padding: 0;
        border: 0;
        border-radius: 0;
        background: transparent;
        box-shadow: none;
        font-size: 0;
        transform: none;
    }

    .sessions-day-table tbody td:last-child .ds-btn:active {
        background: rgba(15, 23, 42, 0.05);
    }

    .sessions-day-table tbody td:last-child .ds-btn:focus-visible {
        outline-offset: -2px;
    }

    /* The arrow sits on the strip. It is the card's own: drawn inside the
       button, Safari put it at the wrong end. */
    .sessions-day-table tbody tr::before {
        content: "";
        position: absolute;
        bottom: 16px;
        inset-inline-end: 12px;
        width: 8px;
        height: 8px;
        border-block-start: 2px solid var(--ds-text-secondary);
        border-inline-end: 2px solid var(--ds-text-secondary);
        transform: rotate(45deg);
    }

    body[dir="rtl"] .sessions-day-table tbody tr::before {
        transform: rotate(-45deg);
    }
}

@media (max-width: 768px) {

    /* ---------------------------------------------------------------
       22. HEADER BUTTONS UNDER A ROW OF TABS

       On Dashboard the shift chip and "Go to the till" wrapped under the
       period tabs pushed to the right edge, each on a row of its own on
       a small phone. They start at the left like everything else, and
       the main button takes the rest of its row.
       --------------------------------------------------------------- */

    .main-content .ds-page-header-actions:has(> .ds-tabs, > .dash-controls),
    .main-content #pageHeaderActions:has(.dash-controls) {
        justify-content: flex-start;
    }

    .main-content .ds-page-header-actions:has(> .ds-tabs, > .dash-controls) > .ds-btn-primary {
        flex: 1 1 auto;
        justify-content: center;
    }
}

@media (min-width: 769px) and (max-width: 1279px) {

    /* ---------------------------------------------------------------
       23. TABLETS (the sidebar layout below the till's 1520px)

       The Dashboard's period tabs, shift chip and "Go to the till" did
       not wrap, so at 770-900px the button sat past the right edge.
       The Inventory and Products tables are wider than a tablet's page
       and their wrappers did not scroll, so the right-hand columns --
       Receive, Adjust, Edit, Delete -- were cut off with no way to them.
       --------------------------------------------------------------- */

    .main-content .ds-page-header-actions {
        flex-shrink: 1;
        min-width: 0;
        flex-wrap: wrap;
        justify-content: flex-end;
    }

    .inventory-page > #invTabBody > .ds-list-card > .inventory-table-wrap,
    .products-page .products-table-wrap {
        overflow-x: auto;
    }
}

@media (min-width: 769px) and (max-height: 500px) {

    /* ---------------------------------------------------------------
       24. PHONE ON ITS SIDE (wide but short)

       A phone turned sideways gets the sidebar layout with 390px of
       height. The till's order header and footer alone took 410px, so
       the order lines got 16px and Charge sat below the screen with no
       way to it. Here the order scrolls as one list with Charge held
       at the bottom edge, as on the phone's open tray.
       The sidebar's name and Logout covered the last nav icons; both
       are in the top bar's account menu, so they go at this height.
       --------------------------------------------------------------- */

    .pos-terminal #orderPanel {
        overflow-y: auto;
        overscroll-behavior: contain;
    }

    .pos-terminal #orderPanel > * {
        flex: none;
    }

    .pos-terminal #orderItems {
        min-height: 0;
        overflow: visible;
    }

    .pos-terminal .pos-order-footer > .pos-charge-btn {
        position: sticky;
        bottom: 8px;
        z-index: 2;
        box-shadow: 0 0 0 8px var(--ds-surface);
    }

    .pos-terminal .pos-order-footer {
        display: contents;
    }

    .pos-terminal .pos-order-footer > * {
        margin-inline: 16px;
    }

    .pos-terminal .pos-order-footer > .pos-charge-btn {
        margin-block: 8px;
    }

    .pos-terminal .pos-order-footer > :last-child {
        margin-bottom: 12px;
    }

    #sidebar .sidebar-footer .user-badge,
    #sidebar .sidebar-footer .sidebar-logout-btn {
        display: none;
    }

    #sidebar .sidebar-footer:not(:has(> .ds-branch-select:not(.is-hidden))) {
        display: none;
    }
}

@media (max-width: 768px) {

    /* ---------------------------------------------------------------
       25. LOGIN

       Logged out there is no bottom bar (index.html hides it), so the
       room kept for it goes too. The login page fills the screen by
       itself: inside the normal page padding it showed as a pale
       frame and scrolled 25px, and the page spacing pushed the card
       12px below the middle.
       --------------------------------------------------------------- */

    html[data-auth="out"] .main-content {
        padding-bottom: 0;
    }

    html[data-auth="out"] .main-content .page-content {
        padding: 0;
    }

    html[data-auth="out"] .login-pane {
        margin-top: 0;
    }
}
