/* ============================================================================
   NEXPORTAL MOBILE LAYER  (public/css/mobile.css)
   ============================================================================
   Plain CSS, no build step, loaded AFTER every other stylesheet in every layout
   (cache-busted with filemtime). Pairs with public/js/mobile.js.

   Standard: docs/mobile-ux-research.md + its "Round 2" section (COMPACT SCALE):
   body 13/18, dense rows 12.5/17, labels/badges 12/16 (hard floor), h1 17, h2 14.5,
   h3 13, KPI 18. Inputs: 16px text (iOS zoom) in a 36px box, padding 6/10, radius 8.
   Buttons: 32px visible, 13px text, radius 8, invisible >=44px hit area (::after inset -6px).
   Cards: padding 10, radius 8, gap 10; page gutter 12. Top bar 44px.

   RULES OF THE HOUSE
   - Everything that changes layout lives inside @media (max-width: 767px).
     Desktop (>=1024px) must render exactly as before.
   - Selectors use :where() (specificity 0) + !important where an inline style
     or a legacy !important rule has to be beaten. A page can still win with
     a more specific !important rule, or opt out with the attributes below.
   - NEVER set `display` with !important on generic elements: Alpine x-show
     writes display:none inline and would be overridden.

   OPT-OUT / HOOK CLASSES (see also the header of public/js/mobile.js)
     table:  data-no-cards | .mobile-scroll | .mobile-cards | td[data-label] | td[data-m=title|actions|skip]
     modal:  data-no-sheet          grid: data-no-grid | data-grid2
     sticky: data-keep-sticky       text: data-no-floor     tap: data-no-tap
     whole-region opt-out: .m-off

   ROUND 2 HOOKS (page agents: use these exact names; all are phone-only, <768px)
   ---------------------------------------------------------------------------
   .m-ovf                 Overflow menu container (a flex row of buttons/links/forms).
       [data-m-secondary]   child that moves into the "Meer acties" panel (hidden inline on phones).
       [data-m-keep="N"]    on the container: keep first N children visible, rest become secondary.
       .m-ovf-btn           trigger appended by mobile.js (do NOT write it yourself).
       .m-ovf-open          set on the container while the panel is open.
       Secondary items are NOT moved/cloned: forms still submit, Alpine @click still works.
       Panel rows are 40px; a <form data-m-secondary> row = its submit button.
       (Alpine x-show on a secondary item keeps working: inline display:none wins.)
       Add data-m-danger to a secondary item to colour it red.
   .m-page-head           Title left + primary action right. Children: h1 | .m-page-title (flex, clamps 2 lines),
                          .m-page-actions (flex:0 1 auto; holds primary button + optional .m-ovf).
                          Buttons/links inside never clip or get overlapped by icons (inline icon + ellipsis).
   .m-toolbar             Row of controls that scrolls horizontally with a fade edge instead of wrapping.
   .m-wrap-row            Set by mobile.js on any nowrap flex row of >=3 buttons/links that would overflow
                          (wraps with 8px gaps). Opt out with data-no-wrap or .m-toolbar/.m-ovf/.m-seg.
   .m-seg                 Segmented control: equal-width cells (<a>/<button>/<label><input type=radio>).
       .m-seg.m-scroll      variant for >4 items: single scrollable snap row with edge fade.
       active cell:         .active | .is-active | [aria-current] | [aria-selected=true] | [aria-pressed=true] | checked radio.
   .m-choice              Equal-size option cards (FCL / LCL / Consol). Each child is a <label> with a hidden
                          radio, a .m-choice-t (title) and an optional .m-choice-s (one-line muted subtitle).
   .m-card                Compact card (padding 10, radius 8, border).   .m-stack: children get 10px gap.
   .m-bottom-bar          position:fixed action bar above the Safari toolbar / keyboard (safe-area padded);
                          body gets extra bottom padding automatically (via :has).  .m-sticky-bar = in-flow sticky variant.
   td[data-m=skip]        table->card: cell hidden on phones (low-value columns).
   .m-hit                 opt a custom control into the invisible 44px hit area (buttons/links/.m-tap get it already).
   .m-nohit               opt out of the hit-area pseudo-element (e.g. element already uses ::after).
   Vars set by mobile.js: --m-vh (1% of visual viewport height), --m-kb (px of on-screen keyboard covering the
   layout viewport bottom). Bottom sheets use them; never use 100vh for sheet/bar heights.
   Body hooks set by the layouts: .m-tms .m-wms .m-scan .m-portal .m-public .m-guest
   ============================================================================ */

