/*
 * Doctor Phone Pro - mobile shell calibration (v2.2)
 * Loaded after the inline styles. Tailwind (CDN) injects its own <style> later at runtime, so overrides of
 * Tailwind utilities use `:root` for higher specificity instead of !important.
 *
 * 1. Dynamic viewport units: overlays and tall panels follow the *visible* viewport, so the mobile URL bar
 *    collapsing/expanding no longer clips sheets or makes them jump.
 * 2. Safe areas: bottom sheets and fixed bottom bars clear the home-indicator / gesture bar.
 * 3. Scroll containment: dragging an internal list never triggers pull-to-refresh or scroll-chains to the page.
 */

/* 1. dynamic viewport ------------------------------------------------------------------------- */
html { height: 100%; }
body { min-height: 100vh; min-height: 100dvh; }

@supports (height: 100dvh) {
    :root .min-h-screen { min-height: 100dvh; }
    :root .h-screen { height: 100dvh; }
    :root .fixed.inset-0 { height: 100dvh; }
    :root .max-h-\[55vh\] { max-height: 55dvh; }
    :root .max-h-\[60vh\] { max-height: 60dvh; }
    :root .max-h-\[90vh\] { max-height: 90dvh; }
    :root .max-h-\[92vh\] { max-height: 92dvh; }
    :root .max-h-\[94vh\] { max-height: 94dvh; }
    :root .h-\[92vh\] { height: 92dvh; }
}

/* 2. safe areas ---------------------------------------------------------------------------------- */
/* bottom-anchored sheets (overlays that align their panel to the bottom edge) */
:root .fixed.inset-0.items-end > :first-child { margin-bottom: env(safe-area-inset-bottom, 0px); }
/* floating bottom widgets: lift them above the gesture bar (additive: 0 on devices without an inset) */
:root .fixed.bottom-4 { bottom: calc(1rem + env(safe-area-inset-bottom, 0px)); }
:root .fixed.bottom-16 { bottom: calc(4rem + env(safe-area-inset-bottom, 0px)); }
/* (overlay/bar padding is left to the markup: overriding Tailwind padding here would remove spacing on
   devices without a notch; the page itself already pads body with env(safe-area-inset-*)) */

/* 3. scroll containment ------------------------------------------------------------------------- */
.overflow-y-auto, .overflow-auto, .overflow-y-scroll, .history-scroll {
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}
.fixed.inset-0 { overscroll-behavior: contain; }
/* v3.17.5: a small scroller nested INSIDE a card list (the archive card's history box) hands the swipe to the page at its edges: a finger that starts on it is never trapped */
.history-scroll[data-history] { overscroll-behavior: auto; }

/* sync badge states (Saving -> Synced) ---------------------------------------------------------- */
#networkStatusText[data-sync-state="saving"]  { color: #fbbf24; }
#networkStatusText[data-sync-state="synced"]  { color: #34d399; }
#networkStatusText[data-sync-state="offline"] { color: #f87171; }
#networkStatusText[data-sync-state="failed"]  { color: #f87171; }

/* accessibility: honour reduced-motion for the app's decorative animations */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* touch targets (measured with Chromium at 360/390/430 px): enlarge the TAP AREA to >= 44x44 with an invisible
   hit-slop, so the 360 px header keeps its exact layout (no extra width that could overflow) ------------------ */
@media (pointer: coarse) {
    #headerBackBtn, #headerHomeBtn, #headerAdminBadge, #btnHeaderLang, #btnHeaderMessages, #btnHeaderNotifications, #btnHeaderManagement,
    #deviceStationBadge, #btnManualSync, [id^="publicLangBtn_"] { position: relative; }

    /* header icon buttons: sized by the v3.12.5 header block below (42-46 px + 1 px slop = 44 px+ tap area, no overlap with the 4 px gaps) */
    #headerBackBtn::after, #headerHomeBtn::after,
    #btnHeaderMessages::after, #btnHeaderNotifications::after, #btnHeaderManagement::after {
        content: ""; position: absolute; inset: -2px;
    }
    /* small badges / pills */
    #deviceStationBadge::after { content: ""; position: absolute; inset: -2px; }
    #btnManualSync::after { content: ""; position: absolute; inset: -7px -2px; }
    [id^="publicLangBtn_"]::after { content: ""; position: absolute; inset: -10px -2px; }

    /* inputs cannot carry a pseudo-element: give them the height directly */
    #quickDirectCodeInput, #publicSearchInput { min-height: 44px; }
    button[onclick="executeQuickDirectSearch()"] { min-height: 44px; }
}

/* admin floating sync widget (v2.4): it covered the primary right-aligned card actions (e.g. «بيع») in the thumb
   zone. Now a single 44 px round icon on the LEFT edge (RTL: away from primary actions); the textual sync state is
   already shown by the header badge. Tabs get bottom padding so the last card can always scroll clear of it. */
:root #manualSyncContainer { right: auto; left: 10px; }
:root #manualSyncContainer #dataHubSyncIndicator { display: none; }
:root #btnManualSync { width: 44px; height: 44px; padding: 0; border-radius: 999px; justify-content: center; }
:root #btnManualSync span { display: none; }
:root #btnManualSync svg { width: 18px; height: 18px; }
:root #adminApp .tab-content { padding-bottom: 72px; }

/* v3.17.2: the intake chip strip. min-width:0 on every flex ancestor lets the strip SHRINK to the card (a flex item never shrinks below its content unless told so: the widened row was clipped and swallowed the swipe on iOS) */
#repairIssuesListContainer .issue-input-row, #repairIssuesListContainer .issue-input-row > div, #editIssuesListContainer .issue-input-row, #editIssuesListContainer .issue-input-row > div { min-width: 0; }
/* thumb-zone forms (v2.5) ----------------------------------------------------------------------------------------
   intake + edit: every field and button >= 44 px on touch screens, money/phone fields open the numeric keypad,
   the intake Save button stays pinned just above the footer while you scroll the form. */
@media (pointer: coarse) {
    #tab-new input:not([type="checkbox"]):not([type="radio"]), #tab-new select, #tab-new button,
    #adminEditModal input:not([type="checkbox"]):not([type="radio"]), #adminEditModal select, #adminEditModal button { min-height: 44px; }
    /* quick-issue chips: one horizontally scrolling row of 44 px chips instead of a wrapped wall of 22 px pills (v3.17.2: the .dpp-chipstrip rules) */
    #repairIssuesListContainer button[onclick^="setQuickIssueText"], #editIssuesListContainer button[onclick^="setQuickIssueText"] { white-space: nowrap; flex: 0 0 auto; padding-inline: 12px; }
}
:root #btnSaveNewPhone { position: relative; box-shadow: 0 -8px 24px rgba(2, 6, 23, .55); }   /* v3.18.3: the save button stays in its own place at the end of the form (it used to float over the fields while scrolling) */
:root #intakeSubView_form { padding-bottom: calc(112px + env(safe-area-inset-bottom, 0px)); }   /* room below it for the floating back button and the footer badge */
#intakeDraftNote:not(.hidden) { display: flex; }

/* the floating manual-sync button only on the home screen: sync is automatic, and on work screens it covered
   primary actions (the pinned intake Save button, card actions) */
body[data-tab]:not([data-tab="home"]) #manualSyncContainer { display: none !important; }

/* ============================ v3.11.5: viewport stability, no focus auto-zoom, fluid touch scrolling (additive) ============================ */

/* 1a. the 16px field baseline lives at the end of css/ui-polish.css (it must load after the rules it overrides there) */

/* 1c. horizontal lock: width follows the visual viewport. <body> already carries overflow-x-hidden, which the browser propagates to the viewport, so the page cannot drift sideways;
   no overflow is set on <html> or on the app roots on purpose: it would turn them into scroll containers / clip boxes (breaks the sticky headers and the sticky table headers' hit-testing). */
html, body { width: 100%; max-width: 100%; }

/* 2. momentum scrolling + overscroll containment for every scroll surface the app builds (sheets, owner panel body, vault / duties lists, tables, inline overflow); the sheet footer already carries its own safe-area padding */
.dpp-sheet, .dpp-sheet-body, #ownerPanelModal, #ownerPanelModal [data-role="body"], .sp-portal-body, .sp-detail-sheet, .sg-wrap,
[style*="overflow:auto"], [style*="overflow-y:auto"], [style*="overflow: auto"], [style*="overflow-y: auto"] {
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
}
.dpp-sheet, #ownerPanelModal, .fixed.inset-0 { overscroll-behavior-y: contain; }