:root {
    --m-fs-title: 17px;
    --m-fs-h2: 14.5px;
    --m-fs-h3: 13px;
    --m-fs-body: 13px;
    --m-fs-dense: 12.5px;
    --m-fs-label: 12px;
    --m-fs-input: 16px;
    --m-fs-kpi: 18px;
    --m-lh-body: 18px;
    --m-lh-dense: 17px;
    --m-lh-label: 16px;
    --m-ctl-h: 36px;
    --m-btn-h: 32px;
    --m-ctl-h-sm: 32px;
    --m-row-h: 40px;
    --m-hit: 44px;
    --m-gutter: 12px;
    --m-gap: 10px;
    --m-pad-card: 10px;
    --m-radius: 8px;
    --m-radius-ctl: 8px;
    --m-hdr-h: calc(44px + env(safe-area-inset-top, 0px));
    --m-line: var(--tms-line, #d7dbe2);
    --m-line-soft: var(--tms-line-soft, #e6e9ee);
    --m-muted: var(--tms-text-muted, #6b7280);
    --m-surface: var(--tms-surface, #fff);
    --m-canvas: var(--tms-canvas, #f5f7fa);
    --m-accent: var(--tms-accent, #8052ff);
    --m-ink: var(--tms-ink, #0d0d12);
}

/* Helper markup that only exists for phones (shown inside the phone media query). */
.m-sortbar { display: none; }
.m-ovf-btn { display: none; }

@media (max-width: 767px) {

    /* ====================================================================
       1. SHELL — the document scrolls (URL bar collapses, keyboard never
          covers a trapped fixed shell), 100dvh with 100vh fallback.
       ==================================================================== */
    html {
        -webkit-text-size-adjust: 100%;
        text-size-adjust: 100%;
    }
    html, body {
        height: auto !important;
        min-height: 100vh;
        min-height: 100dvh;
        overflow-y: visible !important;
        overscroll-behavior: auto !important;
    }
    body { overflow-x: clip; font-size: var(--m-fs-body); line-height: var(--m-lh-body); }
    html.m-lock, html.m-lock body, html.m-menu-lock, html.m-menu-lock body { overflow: hidden !important; overscroll-behavior: contain !important; }
    html.m-lock body { touch-action: none; }

    /* TMS shell: was position:fixed + overflow:hidden (see tms.css §2). */
    .tms-shell {
        position: static !important;
        display: block !important;
        overflow: visible !important;
        min-height: 100vh;
        min-height: 100dvh;
    }
    .tms-main {
        display: flex !important;
        flex-direction: column;
        width: 100% !important;
        min-height: 100vh;
        min-height: 100dvh;
        overflow: visible !important;
        min-width: 0;
    }
    .tms-main main {
        flex: 1 0 auto;
        overflow: visible !important;
        max-width: 100% !important;
        padding: 8px max(var(--m-gutter), env(safe-area-inset-right)) calc(12px + env(safe-area-inset-bottom, 0px)) max(var(--m-gutter), env(safe-area-inset-left)) !important;
    }
    @supports (overflow: clip) {
        .tms-main main { overflow-x: clip !important; }
    }

    /* Slim sticky top bar (<= 48px + notch). display:contents lets the bar
       stick against the whole page instead of only inside <header>. */
    header.tms-header { display: contents; }
    .tms-header-mobile {
        position: sticky;
        top: 0;
        z-index: 30;
        height: var(--m-hdr-h);
        min-height: 0 !important;
        padding: env(safe-area-inset-top, 0px) max(var(--m-gutter), env(safe-area-inset-right)) 0 max(8px, env(safe-area-inset-left)) !important;
        background: var(--m-surface);
        border-bottom: 1px solid var(--m-line);
        box-sizing: border-box;
        flex: none;
        flex-wrap: nowrap !important;
        align-items: center;
        align-content: center;
    }
    html:not(#m) .tms-header-mobile { flex-wrap: nowrap !important; }
    html:not(#m) .tms-header-mobile > * { flex: none !important; width: auto !important; }
    html:not(#m) .tms-header-mobile > form { margin-left: auto; }
    html:not(#m) .tms-header-mobile > a { display: inline-flex; align-items: center; min-height: 44px; }
    .tms-header-mobile button { min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; margin-left: 0 !important; }
    .tms-header-mobile select { height: 32px !important; min-height: 32px !important; padding-top: 0 !important; padding-bottom: 0 !important; font-size: 16px !important; max-width: 46vw !important; }
    .tms-toolbar-mobile {
        flex: none;
        background: var(--m-surface);
        border-bottom: 1px solid var(--m-line);
        padding: 4px max(var(--m-gutter), env(safe-area-inset-right)) 4px max(var(--m-gutter), env(safe-area-inset-left)) !important;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
    }
    .tms-toolbar-mobile::-webkit-scrollbar { display: none; }
    .tms-toolbar-mobile > * { flex: none; }

    /* Footer/status bar: pure desktop chrome. */
    .tms-statusbar { display: none !important; }

    /* Off-canvas drawer + backdrop (Alpine mobileMenuOpen unchanged). */
    .tms-sidebar {
        padding-top: env(safe-area-inset-top, 0px);
        padding-bottom: env(safe-area-inset-bottom, 0px);
        overscroll-behavior: contain;
        max-width: 84vw;
    }
    .tms-backdrop {
        -webkit-backdrop-filter: none !important;
        backdrop-filter: none !important;
        background: rgba(13, 13, 18, 0.5) !important;
    }

    /* Flash bars */
    .flash-bar {
        padding: 8px var(--m-gutter) !important;
        font-size: var(--m-fs-dense) !important;
        line-height: var(--m-lh-dense);
        gap: 8px;
        align-items: flex-start;
    }
    .flash-bar button { min-width: 32px; min-height: 32px; margin: -6px -6px -6px auto; font-size: 20px; line-height: 1; }

    /* Blur is expensive on phones and buys nothing. */
    * { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }

    /* ====================================================================
       2. TYPE — nothing below 12px. Inputs keep 16px (iOS zoom).
       ==================================================================== */
    :where(label) { font-size: var(--m-fs-label); line-height: var(--m-lh-label); font-weight: 500; }
    :where(th) { font-size: var(--m-fs-label); line-height: var(--m-lh-label); }
    :where(small) { font-size: var(--m-fs-label); }

    /* Tailwind arbitrary sizes + legacy inline sizes below the floor. */
    [class*="text-[9px]"], [class*="text-[10px]"], [class*="text-[11px]"],
    [class*="text-[9.5px]"], [class*="text-[10.5px]"], [class*="text-[0.6"], [class*="text-[0.65"], [class*="text-[0.7"],
    [class*="text-2xs"], [class*="text-3xs"],
    [style*="font-size:9px"], [style*="font-size: 9px"], [style*="font-size:9.5px"],
    [style*="font-size:10px"], [style*="font-size: 10px"], [style*="font-size:10.5px"],
    [style*="font-size:11px"], [style*="font-size: 11px"], [style*="font-size:11.5px"],
    [style*="font-size:8px"], [style*="font-size:7px"], [style*="font-size:0.6"], [style*="font-size:.6"], [style*="font-size:0.7"], [style*="font-size:.7"],
    html body .m-fs12 {
        font-size: 12px !important;
        line-height: 16px;
    }
    /* Dense data text (13px) — table cards, lists. */
    :where(.text-xs) { font-size: 12px; line-height: 16px; }

    /* Headings on phones (respect page overrides with classes). */
    :where(main h1) { font-size: var(--m-fs-title); line-height: 22px; }
    :where(main h2) { font-size: var(--m-fs-h2); line-height: 20px; }
    :where(main h3) { font-size: var(--m-fs-h3); line-height: 18px; }
    /* Tailwind text scale, compacted on phones (never touches form controls: they stay 16px). */
    html :is(.text-sm, .text-base):not(input):not(select):not(textarea):not(.m-keep-fs) { font-size: var(--m-fs-body); line-height: var(--m-lh-body); }
    html :is(.text-lg, .text-xl):not(.m-keep-fs) { font-size: var(--m-fs-h2); line-height: 20px; }
    html :is(.text-2xl, .text-3xl):not(.m-keep-fs) { font-size: var(--m-fs-title); line-height: 22px; }
    html :is(.text-4xl, .text-5xl):not(.m-keep-fs) { font-size: 22px; line-height: 26px; }
    /* KPI / big-number tiles */
    :where(.m-kpi, .db-kpi-value, .kpi-value, .stat-value) { font-size: var(--m-fs-kpi); line-height: 22px; }

    /* ====================================================================
       3. CONTROLS — inputs: 16px text in a 36px box; buttons 32px visible with a
          44px hit area (::after inset -6px); 8px radius.
       ==================================================================== */
    html:not(#m) :is(input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="range"]):not([type="file"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]),
           select, textarea) {
        font-size: var(--m-fs-input) !important;
        line-height: 22px !important;
        min-height: var(--m-ctl-h) !important;
        padding-top: 6px !important;
        padding-bottom: 6px !important;
        border-radius: var(--m-radius-ctl) !important;
        max-width: 100%;
        box-sizing: border-box;
    }
    html:not(#m) textarea { min-height: 64px !important; }
    /* Smaller placeholder (the control itself stays 16px so iOS never zooms on focus). */
    ::placeholder { font-size: 13px; }
    /* horizontal padding at specificity 0 so icon-inset classes (pl-8/pl-9, inline padding-left) survive */
    :where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), textarea) { padding-left: 10px; padding-right: 10px; }
    :where(select) { padding-right: 28px !important; text-overflow: ellipsis; }
    html:not(#m) :is(input[type="date"], input[type="time"], input[type="datetime-local"], input[type="month"]) {
        -webkit-appearance: none; appearance: none;
        min-height: var(--m-ctl-h) !important;
        height: var(--m-ctl-h);
    }
    :where(input[type="checkbox"], input[type="radio"]) {
        width: 20px; height: 20px; min-width: 20px; min-height: 20px;
        flex: none;
    }
    :where(input[type="file"]) { font-size: 14px !important; max-width: 100%; }
    :where(input[type="submit"], input[type="button"], input[type="reset"]) {
        min-height: var(--m-ctl-h) !important;
        font-size: var(--m-fs-body) !important;
        min-height: var(--m-btn-h) !important;
        padding: 0 12px;
    }
    html:not(#m) :is(button, [role="button"], .toolbar-btn, .ntm-btn, summary) {
        min-height: var(--m-btn-h) !important;
        font-size: var(--m-fs-body);
        line-height: 18px;
        padding-top: 4px; padding-bottom: 4px;
        border-radius: var(--m-radius-ctl);
        touch-action: manipulation;
    }
    html:not(#m) :is(a[class*="inline-flex"][class*="px-"], a[class*="bg-"][class*="text-white"], a.toolbar-btn, a.ntm-btn) {
        min-height: var(--m-btn-h) !important;
        font-size: var(--m-fs-body);
        line-height: 18px;
        padding-top: 4px; padding-bottom: 4px;
        border-radius: var(--m-radius-ctl);
        touch-action: manipulation;
    }
    /* Invisible >=44px hit area around every 32px control (neighbours keep >=8px gap). */
    html:not(#m) :is(button, [role="button"], .toolbar-btn, .ntm-btn, summary, .m-hit, .m-tap,
                     a[class*="inline-flex"][class*="px-"], a[class*="bg-"][class*="text-white"], a.toolbar-btn, a.ntm-btn):not(.m-nohit):not([data-no-tap]):not(.absolute):not(.fixed):not(.sticky) {
        position: relative;
    }
    html:not(#m) :is(button, [role="button"], .toolbar-btn, .ntm-btn, summary, .m-hit, .m-tap,
                     a[class*="inline-flex"][class*="px-"], a[class*="bg-"][class*="text-white"], a.toolbar-btn, a.ntm-btn):not(.m-nohit):not([data-no-tap])::after {
        content: "";
        position: absolute;
        inset: -6px;
        background: transparent;
    }
    /* absolutely-positioned buttons (close X, row menus) keep their positioning */
    html:not(#m) :is(button, [role="button"]):where(.absolute) { position: absolute; }
    html:not(#m) :is(button, [role="button"]):where(.fixed) { position: fixed; }
    html:not(#m) :is(button, [role="button"]):where(.sticky) { position: sticky; }
    /* Tiny pills / chips must not inherit the 40px button floor. */
    :where(.db-badge, span[class*="px-"][class*="text-"], .badge, .sf-tab-badge) { min-height: 0 !important; min-width: 0; }

    /* JS-marked small tap targets (mobile.js processTaps). */
    html:not(#m) .m-tap { min-height: 32px; min-width: 32px; }
    html:not(#m) .m-tap-inl { padding-block: var(--m-tp, 12px); }

    /* Focus ring that survives the shell change. */
    :where(input, select, textarea, button, a):focus-visible { outline: 2px solid var(--m-accent); outline-offset: 1px; }

    /* Form rhythm: label 4px above field, 12px between fields. */
    :where(label + input, label + select, label + textarea) { margin-top: 4px; }
    :where(main form .mb-4, main form .mb-3) { margin-bottom: 10px; }

    /* ====================================================================
       4. SPACING — kill desktop gutters/gaps that stack into 24-40px.
       ==================================================================== */
    :where(.space-y-6 > * + *, .space-y-5 > * + *) { margin-top: 12px !important; }
    :where(.gap-6, .gap-5) { gap: 12px !important; }
    :where(.p-6, .p-5, .p-4) { padding: var(--m-pad-card) !important; }
    :where(.gap-4) { gap: var(--m-gap) !important; }
    :where(.space-y-4 > * + *) { margin-top: var(--m-gap) !important; }
    :where(.mb-4) { margin-bottom: var(--m-gap) !important; }
    :where(.py-4) { padding-top: 10px !important; padding-bottom: 10px !important; }
    :where(.rounded-lg, .rounded-xl, .rounded-2xl) { border-radius: var(--m-radius) !important; }
    :where(.px-6, .px-5) { padding-left: var(--m-gutter) !important; padding-right: var(--m-gutter) !important; }
    :where(.py-6, .py-5, .py-8) { padding-top: 12px !important; padding-bottom: 12px !important; }
    :where(.mb-6, .mb-5) { margin-bottom: 12px !important; }
    :where(.mt-6, .mt-8) { margin-top: 12px !important; }

    /* Auto-fill card grids with a 300px minimum overflow phones <= 340px. */
    [style*="minmax(240px"], [style*="minmax(260px"], [style*="minmax(280px"], [style*="minmax(300px"], [style*="minmax(320px"], .nx-grid {
        grid-template-columns: minmax(0, 1fr) !important;
    }

    /* ====================================================================
       5. FORM GRIDS (mobile.js sets data-mgrid = 1 | 2)
       ==================================================================== */
    [data-mgrid="1"] { grid-template-columns: minmax(0, 1fr) !important; gap: 8px 12px !important; }
    [data-mgrid="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 8px 12px !important; }
    [data-mgrid] > * { min-width: 0; }

    /* ====================================================================
       6. TABLES -> CARDS  (mobile.js sets table[data-mcards] + td[data-label])
       ==================================================================== */
    html table[data-mcards],
    html table[data-mcards] > tbody,
    html table[data-mcards] > tfoot {
        display: block;
        width: 100% !important;
        min-width: 0 !important;
        max-width: 100% !important;
        border: 0 !important;
        background: transparent !important;
        box-shadow: none !important;
        overflow: visible !important;
    }
    html table[data-mcards] > thead {
        position: absolute !important;
        width: 1px !important; height: 1px !important;
        overflow: hidden !important;
        clip: rect(0 0 0 0);
        white-space: nowrap;
    }
    html table[data-mcards] > tbody > tr,
    html table[data-mcards] > tfoot > tr {
        display: block;
        position: relative;
        background: var(--m-surface) !important;
        border: 1px solid var(--m-line) !important;
        border-radius: var(--m-radius);
        padding: 8px var(--m-pad-card) !important;
        margin: 0 0 6px !important;
        min-height: 0 !important;
        height: auto !important;
    }
    html table[data-mcards] > tbody > tr:hover { background: var(--m-surface) !important; }
    html table[data-mcards] > tbody > tr > td,
    html table[data-mcards] > tbody > tr > th,
    html table[data-mcards] > tfoot > tr > td {
        display: block;
        width: auto !important;
        min-width: 0 !important;
        max-width: none !important;
        padding: 2px 0 !important;
        border: 0 !important;
        background: transparent !important;
        text-align: right !important;
        font-size: var(--m-fs-label) !important;
        line-height: var(--m-lh-label) !important;
        white-space: normal !important;
        overflow-wrap: anywhere;
        word-break: normal;
        position: static !important;
        box-shadow: none !important;
        height: auto !important;
    }
    html table[data-mcards] td[data-label]:not(.m-title):not(.m-actions):not(.m-span)::before {
        content: attr(data-label);
        float: left;
        max-width: 45%;
        margin-right: 12px;
        text-align: left;
        color: var(--m-muted);
        font-size: var(--m-fs-label);
        font-weight: 500;
        line-height: var(--m-lh-label);
        text-transform: none;
        letter-spacing: 0;
    }
    html table[data-mcards] td:not(.m-title)::after { content: ""; display: block; clear: both; }
    /* card title = first cell */
    html table[data-mcards] > tbody > tr > td.m-title {
        text-align: left !important;
        font-size: 13.5px !important;
        line-height: 18px !important;
        font-weight: 600;
        padding: 0 32px 4px 0 !important;
        margin-bottom: 2px;
        border-bottom: 1px solid var(--m-line-soft) !important;
    }
    html table[data-mcards] td.m-title a { display: block; min-height: 20px; }
    html table[data-mcards] > tbody > tr > td.m-title:only-child { border-bottom: 0 !important; margin: 0; padding-bottom: 0 !important; }
    /* actions row */
    html table[data-mcards] > tbody > tr > td.m-actions {
        display: flex;
        flex-wrap: wrap;
        justify-content: flex-end;
        gap: 10px;
        margin-top: 4px;
        padding-top: 6px !important;
        border-top: 1px solid var(--m-line-soft) !important;
    }
    html table[data-mcards] td.m-actions > a,
    html table[data-mcards] td.m-actions > button,
    html table[data-mcards] td.m-actions form,
    html table[data-mcards] td.m-actions form > button { min-height: 32px; min-width: 32px; display: inline-flex; align-items: center; justify-content: center; }
    html table[data-mcards] > tbody > tr > td.m-check {
        position: absolute !important;
        top: 4px; right: 4px;
        width: 36px !important; height: 36px !important;
        padding: 0 !important;
        display: flex; align-items: center; justify-content: center;
    }
    html table[data-mcards] > tbody > tr > td.m-check input { width: 22px; height: 22px; }
    html table[data-mcards] > tbody > tr > td.m-span { text-align: left !important; }
    html table[data-mcards] > tbody > tr > td.m-empty, html table[data-mcards] > tbody > tr > td[data-m="skip"] { display: none; }
    html table[data-mcards] td.hidden, html table[data-mcards] th.hidden, html table[data-mcards] tr.hidden { display: none; }
    html table[data-mcards] td[style*="display: none"], html table[data-mcards] td[style*="display:none"],
    html table[data-mcards] tr[style*="display: none"], html table[data-mcards] tr[style*="display:none"] { display: none; }
    /* wrappers that clipped a table for horizontal scroll must not clip cards */
    :where(.overflow-x-auto, [style*="overflow-x:auto"], [style*="overflow-x: auto"]):has(> table[data-mcards]) { overflow: visible !important; }
    :where(.rounded-sm, .rounded-b-sm, [style*="border-radius:2px"]):has(> table[data-mcards]) { border: 0 !important; background: transparent !important; box-shadow: none !important; }

    /* Sort bar injected above card tables */
    .m-sortbar {
        display: flex; align-items: center; gap: 8px;
        margin: 0 0 8px;
        font-size: var(--m-fs-label);
        color: var(--m-muted);
    }
    .m-sortbar { height: 32px; margin: 0 0 6px; }
    .m-sortbar > span { display: none; }
    html:not(#m):not(#m):not(#m):not(#m) .m-sortbar select {
        flex: 1; min-width: 0; margin: 0 !important;
        height: 32px; min-height: 32px !important; padding: 0 8px !important; line-height: 30px !important;
    }

    /* Tables that stay tables: own scroller + sticky first column. */
    html table[data-mscroll], html table.mobile-scroll {
        display: block;
        max-width: 100%;
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
        border-collapse: separate;
        border-spacing: 0;
    }
    table[data-mscroll] th, table[data-mscroll] td, table.mobile-scroll th, table.mobile-scroll td {
        padding: 6px 8px !important;
        font-size: var(--m-fs-dense) !important;
        white-space: nowrap;
    }
    table[data-mscroll] th, table.mobile-scroll th { font-size: var(--m-fs-label) !important; }
    table[data-mscroll] tr > :first-child, table.mobile-scroll tr > :first-child {
        position: sticky; left: 0; z-index: 2;
        background: var(--m-surface);
        box-shadow: 1px 0 0 var(--m-line-soft);
    }
    /* Any table that scrolls inside its wrapper: compact cells, real min tap rows. */
    :where(.overflow-x-auto, .jc-scroll) table :where(th, td) { padding: 6px 8px; }

    /* ====================================================================
       7. TAB BARS — one line, snap, edge fade, active tab in view
       ==================================================================== */
    html .sf-tab-bar, [role="tablist"], .m-tabs {
        display: flex;
        flex-wrap: nowrap !important;
        overflow-x: auto !important;
        overflow-y: hidden;
        gap: 0;
        scroll-snap-type: x proximity;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        overscroll-behavior-x: contain;
    }
    .sf-tab-bar::-webkit-scrollbar, [role="tablist"]::-webkit-scrollbar, .m-tabs::-webkit-scrollbar { display: none; }
    html .sf-tab-bar {
        position: sticky !important;
        top: var(--m-hdr-h) !important;
        z-index: 25 !important;
        padding: 0 4px !important;
    }
    html .sf-tab-btn, [role="tab"] {
        flex: none;
        min-height: 36px !important;
        padding: 0 10px !important;
        font-size: var(--m-fs-dense) !important;
        scroll-snap-align: center;
        white-space: nowrap;
    }
    .m-seg.m-scroll.m-fade-l { -webkit-mask-image: linear-gradient(to right, transparent 0, #000 20px, #000 calc(100% - 20px), transparent 100%); mask-image: linear-gradient(to right, transparent 0, #000 20px, #000 calc(100% - 20px), transparent 100%); }
    .m-seg.m-scroll:not(.m-fade-l).m-fade-r { -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 20px), transparent 100%); mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 20px), transparent 100%); }
    .m-toolbar.m-fade-l { -webkit-mask-image: linear-gradient(to right, transparent 0, #000 20px, #000 calc(100% - 20px), transparent 100%); mask-image: linear-gradient(to right, transparent 0, #000 20px, #000 calc(100% - 20px), transparent 100%); }
    .m-toolbar:not(.m-fade-l).m-fade-r { -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 20px), transparent 100%); mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 20px), transparent 100%); }
    .sf-tab-bar.m-fade-l { -webkit-mask-image: linear-gradient(to right, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%); mask-image: linear-gradient(to right, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%); }
    .sf-tab-bar:not(.m-fade-l).m-fade-r { -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 24px), transparent 100%); mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 24px), transparent 100%); }
    .sf-tab-bar:not(.m-fade-l):not(.m-fade-r) { -webkit-mask-image: none; mask-image: none; }
    [role="tablist"].m-fade-l, .m-tabs.m-fade-l { -webkit-mask-image: linear-gradient(to right, transparent 0, #000 24px); mask-image: linear-gradient(to right, transparent 0, #000 24px); }
    [role="tablist"].m-fade-r, .m-tabs.m-fade-r { -webkit-mask-image: linear-gradient(to left, transparent 0, #000 24px); mask-image: linear-gradient(to left, transparent 0, #000 24px); }

    /* ====================================================================
       8. MODALS -> BOTTOM SHEETS (mobile.js sets [data-msheet], .m-sheet-panel)
       ==================================================================== */
    [data-msheet] {
        align-items: flex-end !important;
        justify-content: stretch !important;
        padding: 0 !important;
        overscroll-behavior: contain;
        -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
    }
    /* iOS Safari: 100vh/90vh = the LARGE viewport (toolbar hidden) so a 90vh sheet slides
       under the bottom toolbar. Height therefore comes from the VISUAL viewport:
         --m-vh  = visualViewport.height / 100 (set by mobile.js on load/resize/scroll)
         dvh     = native equivalent where supported; min() of both also covers the keyboard.
       --m-kb lifts the sheet above the on-screen keyboard (layout viewport does not shrink on iOS). */
    [data-msheet] > .m-sheet-panel {
        position: fixed !important;
        left: 0 !important; right: 0 !important; top: auto !important;
        bottom: var(--m-kb, 0px) !important;
        width: 100% !important;
        max-width: 100% !important;
        min-width: 0 !important;
        max-height: calc(var(--m-vh, 6px) * 88) !important;
        max-height: min(88dvh, calc(var(--m-vh, 1svh) * 88)) !important;
        margin: 0 !important;
        overflow-y: auto !important;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
        border-radius: 14px 14px 0 0 !important;
        box-sizing: border-box;
        transform: none;
        padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 12px);
        z-index: 51;
    }
    [data-msheet] > .m-sheet-panel:has(.m-sheet-foot) { padding-bottom: 0; }
    [data-msheet] > .m-sheet-panel::before {
        content: "";
        display: block;
        width: 32px; height: 4px;
        margin: 6px auto 0;
        border-radius: 2px;
        background: var(--m-line);
    }
    .m-sheet-foot {
        position: sticky;
        bottom: 0;
        z-index: 2;
        background: var(--m-surface);
        border-top: 1px solid var(--m-line);
        padding: 8px var(--m-gutter) calc(env(safe-area-inset-bottom, 0px) + 12px) !important;
        margin-top: 8px;
        gap: 10px;
    }
    html:not(#m) .m-sheet-foot { flex-wrap: nowrap !important; justify-content: stretch !important; }
    html:not(#m) .m-sheet-foot > * { flex: 1 1 auto; min-width: 0; }
    html:not(#m) .m-sheet-foot > button, html:not(#m) .m-sheet-foot > a { min-height: 40px !important; flex-direction: row !important; align-items: center; justify-content: center; gap: 6px; text-align: center; }
    /* Sheets are read-and-act surfaces: remove desktop widths inside. */
    [data-msheet] .m-sheet-panel [style*="grid-template-columns"] { grid-template-columns: minmax(0, 1fr) !important; }

    /* ====================================================================
       9. STICKY — tall sticky blocks scroll away; short ones clear the top bar
       ==================================================================== */
    .m-unstick { position: static !important; }
    .m-stick-top { top: var(--m-hdr-h) !important; }

    /* ====================================================================
       10. GENERIC COMPONENTS
       ==================================================================== */
    /* Search dropdowns (partner/locode/product/ledger/party): list under the field,
       full field width, 44px rows, readable text. */
    .nx-dd {
        max-height: 50vh !important;
        max-height: 50dvh !important;
        min-width: 100%;
        overscroll-behavior: contain;
    }
    .nx-dd .nx-dd-item, .nx-dd > div { min-height: var(--m-row-h) !important; font-size: var(--m-fs-body) !important; padding: 6px 10px !important; }
    .nx-dd .nx-dd-item > span:last-child { font-size: var(--m-fs-label) !important; }
    /* Global search results + generic absolute lists */
    :where(.absolute.z-50, .absolute.z-40, .absolute.z-30, .absolute.z-20):where(.overflow-y-auto) { max-height: 50dvh; overscroll-behavior: contain; }
    /* Toolbar dropdown menus (export-menu etc.) */
    .nx-menu { min-width: 160px !important; max-width: calc(100vw - 24px); }
    .nx-menu a, .nx-menu button { display: flex !important; align-items: center; min-height: var(--m-row-h); padding-left: 12px !important; padding-right: 12px !important; font-size: var(--m-fs-body) !important; }
    /* Page-level list filter: fill the row */
    .tms-page-search { display: flex; width: 100%; }
    .tms-page-search-input { width: 100% !important; }
    /* action clusters: 2 controls per row instead of 3 wrapped rows */
    .tms-toolbar-mobile .toolbar-btn, .tms-toolbar-mobile a, .tms-toolbar-mobile button { min-height: var(--m-btn-h) !important; }
    /* KPI/stat strips: 2 columns */
    .jc-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
    /* long word safety */
    main :where(td, dd, p, li, h1, h2, h3) { overflow-wrap: anywhere; }
    /* print-only controls */
    button[onclick*="print"] { display: none !important; }

    /* ====================================================================
       11. NON-TMS LAYOUTS
       ==================================================================== */
    /* --- WMS + Scan: chrome ------------------------------------------------ */
    body.m-wms header > div.h-16, body.m-scan header > div.h-16 { height: 48px !important; }
    body.m-wms header, body.m-scan header { padding-top: env(safe-area-inset-top, 0px); }
    body.m-wms main, body.m-scan main {
        padding-top: 12px !important;
        padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px)) !important;
        padding-left: max(var(--m-gutter), env(safe-area-inset-left)) !important;
        padding-right: max(var(--m-gutter), env(safe-area-inset-right)) !important;
    }
    body.m-wms footer { padding-top: 8px; padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px)); font-size: 12px; }
    body.m-wms header a, body.m-wms header button,
    body.m-scan header a, body.m-scan header button {
        min-height: 44px; min-width: 44px;
        display: inline-flex; align-items: center; justify-content: center;
    }
    body.m-scan header nav a, body.m-scan header .flex-1 { min-height: 44px; display: flex; align-items: center; justify-content: center; }
    body.m-scan header .pb-2 { padding-bottom: 8px; }
    /* Scan is one-handed with gloves: primary controls 48px. */
    html:not(#m) body.m-scan :is(button, [role="button"], .btn, summary, input[type="submit"], input[type="button"], a[class*="bg-"], a[class*="border"]):not(header *):not(.scan-nav *):not(.m-ovf-btn) { min-height: 48px !important; }
    html:not(#m) body.m-scan .scan-nav a { min-height: 44px !important; }
    body.m-scan main :where(input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]), select, textarea) { min-height: 48px !important; }
    body.m-wms main :where(a[class*="px-"][class*="py-"], button[class*="px-"]) { min-height: var(--m-ctl-h); display: inline-flex; align-items: center; justify-content: center; }
    body.m-wms .table-scroll, body.m-wms main .overflow-x-auto { -webkit-overflow-scrolling: touch; }
    body.m-wms main h1, body.m-scan main h1 { font-size: var(--m-fs-title); line-height: 22px; }

    /* --- Portal ------------------------------------------------------------ */
    body.m-portal header .py-4 { padding-top: 8px !important; padding-bottom: 8px !important; }
    body.m-portal header nav { row-gap: 0 !important; column-gap: 4px !important; }
    body.m-portal header nav a, body.m-portal header nav button { display: inline-flex; align-items: center; min-height: 40px; padding: 0 8px; }
    body.m-portal main {
        padding: 12px max(var(--m-gutter), env(safe-area-inset-right)) calc(16px + env(safe-area-inset-bottom, 0px)) max(var(--m-gutter), env(safe-area-inset-left)) !important;
    }

    /* --- Guest / app (Breeze) ---------------------------------------------- */
    body.m-guest :where(.px-6) { padding-left: var(--m-gutter) !important; padding-right: var(--m-gutter) !important; }
    body.m-guest a, body.m-guest button { min-height: 44px; }
    body.m-guest a:not([class*="btn"]):not([class*="px-"]) { display: inline-flex; align-items: center; }

    /* --- Public site -------------------------------------------------------- */
    body.m-public header a, body.m-public header button { min-height: 44px; display: inline-flex; align-items: center; }
    body.m-public footer a { display: inline-flex; align-items: center; min-height: 44px; }
    body.m-public main a[class*="btn"], body.m-public main a[class*="px-"], body.m-public main button { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }

    /* Cookie banner: compact, <= ~12% of the viewport, out of the way. */
    #nx-cookie-consent-banner {
        padding: 8px max(12px, env(safe-area-inset-right)) calc(8px + env(safe-area-inset-bottom, 0px)) max(12px, env(safe-area-inset-left)) !important;
        box-shadow: 0 -2px 10px rgba(0, 0, 0, .2) !important;
    }
    #nx-cookie-consent-banner > div { flex-wrap: nowrap !important; gap: 10px !important; align-items: center !important; }
    #nx-cookie-consent-banner p { flex: 1 1 auto !important; font-size: 12px !important; line-height: 16px !important; }
    #nx-cookie-consent-banner > div > div { flex-direction: column; gap: 4px !important; }
    #nx-cookie-consent-banner button { min-height: 36px; padding: 0 12px !important; font-size: 12px !important; white-space: nowrap; }

    /* ====================================================================
       12. ROUND 2 COMPONENTS
       ==================================================================== */

    /* --- dvh overrides for inline/utility vh heights (iOS large-viewport bug) ---------- */
    :is([style*="max-height:90vh"], [style*="max-height: 90vh"], .max-h-\[90vh\]) { max-height: calc(var(--m-vh, 1svh) * 90) !important; max-height: min(90dvh, calc(var(--m-vh, 1svh) * 90)) !important; }
    :is([style*="max-height:85vh"], [style*="max-height: 85vh"]) { max-height: calc(var(--m-vh, 1svh) * 85) !important; max-height: min(85dvh, calc(var(--m-vh, 1svh) * 85)) !important; }
    :is([style*="max-height:80vh"], [style*="max-height: 80vh"]) { max-height: calc(var(--m-vh, 1svh) * 80) !important; max-height: min(80dvh, calc(var(--m-vh, 1svh) * 80)) !important; }
    :is([style*="max-height:calc(100vh - 16px)"], [style*="max-height: calc(100vh - 16px)"]) { max-height: calc(var(--m-vh, 1svh) * 100 - 16px) !important; max-height: min(calc(100dvh - 16px), calc(var(--m-vh, 1svh) * 100 - 16px)) !important; }
    iframe[style*="height: 80vh"], iframe[style*="height:80vh"] { height: calc(var(--m-vh, 1svh) * 80) !important; height: min(80dvh, calc(var(--m-vh, 1svh) * 80)) !important; }

    /* --- 12a. OVERFLOW MENU (.m-ovf) ------------------------------------
       Secondary children are hidden; mobile.js appends ONE .m-ovf-btn. When open, the
       secondary items are laid out as a fixed dropdown panel (mobile.js sets
       --ovf-x/-y/-w/-h on the container and --i on each item). Nothing is moved or cloned. */
    /* Robust hide: !important beats inline display:inline-flex and the 'html:not(#m) .m-page-actions > a'
       rules; the open state / the JS probe (data-m-probe) lift it. Works when .m-ovf IS .m-page-actions. */
    html:not(#m) .m-ovf:not(.m-ovf-open):not([data-m-probe]) > [data-m-secondary],
    html:not(#m) .m-ovf > [data-m-secondary][hidden] { display: none !important; }
    html .m-ovf > .m-ovf-btn {
        display: inline-flex; align-items: center; justify-content: center;
        flex: none; position: relative;
        width: var(--m-btn-h); height: var(--m-btn-h); min-width: var(--m-btn-h); min-height: var(--m-btn-h);
        padding: 0 !important; margin: 0;
        border: 1px solid var(--m-line); border-radius: var(--m-radius-ctl);
        background: var(--m-surface); color: var(--m-ink);
        cursor: pointer; touch-action: manipulation;
    }
    html .m-ovf > .m-ovf-btn[hidden] { display: none; }
    html .m-ovf > .m-ovf-btn::after { content: ""; position: absolute; inset: -6px; }
    .m-ovf-btn svg { width: 16px; height: 16px; pointer-events: none; }
    .m-ovf-btn[aria-expanded="true"] { background: var(--m-canvas); border-color: var(--m-accent); }
    html .m-ovf { gap: 12px; align-items: center; }
    /* the dropdown panel background lives on the container's ::after (z below the items) */
    html .m-ovf.m-ovf-open::after {
        content: "";
        position: fixed;
        left: var(--ovf-x, 8px); top: var(--ovf-y, 8px);
        width: var(--ovf-w, 240px); height: var(--ovf-h, 48px);
        background: var(--m-surface, #fff);
        border: 1px solid var(--m-line);
        border-radius: 10px;
        box-shadow: 0 8px 24px rgba(13, 13, 18, .18);
        z-index: 70;
        pointer-events: none;
    }
    html:not(#m) .m-ovf.m-ovf-open > [data-m-secondary]:not([hidden]) {
        display: flex;
        position: fixed !important;
        left: calc(var(--ovf-x, 8px) + 4px); width: calc(var(--ovf-w, 240px) - 8px);
        top: calc(var(--ovf-y, 8px) + 4px + var(--i, 0) * 40px);
        height: 40px; min-height: 40px !important; margin: 0 !important;
        z-index: 71; box-sizing: border-box;
        align-items: center; justify-content: flex-start;
        padding: 0 10px !important;
        background: transparent !important; border: 0 !important; box-shadow: none !important;
        border-radius: 8px !important;
        color: var(--m-ink) !important; font-size: var(--m-fs-body); line-height: 18px !important; text-align: left;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
        max-width: none !important; width: calc(var(--ovf-w, 240px) - 8px) !important; height: 40px !important;
    }
    /* inline color:#fff (primary-style buttons) must not turn white-on-white inside the panel */
    html:not(#m) .m-ovf.m-ovf-open > [data-m-secondary] :is(svg, span, i, b, strong, em) { color: inherit !important; }
    html .m-ovf.m-ovf-open > [data-m-secondary]::after { display: none; }
    html .m-ovf.m-ovf-open > [data-m-secondary]:is(a, button):active,
    html .m-ovf.m-ovf-open > [data-m-secondary]:is(a, button):focus-visible { background: var(--m-canvas) !important; }
    html .m-ovf.m-ovf-open > form[data-m-secondary] { padding: 0 !important; }
    html:not(#m) .m-ovf.m-ovf-open > form[data-m-secondary] > :is(button, input[type="submit"]) {
        width: 100%; height: 100%; min-height: 40px !important; justify-content: flex-start;
        padding: 0 10px !important; border: 0 !important; background: transparent !important; box-shadow: none !important;
        color: var(--m-ink) !important; font: inherit; text-align: left; border-radius: 8px !important;
    }
    html .m-ovf.m-ovf-open > form[data-m-secondary] > :is(button, input)::after { display: none; }
    html:not(#m) .m-ovf.m-ovf-open > [data-m-danger],
    html:not(#m) .m-ovf.m-ovf-open > form[data-m-danger] > :is(button, input) { color: #b42318 !important; }
    html[data-theme="dark"]:not(#m) .m-ovf.m-ovf-open > [data-m-danger],
    html[data-theme="dark"]:not(#m) .m-ovf.m-ovf-open > form[data-m-danger] > :is(button, input),
    html.dark:not(#m) .m-ovf.m-ovf-open > [data-m-danger],
    html.dark:not(#m) .m-ovf.m-ovf-open > form[data-m-danger] > :is(button, input) { color: #f97066 !important; }
    /* same element as .m-page-actions: keep it one non-wrapping row */
    html:not(#m) .m-page-actions.m-ovf { display: flex; flex-wrap: nowrap; align-items: center; gap: 12px; }

    /* --- 12b. SEGMENTED CONTROL (.m-seg) --------------------------------- */
    .m-seg {
        display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
        height: 32px; box-sizing: border-box;
        border: 1px solid var(--m-line); border-radius: var(--m-radius-ctl);
        background: var(--m-canvas); padding: 2px; gap: 2px;
        overflow: hidden; max-width: 100%;
    }
    html:not(#m) .m-seg > * {
        display: block; position: relative;
        min-width: 0; min-height: 0 !important; height: 26px;
        margin: 0; padding: 0 6px !important;
        border: 0 !important; border-radius: 6px !important;
        background: transparent; color: var(--m-ink);
        font-size: var(--m-fs-dense) !important; font-weight: 500; line-height: 26px !important;
        text-align: center; text-decoration: none;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
        cursor: pointer; box-shadow: none;
    }
    html:not(#m) .m-seg > *::after { inset: -4px 0; }
    .m-seg > * svg, .m-seg > * i { display: inline-block; vertical-align: -2px; margin-right: 4px; flex: none; }
    .m-seg input[type="radio"], .m-seg input[type="checkbox"] {
        position: absolute; opacity: 0; width: 1px; height: 1px; min-height: 0; min-width: 0; margin: 0; pointer-events: none;
    }
    html:not(#m) .m-seg > :is(.active, .is-active, .is-on, [aria-current="page"], [aria-current="true"], [aria-selected="true"], [aria-pressed="true"], :has(input:checked)) {
        background: var(--m-accent); color: #fff; font-weight: 600;
    }
    .m-seg > :focus-within, .m-seg > :focus-visible { outline: 2px solid var(--m-accent); outline-offset: 1px; }
    .m-seg.m-scroll {
        display: flex; grid-auto-flow: initial;
        overflow-x: auto; overflow-y: hidden; scroll-snap-type: x proximity;
        scrollbar-width: none; -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain;
    }
    .m-seg.m-scroll::-webkit-scrollbar { display: none; }
    html:not(#m) .m-seg.m-scroll > * { flex: none; padding: 0 12px !important; scroll-snap-align: center; }

    /* --- 12c. CHOICE CARDS (.m-choice): FCL / LCL / Consol ---------------- */
    .m-choice {
        display: grid; gap: 8px; align-items: stretch;
        grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
    }
    html:not(#m) .m-choice > * {
        position: relative; display: flex; flex-direction: column; justify-content: center; align-items: flex-start; gap: 2px;
        min-width: 0; min-height: 52px !important; margin: 0; padding: 8px 10px !important;
        border: 1px solid var(--m-line) !important; border-radius: var(--m-radius) !important;
        background: var(--m-surface); color: var(--m-ink); text-align: left; cursor: pointer; box-sizing: border-box;
        line-height: 16px !important;
    }
    html:not(#m) .m-choice > *::after { inset: -2px; }
    .m-choice .m-choice-t, .m-choice > * > b, .m-choice > * > strong {
        display: block; max-width: 100%; font-size: var(--m-fs-body); font-weight: 600; line-height: 18px;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .m-choice .m-choice-s, .m-choice > * > small {
        display: block; max-width: 100%; font-size: var(--m-fs-label); font-weight: 400; line-height: 16px; color: var(--m-muted);
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .m-choice input[type="radio"], .m-choice input[type="checkbox"] {
        position: absolute; opacity: 0; width: 1px; height: 1px; min-height: 0; min-width: 0; margin: 0; pointer-events: none;
    }
    html:not(#m) .m-choice > :is(.active, .is-active, .is-on, [aria-checked="true"], [aria-pressed="true"], :has(input:checked)) {
        border-color: var(--m-accent) !important;
        background: color-mix(in srgb, var(--m-accent) 8%, var(--m-surface));
        box-shadow: inset 0 0 0 1px var(--m-accent);
    }
    .m-choice > :focus-within { outline: 2px solid var(--m-accent); outline-offset: 1px; }

    /* --- 12d. PAGE HEADER PATTERN ---------------------------------------- */
    .m-page-head { display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; min-width: 0; margin: 0 0 8px; }
    .m-page-head > :is(h1, h2, .m-page-title) {
        flex: 1 1 40%; min-width: 0; margin: 0;
        display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
        font-size: var(--m-fs-title); line-height: 22px; font-weight: 700;
    }
    .m-page-head > :not(:is(h1, h2, .m-page-title)) { flex: 0 1 auto; min-width: 0; }
    .m-page-head .m-page-actions { display: flex; align-items: center; gap: 12px; flex: 0 1 auto; min-width: 0; }
    /* Buttons/links in headers + toolbars: never clipped mid-word, never overlapped by their icon. */
    html:not(#m) :is(.m-page-head, .m-toolbar, .m-page-actions) > :is(a, button):not(.m-ovf-btn),
    html:not(#m) :is(.m-page-head, .m-toolbar, .m-page-actions) .m-btn {
        display: inline-block; height: var(--m-btn-h); min-width: 0; max-width: 100%;
        padding: 0 12px !important; line-height: 30px !important;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: center; vertical-align: middle;
        box-sizing: border-box;
    }
    html:not(#m) :is(.m-page-head, .m-toolbar, .m-page-actions) > :is(a, button) > :is(svg, i, img) {
        display: inline-block; vertical-align: -3px; flex: none; position: static !important;
        width: 16px; height: 16px; margin: 0 6px 0 0 !important;
    }
    html:not(#m) :is(.m-page-head, .m-toolbar, .m-page-actions) > :is(a, button) > :is(svg, i, img):only-child { margin: 0 !important; }
    html:not(#m) :is(.m-page-head, .m-toolbar, .m-page-actions) > :is(a, button):only-child { max-width: 100%; }
    .m-toolbar {
        display: flex; flex-wrap: nowrap; align-items: center; gap: 10px;
        overflow-x: auto; overflow-y: hidden; padding: 2px 1px; margin: 0 0 8px;
        scrollbar-width: none; -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain; scroll-snap-type: x proximity;
    }
    .m-toolbar::-webkit-scrollbar { display: none; }
    .m-toolbar > * { flex: none; scroll-snap-align: start; }
    /* Generic fix (mobile.js adds .m-wrap-row): a row of >=3 buttons must wrap, not overlap or clip. */
    html .m-wrap-row { flex-wrap: wrap !important; row-gap: 8px; column-gap: 10px; height: auto; }
    html .m-wrap-row > * { flex: 1 1 auto !important; min-width: min-content !important; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }

    /* --- 12e. CARDS / STACKS ---------------------------------------------- */
    .m-card { background: var(--m-surface); border: 1px solid var(--m-line); border-radius: var(--m-radius); padding: var(--m-pad-card); box-sizing: border-box; min-width: 0; }
    .m-stack { display: flex; flex-direction: column; gap: var(--m-gap); }

    /* --- 12f. BOTTOM BARS (never under the Safari toolbar / keyboard) ------- */
    .m-bottom-bar {
        position: fixed; left: 0; right: 0; bottom: var(--m-kb, 0px); z-index: 40;
        display: flex; gap: 10px; align-items: center;
        padding: 8px max(var(--m-gutter), env(safe-area-inset-right)) calc(env(safe-area-inset-bottom, 0px) + 12px) max(var(--m-gutter), env(safe-area-inset-left));
        background: var(--m-surface); border-top: 1px solid var(--m-line);
        box-sizing: border-box;
    }
    .m-bottom-bar > * { flex: 1 1 auto; min-width: 0; }
    body:has(.m-bottom-bar) .tms-main main, body:has(.m-bottom-bar) main { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px) + 12px) !important; }
    .m-sticky-bar {
        position: sticky; bottom: 0; z-index: 20;
        display: flex; gap: 10px; align-items: center;
        padding: 8px 0 calc(env(safe-area-inset-bottom, 0px) + 12px);
        background: var(--m-surface); border-top: 1px solid var(--m-line);
    }
    .m-sticky-bar > * { flex: 1 1 auto; min-width: 0; }
    /* cookie banner + drawer respect the keyboard/toolbar too */
    #nx-cookie-consent-banner { bottom: var(--m-kb, 0px) !important; }
}

/* Phones narrower than 360px: keep the 12px gutter, allow header text to shrink. */
@media (max-width: 359px) {
    .tms-header-mobile { gap: 4px; }
    html table[data-mcards] td[data-label]:not(.m-title):not(.m-actions):not(.m-span)::before { max-width: 40%; }
}

/* Reduced motion: no drawer/sheet animation. */
@media (max-width: 767px) and (prefers-reduced-motion: reduce) {
    .tms-sidebar, [data-msheet] > .m-sheet-panel { transition: none !important; }
}

/* ---------------------------------------------------------------------------
   Tailwind shim (2026-09-21). Production serves a Tailwind build from 2026-08-13
   that does not contain these utilities, and deploys do not rebuild it. Views use
   them, so they are defined here as plain CSS with the same semantics. Remove the
   matching rule once a fresh `npm run build` is deployed and the class is present
   in public/build/assets/*.css.
   --------------------------------------------------------------------------- */
.items-baseline { align-items: baseline; }
.min-h-\[40px\] { min-height: 40px; }
.min-h-\[44px\] { min-height: 44px; }
.min-w-\[110px\] { min-width: 110px; }
.space-y-2\.5 > :not([hidden]) ~ :not([hidden]) { margin-top: 0.625rem; }
.grow { flex-grow: 1; }
.max-w-xs { max-width: 20rem; }
.pr-8 { padding-right: 2rem; }
.pr-9 { padding-right: 2.25rem; }
.z-30 { z-index: 30; }
.touch-none { touch-action: none; } /* handtekening-canvas: vinger tekent i.p.v. scrolt (zending-dossier, portal-verzenden) */
@media (min-width: 640px) {
    .sm\:ml-2 { margin-left: 0.5rem; }
    .sm\:p-6 { padding: 1.5rem; }
}
@media (min-width: 1024px) {
    .lg\:min-h-0 { min-height: 0; }
}