/* slim, unobtrusive scrollbars: no gutter jump while a thumb flings a list */
.overflow-y-auto, .overflow-auto, .overflow-y-scroll, .history-scroll, .dpp-sheet-body, #ownerPanelModal [data-role="body"],
[style*="overflow:auto"], [style*="overflow-y:auto"], [style*="overflow: auto"], [style*="overflow-y: auto"] {
    scrollbar-width: thin;
    scrollbar-color: rgba(148, 163, 184, .35) transparent;
}
.overflow-y-auto::-webkit-scrollbar, .overflow-auto::-webkit-scrollbar, .history-scroll::-webkit-scrollbar, .dpp-sheet-body::-webkit-scrollbar,
#ownerPanelModal [data-role="body"]::-webkit-scrollbar { width: 4px; height: 4px; }
.overflow-y-auto::-webkit-scrollbar-thumb, .overflow-auto::-webkit-scrollbar-thumb, .history-scroll::-webkit-scrollbar-thumb, .dpp-sheet-body::-webkit-scrollbar-thumb,
#ownerPanelModal [data-role="body"]::-webkit-scrollbar-thumb { background: rgba(148, 163, 184, .35); border-radius: 99px; }
.overflow-y-auto::-webkit-scrollbar-track, .overflow-auto::-webkit-scrollbar-track, .history-scroll::-webkit-scrollbar-track, .dpp-sheet-body::-webkit-scrollbar-track,
#ownerPanelModal [data-role="body"]::-webkit-scrollbar-track { background: transparent; }

/* safe areas on edge-to-edge phones: the last row of a sheet / panel and any fixed bottom bar without its own bottom padding clears the gesture bar */
#ownerPanelModal [data-role="body"] { padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px)) !important; }   /* the panel sets its padding inline */
:root .fixed.bottom-0:not([class*="pb-"]) { padding-bottom: env(safe-area-inset-bottom, 0px); }

/* ============================ v3.11.6: ultra-compact filter / sort strips on phones (additive) ============================
   Chips are drawn 28 px tall (11 px type, 4 px gaps); the TAP area stays 44 px through an invisible hit-slop (::after, -8 px top / bottom) that lives inside the strip's own
   8 px padding (an overflow-x scroller would clip a slop outside it); the matching negative margin gives that padding back to the layout, so a strip costs 28 px, not 44 px.
   The strip itself ignores pointer events (its padding must not swallow taps meant for the search box above it); the chips take them. */
@media (max-width: 768px) {
    :root #tab-active > .glass > * + * { margin-top: .4rem; }
    [role="toolbar"].overflow-x-auto {
        gap: 4px; padding: 8px 4px; margin: -4px -4px -8px; overflow-y: hidden; pointer-events: none;
        -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain; scrollbar-width: none;
    }
    [role="toolbar"].overflow-x-auto::-webkit-scrollbar { display: none; }
    [role="toolbar"].overflow-x-auto > button {
        position: relative; pointer-events: auto; min-height: 0 !important; height: 28px; padding: 0 8px; line-height: 1;
        font-size: 11px; border-radius: 999px; display: inline-flex; align-items: center; gap: 3px;
    }
    [role="toolbar"].overflow-x-auto > button::after { content: ""; position: absolute; inset: -9px 0; }   /* ::after starts at the padding box: -9px = 8 px slop + the 1 px border */
    [role="toolbar"].overflow-x-auto > button .font-mono { font-size: 10px; }
    /* date scope (الكل / اليوم / أسبوع / شهر) */
    [id^="btnActFilter-"] { position: relative; min-height: 0 !important; min-width: 0 !important; height: 28px; padding: 0 10px !important; font-size: 11px; line-height: 1; display: inline-flex; align-items: center; }
    [id^="btnActFilter-"]::after { content: ""; position: absolute; inset: -9px -2px; }
    /* sort bar */
    :root #tab-active #activeSortBar { padding: 2px 6px; gap: 4px; }
    :root #tab-active #activeSortBar select { min-height: 32px; padding: 2px 4px; }
}

/* v3.12.5: header for modern 19.5:9 phones (390-430 px wide, 844-932 px tall) -------------------------------------------------------------------
   One flat row: [back][home] [identity badge, flexible] [device][chat][bell][settings]. Six equal icon buttons (42 px on 360 px phones, 46 px at 430 px)
   with 4 px gaps; the badge takes whatever is left, so nothing can overflow. Heights stay compact (56 px bar); taps are >= 44 px through the 2 px slop. */
.dpp-hdr { --hb: clamp(42px, 11.3vw, 46px); }
.dpp-hdr .dpp-hdr-row { gap: 4px; }
.dpp-hdr .hg { display: contents; }
:root .dpp-hdr .hb { position: relative; display: flex; align-items: center; justify-content: center; flex: 0 0 var(--hb); width: var(--hb); min-width: var(--hb); height: var(--hb); padding: 0; border-radius: 14px; }
:root .dpp-hdr .hb i { font-size: clamp(17px, 4.8vw, 20px); line-height: 1; }
:root .dpp-hdr .hb span:not([id$="Count"]) { display: none; }
:root .dpp-hdr .hb::after { content: ""; position: absolute; inset: -2px; }
.dpp-hdr .dpp-hdr-id { padding: 0; }
:root #headerAdminBadge { height: max(var(--hb), 44px); min-width: 0; width: 100%; padding-inline: 5px; gap: 4px; }
@media (max-width: 370px) { .dpp-hdr { --hb: 40px; } }   /* 360 px phones: 40 px buttons + the 2 px slop = 44 px taps, and the badge keeps room for crown + name */
#headerAdminBadge .fa-fingerprint { display: none; }
#headerAdminNameText { min-width: 0; max-width: none !important; overflow: hidden; text-overflow: ellipsis; font-size: clamp(12px, 3.4vw, 14px); flex: 0 0 auto; }   /* the name never gives room away: the mode label (v3.12.8) is the one that shrinks */
#currentModeLabel { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* v3.19.0: the messages chip left the header (the chat tile has its own counter), so the identity badge shows crown + name | mode glyph + mode name in portrait too; a long mode name shrinks (data-len), it never overflows */
#headerAdminBadge[data-owner="1"] #headerAdminIcon { display: none; }   /* the crown replaces the owner's role icon */
/* the owners' badge: a crown in front of the name, gold edge, and it is the one door to the owners' panel (set by owner-panel.js on a signed-in owner) */
#headerAdminBadge[data-owner="1"] { cursor: pointer; border-color: rgba(251, 191, 36, .55); background: linear-gradient(135deg, rgba(251, 191, 36, .16), rgba(255, 255, 255, .04)); -webkit-tap-highlight-color: transparent; }
#headerAdminBadge[data-owner="1"]:active { transform: scale(.97); }
#headerAdminBadge[data-owner="1"] #headerAdminNameText::before { content: ""; display: inline-block; width: 1.25em; height: 1em; margin-inline-end: 4px; vertical-align: -.12em; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 22'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0' y1='0' x2='1' y2='1'%3E%3Cstop offset='0' stop-color='%23FFF3B8'/%3E%3Cstop offset='.42' stop-color='%23F6C544'/%3E%3Cstop offset='.7' stop-color='%23C58A17'/%3E%3Cstop offset='1' stop-color='%23F2C94C'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M2 6l6.2 5.2L14 2l5.8 9.2L26 6l-2.6 12.6H4.6z' fill='url(%23g)' stroke='%23FFE08A' stroke-width='.8' stroke-linejoin='round'/%3E%3Crect x='4.6' y='18.6' width='18.8' height='2.6' rx='1.1' fill='url(%23g)'/%3E%3Ccircle cx='2.4' cy='5.6' r='1.7' fill='%23FFF3B8'/%3E%3Ccircle cx='14' cy='2.2' r='1.7' fill='%23FFF3B8'/%3E%3Ccircle cx='25.6' cy='5.6' r='1.7' fill='%23FFF3B8'/%3E%3C/svg%3E") center / contain no-repeat; }   /* v3.13.9: a metallic gold vector crown (no emoji) blended into the pill */
#headerAdminBadge[data-owner="1"]:focus-visible { outline: 2px solid #fbbf24; outline-offset: 2px; }
