/* ============================================================
   Inventory Backoffice V2 — Central Design System
   โทน: modern backoffice, clean, premium, warm-coffee primary
   ============================================================ */

/* ---------- Design tokens ----------
   ย้ายไป theme.css (Style Master) แล้ว — แก้สี/โทเค็นทั้งหมดที่ไฟล์นั้นที่เดียว
   site.css ใช้ var(--token) ทั้งหมด ไม่ตั้งค่าสีเองที่นี่ */

html, body {
    height: 100%;
    /* manipulation = ตัด double-tap zoom (ซูมค้างเวลากดปุ่มย้ำ ๆ) แต่ยังเลื่อน/pinch ได้ See LogHistory #24. */
    touch-action: manipulation;
}

body {
    margin: 0;
    color: var(--color-text);
    background: var(--color-bg);
    font-family: var(--ff-sans);
    font-size: var(--fs-base);
    -webkit-font-smoothing: antialiased;
}

a { color: var(--color-primary-hover); }

/* ============================================================
   App shell
   ============================================================ */
.shell-hidden { background: var(--color-bg); }

.app-shell {
    display: flex;
    min-height: 100vh;
}

/* ---------- Sidebar ---------- */
.app-sidebar {
    width: var(--sidebar-width);
    background: var(--sidebar-bg, var(--color-surface));
    border-right: 1px solid var(--color-border);
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    position: sticky;
    top: 0;
    height: 100vh;
    transition: width 0.2s ease;
    z-index: var(--z-drawer);
}

.app-sidebar__brand {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4);
    height: var(--topbar-height);
    border-bottom: 1px solid var(--color-border);
}

.app-sidebar__brand-mark {
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    /* กันลูกในกล่องล้นออกไปรับสัมผัสนอกกรอบ 34px (mask ซ่อนภาพแต่ไม่ตัด hit-test) */
    overflow: hidden;
    /* โลโก้ IconB.svg เป็น mask + เติมสีด้วย gradient แบรนด์ → เปลี่ยนสีตามธีมอัตโนมัติ */
    background: linear-gradient(135deg, var(--brand-start), var(--brand-end));
    -webkit-mask: url("/images/IconB.svg") center / contain no-repeat;
    mask: url("/images/IconB.svg") center / contain no-repeat;
}

.app-sidebar__brand-text { line-height: 1.1; }
.app-sidebar__brand-text strong { font-size: var(--fs-sm); }
.app-sidebar__brand-text small { color: var(--color-muted); font-size: var(--fs-xs); }

/* menu search */
.app-sidebar__search {
    padding: var(--space-3) var(--space-3) var(--space-2);
}
.app-sidebar__search .menu-search {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 0 var(--space-3);
    height: 36px;
}
.app-sidebar__search .menu-search i { color: var(--color-faint); }
.app-sidebar__search .menu-search input {
    border: 0;
    background: transparent;
    outline: none;
    flex: 1;
    font-size: var(--fs-sm);
    color: var(--color-text);
    min-width: 0;
}

/* nav */
.app-sidebar__nav {
    flex: 1;
    overflow-y: auto;
    padding: var(--space-2) var(--space-3) var(--space-4);
    /* ซ่อน scrollbar แต่ยังเลื่อนได้ (Firefox/IE) */
    scrollbar-width: none;
    -ms-overflow-style: none;
}
/* ซ่อน scrollbar (Chrome/Edge/Safari) */
.app-sidebar__nav::-webkit-scrollbar { width: 0; height: 0; display: none; }

.nav-group { margin-top: var(--space-4); }
.nav-group:first-child { margin-top: 0; }

.nav-group__label {
    padding: var(--space-2) var(--space-3);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-faint);
}

/* collapsible group (accordion) — หมวดเมนูพับ/เปิดได้แบบเว็บเดิม */
.nav-group__toggle {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    width: 100%;
    padding: 9px var(--space-3);
    margin-bottom: 2px;
    border: 0;
    background: none;
    border-radius: var(--radius-md);
    color: var(--color-text);
    font-size: var(--fs-sm);
    font-weight: 600;            /* หัวข้อหมวด = ตัวหนา ให้ต่างจากเมนูย่อย */
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s ease, color 0.15s ease;
}
.nav-group__toggle > i:first-child { font-size: 16px; width: 20px; text-align: center; flex-shrink: 0; color: var(--color-muted); }
.nav-group__toggle:hover { background: var(--nav-active-bg); color: var(--nav-active-fg); }
.nav-group__toggle:hover > i:first-child { color: var(--nav-active-fg); }
.nav-group__caret { margin-left: auto; font-size: 12px; color: var(--color-faint); transition: transform 0.15s ease; }
.nav-group--collapsible.is-open > .nav-group__toggle .nav-group__caret { transform: rotate(180deg); }

/* หมวดที่ "เปิดอยู่" = หัวข้อเป็นสีหลัก + ตัวหนาขึ้น ให้เห็นชัดว่าอันไหนกางอยู่ */
.nav-group--collapsible.is-open > .nav-group__toggle {
    color: var(--color-primary-hover);
    font-weight: 700;
}
.nav-group--collapsible.is-open > .nav-group__toggle > i:first-child,
.nav-group--collapsible.is-open > .nav-group__toggle .nav-group__caret {
    color: var(--color-primary-hover);
}

/* เมนูย่อย: เยื้องเข้า + เส้นนำแนวตั้ง ให้เห็นว่าอยู่ใต้หมวด */
.nav-group--collapsible > .nav-group__items {
    display: none;
    margin: 2px 0 var(--space-2) 18px;
    padding-left: 8px;
    border-left: 1.5px solid var(--color-border);
}
.nav-group--collapsible.is-open > .nav-group__items { display: block; }
.nav-group--collapsible .nav-group__items .nav-item { font-size: var(--fs-xs); }
.nav-group--collapsible .nav-group__items .nav-item i { font-size: 14px; }
/* ขณะค้นหาเมนู: บังคับแสดง item ทุกกลุ่ม ไม่สนสถานะพับ */
.app-sidebar__nav.searching .nav-group--collapsible > .nav-group__items { display: block; }
.app-sidebar__nav.searching .nav-group__caret { opacity: 0; }

.nav-item {
    position: relative;                 /* สำหรับแถบ accent ขอบขวา (::after) */
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: 9px var(--space-3);
    border-radius: var(--radius-md);
    color: var(--color-text);
    text-decoration: none;
    font-size: var(--fs-sm);
    margin-bottom: 2px;
    white-space: nowrap;
    transition: background 0.15s ease, color 0.15s ease;
}

.nav-item i { font-size: 16px; width: 20px; text-align: center; flex-shrink: 0; color: var(--color-muted); }

/* hover + หน้าที่เปิดอยู่ = พื้นฟ้าอ่อน + ตัวอักษร/ไอคอนฟ้า + แถบฟ้าขอบขวา */
.nav-item:hover,
.nav-item.active {
    background: var(--nav-active-bg);
    color: var(--nav-active-fg);
}
.nav-item:hover i,
.nav-item.active i { color: var(--nav-active-fg); }

.nav-item.active { font-weight: 700; }

.nav-item:hover::after,
.nav-item.active::after {
    content: "";
    position: absolute;
    right: 0;
    top: 6px;
    bottom: 6px;
    width: 3px;
    border-radius: 3px 0 0 3px;
    background: var(--nav-active-fg);
}

/* sidebar footer (logout) */
.app-sidebar__footer {
    border-top: 1px solid var(--color-border);
    padding: var(--space-3);
}
.nav-item--logout { color: var(--color-danger); }
.nav-item--logout i { color: var(--color-danger); }
.nav-item--logout:hover { background: var(--color-danger-soft); color: var(--color-danger); }

/* collapsed mode (desktop) */
.app-shell.sidebar-collapsed .app-sidebar { width: var(--sidebar-width-collapsed); }
.app-shell.sidebar-collapsed .app-sidebar__brand-text,
.app-shell.sidebar-collapsed .app-sidebar__search,
.app-shell.sidebar-collapsed .nav-group__label,
.app-shell.sidebar-collapsed .nav-group__toggle > span,
.app-shell.sidebar-collapsed .nav-group__caret,
.app-shell.sidebar-collapsed .nav-item span { display: none; }
.app-shell.sidebar-collapsed .nav-item { justify-content: center; padding: 9px 0; }
.app-shell.sidebar-collapsed .nav-item i { width: auto; }
/* โหมดย่อ (icon-only): โชว์ไอคอนเมนูทุกอันเลย ไม่ต้องพับ + ยกเลิกการเยื้อง/เส้นนำ */
.app-shell.sidebar-collapsed .nav-group__toggle { justify-content: center; padding: 9px 0; }
.app-shell.sidebar-collapsed .nav-group__toggle > i:first-child { width: auto; }
.app-shell.sidebar-collapsed .nav-group--collapsible > .nav-group__items {
    display: block;
    margin: 0;
    padding-left: 0;
    border-left: 0;
}

/* drawer backdrop (mobile) */
.app-drawer-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.4);
    z-index: calc(var(--z-drawer) - 1);
    cursor: pointer; /* iOS/iPadOS Safari ยิง click ให้ <div> เฉพาะเมื่อมี cursor:pointer — ไม่งั้นแตะข้างปิด drawer ไม่ได้ */
}

/* ---------- Main + Topbar ---------- */
.app-main {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.app-topbar {
    height: var(--topbar-height);
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 var(--space-5);
    position: sticky;
    top: 0;
    z-index: 100;
    gap: var(--space-4);
}

.app-topbar__left { display: flex; align-items: center; gap: var(--space-3); flex: 0 0 auto; min-width: 0; }
.app-topbar__title { font-weight: 600; font-size: var(--fs-md); min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* desktop: ชื่อหน้าอยู่ต่อจากปุ่มเมนู (ชิดซ้าย) แล้วดันกลุ่มไอคอนขวาไปสุดขอบ
   margin-left ลบ 4px = ชดเชยส่วนต่าง gap ของ app-bar (16) กับ gap ในกลุ่มซ้าย (12) */
.app-topbar__title { margin-right: auto; margin-left: calc(var(--space-3) - var(--space-4)); }
.app-topbar__right { display: flex; align-items: center; gap: var(--space-3); flex: 0 0 auto; }

.topbar-toggle {
    border: 0;
    background: transparent;
    color: var(--color-muted);
    font-size: 20px;
    cursor: pointer;
    width: 44px;
    height: 44px;
    border-radius: var(--radius-md);
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 44px;
    position: relative;
    z-index: 2;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    user-select: none;
    -webkit-user-select: none;
}
.topbar-toggle > i { pointer-events: none; }
.topbar-toggle:hover { background: var(--color-surface-alt); }

/* ปุ่มล็อกการซูม — มีความหมายเฉพาะอุปกรณ์สัมผัส (มือถือ/แท็บเล็ต) จึงซ่อนบนเดสก์ท็อปที่ใช้เมาส์ */
.topbar-zoomlock { display: none; }
@media (pointer: coarse) { .topbar-zoomlock { display: flex; } }
.topbar-zoomlock.is-on { background: var(--color-primary-soft); color: var(--color-primary); }

/* โหมดล็อกซูม: ตัด double-tap zoom โดยไม่กระทบการเลื่อน/แตะปกติ (pinch กันเพิ่มด้วย viewport + JS) */
html.zoom-locked, html.zoom-locked body { touch-action: manipulation; }

.topbar-brand-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--color-primary-soft);
    color: var(--color-primary-hover);
    border-radius: var(--radius-pill);
    padding: 4px 12px;
    font-size: var(--fs-sm);
    font-weight: 600;
}

/* user menu */
.topbar-user { position: relative; }
.topbar-user__btn {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    padding: 4px 10px 4px 4px;
    cursor: pointer;
    color: var(--color-text);
}
.topbar-user__btn:hover { background: var(--color-surface-alt); }
.topbar-user__avatar {
    width: 32px; height: 32px; border-radius: 50%;
    background: linear-gradient(135deg, var(--brand-start), var(--brand-end));
    color: #fff; display: flex; align-items: center; justify-content: center;
    font-size: var(--fs-sm); font-weight: 700; flex-shrink: 0;
}
.topbar-user__name { font-size: var(--fs-sm); font-weight: 600; }
.topbar-user__menu {
    position: absolute;
    right: 0;
    top: calc(100% + 8px);
    min-width: 200px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    padding: var(--space-2);
    display: none;
}
.topbar-user.open .topbar-user__menu { display: block; }
.topbar-user__menu .menu-head { padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--color-border); margin-bottom: var(--space-1); }
.topbar-user__menu .menu-head strong { display: block; font-size: var(--fs-sm); }
.topbar-user__menu .menu-head small { color: var(--color-muted); font-size: var(--fs-xs); }
.topbar-user__menu a {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    color: var(--color-text); text-decoration: none; font-size: var(--fs-sm);
}
.topbar-user__menu a:hover { background: var(--color-surface-alt); }
.topbar-user__menu a.danger { color: var(--color-danger); }

.app-content { padding: var(--space-6); flex: 1; }

/* ============================================================
   Page header + breadcrumb
   ============================================================ */
.page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-4);
    margin-bottom: var(--space-5);
    flex-wrap: wrap;
}
.page-header__title { font-size: var(--fs-xl); font-weight: 700; margin: 0; }
.page-header__subtitle { color: var(--color-muted); font-size: var(--fs-sm); margin: 4px 0 0; }
.breadcrumb-bar { display: flex; gap: 6px; font-size: var(--fs-xs); color: var(--color-faint); margin-bottom: var(--space-2); }
.breadcrumb-bar a { color: var(--color-faint); text-decoration: none; }
.breadcrumb-bar a:hover { color: var(--color-primary-hover); }
.page-header__actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }

/* ============================================================
   Buttons
   ============================================================ */
.btn-app {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    padding: 8px 16px;
    font-size: var(--fs-base);
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease, color 0.15s ease;
    white-space: nowrap;
}
.btn-app:disabled, .btn-app.disabled { opacity: 0.6; cursor: not-allowed; pointer-events: none; }
.btn-app i { font-size: 16px; }

.btn-primary-app { background: var(--color-primary); color: #fff; }
.btn-primary-app:hover { background: var(--color-primary-hover); color: #fff; }

.btn-secondary-app { background: var(--color-neutral-soft); color: var(--color-text); }
.btn-secondary-app:hover { background: #e4e6ec; }

.btn-outline-app { background: transparent; color: var(--color-text); border-color: var(--color-border-strong); }
.btn-outline-app:hover { background: var(--color-surface-alt); }

.btn-danger-app { background: var(--color-danger); color: #fff; }
.btn-danger-app:hover { background: #b53a3a; color: #fff; }

.btn-ghost-app { background: transparent; color: var(--color-muted); }
.btn-ghost-app:hover { background: var(--color-surface-alt); color: var(--color-text); }

.btn-sm-app { padding: 5px 10px; font-size: var(--fs-sm); }
.btn-icon-app {
    width: 34px; height: 34px; padding: 0;
    border-radius: var(--radius-md);
    background: transparent; color: var(--color-muted);
    border: 1px solid transparent;
}
.btn-icon-app:hover { background: var(--color-surface-alt); color: var(--color-text); }

/* ============================================================
   Cards
   ============================================================ */
.card-app {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}
.card-app__header {
    padding: var(--space-4) var(--space-5);
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
}
.card-app__title { font-size: var(--fs-md); font-weight: 600; margin: 0; }
.card-app__body { padding: var(--space-5); }

/* summary / stat card */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--space-4);
}
.stat-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: var(--space-5);
    display: flex;
    align-items: center;
    gap: var(--space-4);
}
.stat-card__icon {
    width: 46px; height: 46px; border-radius: var(--radius-md);
    display: flex; align-items: center; justify-content: center;
    font-size: 22px; flex-shrink: 0;
}
.stat-card__icon.is-primary { background: var(--color-primary-soft); color: var(--color-primary-hover); }
.stat-card__icon.is-success { background: var(--color-success-soft); color: var(--color-success); }
.stat-card__icon.is-warning { background: var(--color-warning-soft); color: var(--color-warning); }
.stat-card__icon.is-info { background: var(--color-info-soft); color: var(--color-info); }
.stat-card__icon.is-danger { background: var(--color-danger-soft); color: var(--color-danger); }
.stat-card__value { font-size: var(--fs-xl); font-weight: 700; line-height: 1.1; }
.stat-card__label { color: var(--color-muted); font-size: var(--fs-sm); margin-top: 2px; }

/* quick action tile */
.quick-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: var(--space-3);
}
.quick-tile {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-4);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    text-decoration: none;
    color: var(--color-text);
    transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
}
.quick-tile:hover { border-color: var(--color-primary); box-shadow: var(--shadow-md); color: var(--color-text); }
.quick-tile i { font-size: 22px; color: var(--color-primary); }
.quick-tile span { font-size: var(--fs-sm); font-weight: 600; }

/* ============================================================
   Filter bar
   ============================================================ */
.filter-bar {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: var(--space-4) var(--space-5);
    margin-bottom: var(--space-5);
}
.filter-bar__row { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: flex-end; }
.filter-bar__actions { margin-left: auto; display: flex; gap: var(--space-2); }

/* ============================================================
   Forms
   ============================================================ */
.form-section { margin-bottom: var(--space-6); }
.form-section__title {
    font-size: var(--fs-md);
    font-weight: 600;
    margin: 0 0 var(--space-4);
    padding-bottom: var(--space-2);
    border-bottom: 1px solid var(--color-border);
}
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: var(--space-4); }
.field__label { font-size: var(--fs-sm); font-weight: 600; color: var(--color-text); }
.field__label .req { color: var(--color-danger); margin-left: 2px; }
.field__helper { font-size: var(--fs-xs); color: var(--color-muted); }
.field__error { font-size: var(--fs-xs); color: var(--color-danger); }

.input-app,
.select-app,
.textarea-app {
    width: 100%;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    padding: 9px 12px;
    font-size: var(--fs-base);
    color: var(--color-text);
    background: var(--color-surface);
    outline: none;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.input-app:focus,
.select-app:focus,
.textarea-app:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--brand-shadow);
}
.input-app:disabled, .select-app:disabled, .textarea-app:disabled {
    background: var(--color-surface-alt);
    color: var(--color-muted);
}
.input-app.is-invalid, .select-app.is-invalid, .textarea-app.is-invalid {
    border-color: var(--color-danger);
}
.textarea-app { min-height: 90px; resize: vertical; }

/* search input with icon */
.search-input { position: relative; }
.search-input i {
    position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
    color: var(--color-faint);
}
.search-input .input-app { padding-left: 36px; }

/* ปุ่มล้างคำค้นหา (✕) — site.js เติมให้อัตโนมัติทุก .search-input */
.search-input.has-clear .input-app { padding-right: 36px; }
.search-input .search-clear {
    position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
    width: 28px; height: 28px; padding: 0;
    display: flex; align-items: center; justify-content: center;
    border: 0; background: transparent; cursor: pointer;
    border-radius: 999px; color: var(--color-faint); font-size: 15px;
}
.search-input .search-clear:hover { background: var(--color-surface-alt); color: var(--color-text); }
/* ไอคอนในปุ่มต้องไหลตามปุ่ม ไม่ใช่ถูกดันไปซ้ายเหมือนไอคอนแว่นขยาย */
.search-input .search-clear i {
    position: static; left: auto; top: auto; transform: none; color: inherit;
}

/* fixed save bar */
/* ===== ปุ่มเลื่อนขึ้นบนสุด (global — อยู่ใน _Layout, init ที่ site.js) =====
   z-index ต่ำกว่า overlay/modal แต่สูงกว่า save-bar (40) ; วางเหนือ save-bar เมื่อหน้ามี save-bar */
.back-to-top {
    position: fixed;
    right: var(--space-4);
    bottom: var(--space-5);
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text);
    box-shadow: 0 4px 14px rgba(15, 23, 42, 0.18);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    cursor: pointer;
    z-index: 60;
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px);
    transition: opacity .18s ease, transform .18s ease, visibility .18s ease;
}
.back-to-top.is-visible { opacity: 1; visibility: visible; transform: translateY(0); }
.back-to-top:hover { background: var(--color-surface-alt); }
.back-to-top:active { transform: translateY(1px); }
/* หน้าที่มีแถบบันทึกติดขอบล่าง → ยกปุ่มขึ้นไม่ให้ทับปุ่มบันทึก */
.back-to-top.has-savebar { bottom: calc(var(--space-5) + 64px); }

/* หัวเอกสาร (Detail) — จอ PC คงรูปแบบเดิม: label บน / ค่าล่าง 4 ช่องต่อบรรทัด ไม่มีเส้นคั่น
   (เท่ากับ row g-3 + col-md-3 + .field__label เดิม) ส่วนมือถือ <=600px จัดใหม่ในบล็อกด้านล่าง */
.docmeta {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-3);
    margin: 0;
}
.docmeta__row { display: block; }
.docmeta dt {
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--color-text);
}
.docmeta dd {
    margin: 0;
    color: var(--color-text);
    font-size: var(--fs-base);
    font-weight: 400;
    word-break: break-word;
}
.docmeta__pending { color: var(--color-faint); }
@media (min-width: 768px) {
    .docmeta { grid-template-columns: repeat(4, 1fr); }
}
.docmeta dd .btn-app { font-weight: 600; }

@media (max-width: 600px) {
    .back-to-top { width: 48px; height: 48px; right: 12px; bottom: 16px; }
    .back-to-top.has-savebar { bottom: 84px; }
}
@media (prefers-reduced-motion: reduce) {
    .back-to-top { transition: none; }
}

.save-bar {
    position: sticky;
    bottom: 0;
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    padding: var(--space-3) var(--space-5);
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2);
    box-shadow: 0 -2px 8px rgba(15, 23, 42, 0.05);
    /* ต้องสูงกว่าแถบ tab/ค้นหาที่ sticky อยู่ด้านบน (z-index 30) — จอเตี้ยสองแถบนี้ทับกัน
       ถ้าต่ำกว่า ปุ่มบันทึกจะจมหายไปใต้แถบ tab จนกดไม่ได้ */
    z-index: 40;
}

/* ============================================================
   Multi-select dropdown (checkbox + ค้นหาได้) — reusable
   ใช้กับ <select multiple data-multiselect> ใดก็ได้
   ============================================================ */
.ms { position: relative; }
.ms__control {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    width: 100%;
    min-height: 40px;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    padding: 7px 12px;
    background: var(--color-surface);
    color: var(--color-text);
    font-size: var(--fs-base);
    cursor: pointer;
    text-align: left;
}
.ms.open .ms__control {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--brand-shadow);
}
.ms__summary { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.ms__summary.is-placeholder { color: var(--color-faint); }
.ms__caret { color: var(--color-faint); font-size: 13px; transition: transform 0.15s ease; }
.ms.open .ms__caret { transform: rotate(180deg); }

.ms__panel {
    position: absolute;
    z-index: 60;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    display: none;
    overflow: hidden;
}
.ms.open .ms__panel { display: block; }
.ms__search { padding: var(--space-2); border-bottom: 1px solid var(--color-border); }
.ms__search .input-app { height: 34px; }
.ms__options { max-height: 240px; overflow-y: auto; padding: var(--space-1); }
.ms__opt {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: 7px 10px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: var(--fs-sm);
}
.ms__opt:hover { background: var(--color-surface-alt); }
.ms__opt input { width: 16px; height: 16px; accent-color: var(--color-primary); flex-shrink: 0; }
.ms__empty { padding: var(--space-4); text-align: center; color: var(--color-muted); font-size: var(--fs-sm); }
.ms__footer {
    display: flex;
    justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border-top: 1px solid var(--color-border);
}
.ms__footer button {
    border: 0;
    background: transparent;
    color: var(--color-primary-hover);
    font-size: var(--fs-sm);
    font-weight: 600;
    cursor: pointer;
    padding: 2px 6px;
    border-radius: var(--radius-sm);
}
.ms__footer button:hover { background: var(--color-surface-alt); }

/* ============================================================
   Searchable single-select dropdown
   ============================================================ */
.ss {
    position: relative;
    width: 100%;
    min-width: 0;
}
.ss__control {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    width: 100%;
    min-height: 42px;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    padding: 8px 12px;
    background: var(--input-face,
        linear-gradient(180deg, rgba(255, 255, 255, 0.95), rgba(250, 249, 247, 0.92)),
        var(--color-surface));
    color: var(--color-text);
    font-size: var(--fs-base);
    font-weight: 600;
    cursor: pointer;
    text-align: left;
    box-shadow: var(--sheen-inset, inset 0 1px 0 rgba(255, 255, 255, 0.75));
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.ss__control:hover {
    border-color: var(--color-primary);
    background: var(--surface-solid, #fff);
}
.ss.open .ss__control {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--brand-shadow);
}
.ss__summary {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
    min-width: 0;
}
.ss__summary.is-placeholder { color: var(--color-faint); }
.ss__caret {
    color: var(--color-faint);
    font-size: 13px;
    transition: transform 0.15s ease, color 0.15s ease;
}
.ss.open .ss__caret,
.ss__control:hover .ss__caret { color: var(--color-primary-hover); }
.ss.open .ss__caret { transform: rotate(180deg); }

.ss__panel {
    position: absolute;
    z-index: 80;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    display: none;
    overflow: hidden;
    animation: dropdown-in 0.14s ease;
}
.ss.open .ss__panel { display: block; }
.ss__search {
    position: relative;
    padding: var(--space-2);
    border-bottom: 1px solid var(--color-border);
    background: var(--color-surface-alt);
}
.ss__search::before {
    content: "\F52A";
    font-family: "bootstrap-icons";
    position: absolute;
    left: 20px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--color-faint);
    font-size: 13px;
    pointer-events: none;
}
.ss__search .input-app {
    height: 36px;
    border-color: var(--color-border);
    border-radius: var(--radius-md);
    padding-left: 32px;
    background: var(--surface-solid, #fff);
}
.ss__options {
    max-height: 252px;
    overflow-y: auto;
    padding: var(--space-1);
}
.ss__opt {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    width: 100%;
    border: 0;
    background: transparent;
    color: var(--color-text);
    text-align: left;
    padding: 9px 10px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: var(--fs-sm);
    font-weight: 600;
    line-height: 1.35;
    transition: background 0.12s ease, color 0.12s ease;
}
.ss__opt::after {
    content: "\F633";
    font-family: "bootstrap-icons";
    color: var(--color-primary-hover);
    font-size: 13px;
    opacity: 0;
}
.ss__opt:hover {
    background: var(--color-surface-alt);
    color: var(--color-primary-hover);
}
.ss__opt.selected {
    background: var(--color-primary-soft);
    color: var(--color-primary-hover);
}
.ss__opt.selected::after { opacity: 1; }
/* แถวที่ไฮไลต์ด้วยคีย์บอร์ด (Enter = เลือกแถวนี้) */
.ss__opt.is-active,
.ms__opt.is-active {
    background: var(--color-surface-alt);
    color: var(--color-primary-hover);
    box-shadow: inset 0 0 0 1.5px var(--color-primary);
}
.ss__opt.selected.is-active { background: var(--color-primary-soft); }
.ss__empty { padding: var(--space-4); text-align: center; color: var(--color-muted); font-size: var(--fs-sm); }

@keyframes dropdown-in {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}

/* custom dropdown ใน container ที่ scroll/clip/transform (เช่น ตาราง bulk, modal panel)
   → panel ถูก portal ไปไว้ที่ <body> แล้ววางแบบ fixed (JS คำนวณ top/left/width) กันถูกตัด/อ้างอิงผิด */
.ss__panel.dd-portal,
.ms__panel.dd-portal {
    position: fixed;
    z-index: 2100;
    display: block;
    max-width: calc(100vw - 16px);
}
.ss__panel.dd-portal .ss__options,
.ms__panel.dd-portal .ms__options {
    max-height: min(252px, calc(100vh - 104px));
}
.ss__opt,
.ms__opt { overflow-wrap: anywhere; }

/* custom dropdown — สถานะ disabled / invalid (mirror จาก <select> ที่ซ่อนไว้) */
.ms.is-disabled .ms__control,
.ss.is-disabled .ss__control,
.ms__control:disabled,
.ss__control:disabled {
    background: var(--color-surface-alt);
    color: var(--color-muted);
    cursor: not-allowed;
    box-shadow: none;
}
.ms.is-disabled .ms__caret,
.ss.is-disabled .ss__caret { opacity: 0.5; }

.ms.is-invalid .ms__control,
.ss.is-invalid .ss__control {
    border-color: var(--color-danger);
}
.ms.is-invalid.open .ms__control,
.ss.is-invalid.open .ss__control {
    box-shadow: 0 0 0 3px var(--color-danger-soft);
}

/* ============================================================
   Date-range picker (custom calendar) — ลากครอบช่วงวันที่ หรือคลิกวันเดียว
   ใช้แทนคู่ <input type="date"> เดิม (ตั้งแต่วันที่ / ถึงวันที่)
   markup: <div class="daterange" data-date-range ...></div> (ดู site.js)
   ============================================================ */
.daterange { position: relative; }

.dr__control {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    min-height: 42px;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    padding: 8px 12px;
    background: var(--input-face,
        linear-gradient(180deg, rgba(255, 255, 255, 0.95), rgba(250, 249, 247, 0.92)),
        var(--color-surface));
    color: var(--color-text);
    font-size: var(--fs-base);
    font-weight: 600;
    cursor: pointer;
    text-align: left;
    box-shadow: var(--sheen-inset, inset 0 1px 0 rgba(255, 255, 255, 0.75));
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.dr__control:hover { border-color: var(--color-primary); background: var(--surface-solid, #fff); }
.daterange.open .dr__control {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--brand-shadow);
}
.dr__icon { color: var(--color-faint); font-size: 15px; flex: none; }
.daterange.open .dr__icon,
.dr__control:hover .dr__icon { color: var(--color-primary-hover); }
.dr__summary {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dr__summary.is-placeholder { color: var(--color-faint); font-weight: 500; }
.dr__clear {
    flex: none;
    border: 0;
    background: transparent;
    color: var(--color-faint);
    cursor: pointer;
    padding: 2px;
    border-radius: var(--radius-sm);
    line-height: 1;
    display: none;
}
.dr__clear:hover { color: var(--color-danger); background: var(--color-danger-soft); }
.daterange.has-value .dr__clear { display: inline-flex; }

.dr__panel {
    position: absolute;
    z-index: 80;
    top: calc(100% + 6px);
    left: 0;
    width: 296px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    display: none;
    padding: var(--space-3);
    animation: dropdown-in 0.14s ease;
    user-select: none;
}
.daterange.open .dr__panel { display: block; }
.dr__panel.dr-portal { position: fixed; z-index: 2100; display: block; }

.dr__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--space-2);
}
.dr__nav {
    border: 1px solid var(--color-border);
    background: var(--color-surface-alt);
    color: var(--color-text);
    width: 30px; height: 30px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.dr__nav:hover { border-color: var(--color-primary); color: var(--color-primary-hover); background: var(--surface-solid, #fff); }
.dr__title { font-weight: 700; font-size: var(--fs-sm); color: var(--color-text); }

.dr__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.dr__wd {
    text-align: center;
    font-size: var(--fs-xs);
    font-weight: 700;
    color: var(--color-muted);
    padding: 4px 0;
}
.dr__day {
    border: 0;
    background: transparent;
    color: var(--color-text);
    height: 34px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: var(--fs-sm);
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.1s ease, color 0.1s ease;
}
.dr__day:hover { background: var(--color-surface-alt); color: var(--color-primary-hover); }
.dr__day--muted { color: var(--color-faint); font-weight: 500; }
.dr__day--today { box-shadow: inset 0 0 0 1px var(--color-primary); }
.dr__day--in-range { background: var(--color-primary-soft); color: var(--color-primary-hover); border-radius: 0; }
.dr__day--start, .dr__day--end {
    background: var(--color-primary);
    color: #fff;
}
.dr__day--start { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.dr__day--end { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.dr__day--single { background: var(--color-primary); color: #fff; border-radius: var(--radius-sm); }
.dr__day--start.dr__day--end { border-radius: var(--radius-sm); }
.dr__day--start:hover, .dr__day--end:hover, .dr__day--single:hover {
    background: var(--color-primary-hover); color: #fff;
}
/* วันที่ถูกปิดไม่ให้เลือก (เช่นวันสิ้นเดือนในใบนับรายวัน) — เทา จาง กดไม่ได้ */
.dr__day--off, .dr__day--off:hover {
    color: var(--color-faint); background: var(--color-surface-alt);
    opacity: .55; cursor: not-allowed; text-decoration: line-through;
}

.dr__foot {
    display: flex;
    gap: var(--space-2);
    margin-top: var(--space-3);
    padding-top: var(--space-2);
    border-top: 1px solid var(--color-border);
}
.dr__preset {
    flex: 1;
    border: 1px solid var(--color-border);
    background: var(--color-surface-alt);
    color: var(--color-text);
    border-radius: var(--radius-sm);
    padding: 7px 8px;
    font-size: var(--fs-xs);
    font-weight: 600;
    cursor: pointer;
    transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.dr__preset:hover { border-color: var(--color-primary); color: var(--color-primary-hover); background: var(--surface-solid, #fff); }
.dr__preset--clear:hover { border-color: var(--color-danger); color: var(--color-danger); background: var(--color-danger-soft); }

/* ============================================================
   Status badges
   ============================================================ */
.badge-app {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    border-radius: var(--radius-pill);
    padding: 3px 10px;
    font-size: var(--fs-xs);
    font-weight: 600;
    line-height: 1.4;
}
.badge-app::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge-success { background: var(--color-success-soft); color: var(--color-success); }
.badge-warning { background: var(--color-warning-soft); color: var(--color-warning); }
.badge-danger { background: var(--color-danger-soft); color: var(--color-danger); }
.badge-info { background: var(--color-info-soft); color: var(--color-info); }
.badge-primary { background: var(--color-primary-soft); color: var(--color-primary-hover); }
.badge-neutral { background: var(--color-neutral-soft); color: var(--color-neutral); }

/* ป้ายสถานะเอกสาร — อ่านง่ายกว่า badge ทั่วไป (ตัวใหญ่ขึ้น + เส้นขอบสีเดียวกับตัวอักษร)
   ใช้คู่กับ .badge-app เช่น <span class="badge-app badge-status badge-warning"> */
.badge-status {
    font-size: var(--fs-sm);
    font-weight: 700;
    padding: 5px 14px;
    border: 1px solid currentColor;
    letter-spacing: .01em;
    white-space: nowrap;
}
.badge-status::before { width: 8px; height: 8px; }

/* ============================================================
   Data table
   ============================================================ */
.table-wrap {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}
.table-scroll { overflow-x: auto; }
.table-app {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-base);
}
.table-app thead th {
    position: sticky;
    top: 0;
    background: var(--color-surface-alt);
    color: var(--color-muted);
    font-weight: 600;
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    text-align: left;
    padding: 11px var(--space-4);
    border-bottom: 1px solid var(--color-border);
    white-space: nowrap;
}
.table-app tbody td {
    padding: 11px var(--space-4);
    border-bottom: 1px solid var(--color-border);
    vertical-align: middle;
}
.table-app tbody tr:last-child td { border-bottom: 0; }
.table-app tbody tr:hover { background: var(--color-surface-alt); }
.table-app .num { text-align: right; font-variant-numeric: tabular-nums; }
.table-app .center { text-align: center; }
/* เลขที่เอกสาร (running no.) — ใช้สีหลักตามธีมให้เด่น (badge/สีอื่นในเซลล์คงสีเดิม) */
.table-app td[data-label="เลขที่เอกสาร"],
.table-app td[data-label="เลขที่เอกสาร"] strong {
    color: var(--color-primary);
    font-weight: 700;
}
.table-app .row-actions { display: flex; gap: 4px; justify-content: flex-end; }
.table-app .row-warning { background: var(--color-warning-soft); }
.table-app .row-danger { background: var(--color-danger-soft); }

/* ===== Generic report table (Reports/View) ===== */
/* กล่องตารางรายงาน scroll เอง (max-height) → หัวตาราง (sticky top:0) ติดอยู่เวลาเลื่อนดูแถวเยอะ */
.report-scroll { max-height: 70vh; overflow: auto; }
.report-scroll .report-table thead th { z-index: 2; }
/* แถบเครื่องมือเหนือตาราง: ช่องกรองในตาราง + ปุ่มส่งออก */
.report-toolbar { display: flex; gap: var(--space-2); align-items: center; margin-left: auto; }
.report-toolbar__search { min-width: 220px; }
/* หัวคอลัมน์คลิกเรียงได้ + ลูกศรบอกทิศทาง */
.report-table thead th { cursor: pointer; user-select: none; }
.report-table thead th.report-table__noaction { cursor: default; }
/* คอลัมน์ "ลำดับ" (เลขรัน) — แคบ สีจาง ไม่ให้แย่งสายตาจากข้อมูลจริง */
.report-table .report-col-no { width: 56px; min-width: 56px; color: var(--color-muted); }
.report-table thead th[data-sort]::after { margin-left: 4px; opacity: 0.8; font-size: 10px; }
.report-table thead th[data-sort="asc"]::after { content: "\25B2"; }
.report-table thead th[data-sort="desc"]::after { content: "\25BC"; }
/* หัวคอลัมน์ที่มีคำอธิบาย (สูตร) — ขีดเส้นใต้ประบอกว่าชี้เพื่อดูได้ */
.report-table thead th.has-tip { text-decoration: underline dotted; text-underline-offset: 3px; }
/* เซลล์ที่คลิกดู transaction ได้ (inventory drill-down) */
.report-table td.cell-drill { cursor: pointer; color: var(--color-primary); text-decoration: underline dotted; text-underline-offset: 3px; }
.report-table td.cell-drill:hover { background: var(--color-surface-alt); }
/* กันคอลัมน์ reflow/ตัดบรรทัดไม่เท่ากันระหว่างโหลดครั้งแรกกับหลังเรียง/กรอง — ความกว้างคงที่ + เลื่อนแนวนอนแทน */
.report-table td { white-space: nowrap; }
/* จำนวนที่บอกทิศทาง (รายงานสรุปใบโอนของ): โอนออก = -N แดง, โอนเข้า = +N เขียว */
.report-table td.val-out { color: var(--color-danger, #b23b3b); font-weight: 600; }
.report-table td.val-in { color: var(--color-success, #2f7d5b); font-weight: 600; }
/* คำอธิบายสีทิศทาง เหนือตาราง */
.report-dir-legend { display: inline-flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); margin-left: var(--space-2); }
.report-dir-legend__item { font-weight: 600; }
.report-dir-legend__item.val-out { color: var(--color-danger, #b23b3b); }
.report-dir-legend__item.val-in { color: var(--color-success, #2f7d5b); }
.report-dir-legend__note { color: var(--color-muted); text-decoration: underline dotted; text-underline-offset: 3px; cursor: help; }
/* คอลัมน์ที่ค่ามีหลายบรรทัด (ต่อด้วย \n เช่น "การจอง" ของ on-hand) — ขึ้นบรรทัดได้ ชิดบน */
.report-table td.cell-preline { white-space: pre-line; vertical-align: top; }
/* คอลัมน์การจอง: ≤3 แสดงในตาราง, เกิน 3 แสดงสรุป (คลิกที่สรุปเพื่อเปิด drawer) */
.report-table td.cell-preline .reserve-list { white-space: pre-line; line-height: 1.5; }
.report-table td.cell-preline .reserve-open {
    background: none; border: 0; padding: 0; cursor: pointer;
    font: inherit; font-weight: 600; color: inherit; text-align: left;
    text-decoration: underline; text-underline-offset: 2px; white-space: nowrap;
}
.report-table td.cell-preline .reserve-open:hover { color: var(--color-primary, #2563eb); }

/* ===== Drawer รายการจอง (on-hand) — เลื่อนจากขวา, non-modal, ไม่บัง grid ===== */
.reserve-drawer {
    position: fixed; top: var(--topbar-height); right: 0; bottom: 0;
    width: min(290px, 92vw);
    background: var(--color-surface);
    border-left: 1px solid var(--color-border);
    box-shadow: -8px 0 24px rgba(0, 0, 0, 0.08);
    transform: translateX(100%);
    transition: transform 0.25s ease;
    z-index: 90; /* ต่ำกว่า topbar (100) แต่เหนือ content */
    display: flex; flex-direction: column;
}
.reserve-drawer.open { transform: translateX(0); }
.reserve-drawer__header {
    display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3);
    padding: var(--space-4); border-bottom: 1px solid var(--color-border);
}
.reserve-drawer__title { font-weight: 600; font-size: var(--fs-md); }
.reserve-drawer__sub { color: var(--color-muted); font-size: var(--fs-sm); margin-top: 2px; word-break: break-word; }
.reserve-drawer__close {
    background: none; border: 0; cursor: pointer; color: var(--color-muted);
    font-size: 18px; line-height: 1; padding: 4px; flex-shrink: 0;
}
.reserve-drawer__close:hover { color: var(--color-text); }
.reserve-drawer__summary {
    padding: var(--space-3) var(--space-4); font-weight: 600;
    background: var(--color-surface-alt); border-bottom: 1px solid var(--color-border);
}
.reserve-drawer__body { flex: 1; overflow: auto; padding: 0 var(--space-4) var(--space-4); }
.reserve-drawer__table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.reserve-drawer__table th {
    position: sticky; top: 0; background: var(--color-surface);
    text-align: left; color: var(--color-muted); font-weight: 600;
    padding: 10px 6px; border-bottom: 1px solid var(--color-border);
}
.reserve-drawer__table td { padding: 8px 6px; border-bottom: 1px solid var(--color-border); }
.reserve-drawer__table .num { text-align: right; font-variant-numeric: tabular-nums; }
/* จอกว้าง: ดันเนื้อหาให้แคบลงแทนที่จะทับ → ดู grid อื่นต่อได้พร้อมกัน */
@media (min-width: 1024px) {
    .app-content.reserve-drawer-push { padding-right: calc(290px + var(--space-6)); transition: padding-right 0.25s ease; }
}
/* คอลัมน์ที่ไม่จำเป็นต้องเห็นเต็ม (เช่น ITEMGROUP) — แคบ + ตัดด้วย ellipsis (ชี้เมาส์ดูเต็มที่ title) */
.report-table th.col-narrow, .report-table td.col-narrow { max-width: 110px; overflow: hidden; text-overflow: ellipsis; }
/* คอลัมน์จำกัดความกว้าง + ตัดขึ้นบรรทัดใหม่เมื่อยาว (เช่น "ชื่อสินค้า") — ไม่ดันตารางกว้าง */
.report-table th.col-wrap, .report-table td.col-wrap { white-space: normal; max-width: 200px; min-width: 130px; word-break: break-word; }
/* รายงาน (on-hand ฯลฯ): ตัวอักษรเล็กลง + แถวกระชับ → เห็นข้อมูลได้มากต่อหน้าจอ */
.report-table { font-size: var(--fs-xs); }
/* หัวคอลัมน์ตารางรายงาน: น้ำตาลเข้มแบบปุ่ม primary (พื้นโทนแบรนด์ + ตัวอักษรขาว) */
.report-table thead th {
    padding: 7px 10px;
    background: var(--color-primary);
    color: #fff;
    border-bottom: 2px solid var(--color-primary-hover);
}
.report-table tbody td { padding: 6px 10px; }
/* เส้นคั่นคอลัมน์แนวตั้งแบบอ่อน (อ่อนกว่าเส้นแถวแนวนอน) — เฉพาะตารางรายงาน, ยกเว้นคอลัมน์สุดท้าย */
.report-table thead th:not(:last-child),
.report-table tbody td:not(:last-child) {
    border-right: 1px solid color-mix(in srgb, var(--color-border) 55%, transparent);
}
/* บนหัวพื้นเข้ม เส้นคั่นใช้ขาวโปร่งให้เห็นบนน้ำตาล */
.report-table thead th:not(:last-child) {
    border-right-color: color-mix(in srgb, #fff 22%, transparent);
}
/* คอลัมน์ระบุตัวตน (สาขา/รหัส/ชื่อ/หน่วย): พื้นอ่อนแบ่งส่วน "รายการ" ออกจาก "ข้อมูลนับ" */
.report-table tbody td.col-ident { background: var(--color-primary-soft); }
.report-table tbody tr:hover td.col-ident { background: color-mix(in srgb, var(--color-primary-soft) 85%, var(--color-primary)); }
/* เส้นแบ่งท้ายบล็อก (หลังคอลัมน์ "หน่วย") ให้ชัด */
.report-table th.col-ident-last,
.report-table td.col-ident-last { border-right: 2px solid var(--color-border-strong); }
/* ตรึงคอลัมน์ระบุตัวตนด้านซ้าย (sticky) เวลาเลื่อนแนวนอน — JS ตั้งค่า left ตามความกว้างจริง */
.report-table th.col-freeze,
.report-table td.col-freeze { position: sticky; z-index: 1; }
.report-table thead th.col-freeze { z-index: 3; }   /* หัว + ตรึง ต้องอยู่บนสุด */
/* ตารางแบบ paged: ปิดการเรียงฝั่ง client (เรียงได้แค่หน้าเดียว ทำให้เข้าใจผิด) */
.report-table--paged thead th { cursor: default; }
/* ตัวควบคุมหน้า (server-side paging) */
.report-pager { justify-content: space-between; }
.report-pager__sizes, .report-pager__nav { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.report-pager__label { color: var(--color-muted); font-size: var(--fs-xs); }
.report-pager__info { color: var(--color-muted); font-size: var(--fs-sm); padding: 0 var(--space-2); white-space: nowrap; }
.report-pager .btn-app[disabled] { opacity: 0.45; pointer-events: none; }

/* modal กว้าง + ปุ่มปิด (ใช้กับ drill-down รายการ transaction) */
.modal-app--wide { max-width: 680px; }
.modal-app--wide .modal-app__header { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.modal-app--wide .modal-app__body { max-height: 70vh; overflow: auto; }
/* modal ขนาดใหญ่ (ตารางหลายคอลัมน์ เช่น กู้คืน Item) — ใช้คู่กับ .modal-app--wide */
.modal-app--xl { max-width: 1040px; }
/* บังคับความกว้างด้วย ID (specificity สูงกว่า .modal-app ที่นิยามทีหลังในไฟล์ ไม่งั้นถูก override กลับเป็น 420px) */
#recoverBackdrop .modal-app { max-width: 1040px; }
/* modal drill-down รายการเอกสาร (inventory transaction + ใบนับของรายงาน sum-stock) — เหตุผลเดียวกับข้างบน */
#invTranBackdrop .modal-app { max-width: min(940px, 94vw); }
#invTranBackdrop .modal-app__body { max-height: 72vh; overflow: auto; }
/* modal ประวัติ Refresh Token (/MainData/RevokeToken) — กว้างตามขนาดข้อมูลจริง ไม่ยืดเต็มกรอบเมื่อคอลัมน์สั้น */
#historyBackdrop .modal-app { width: fit-content; min-width: min(620px, 96vw); max-width: min(1180px, 96vw); }
#historyBackdrop .modal-app__body { max-height: 74vh; overflow: hidden; }
/* จอเล็กใช้โหมดการ์ด (.table-cards) ที่ต้องตัดบรรทัดได้ → บังคับ nowrap เฉพาะโหมดตาราง */
@media (min-width: 601px) {
    #historyBackdrop .table-app th,
    #historyBackdrop .table-app td { white-space: nowrap; }
    #historyBackdrop .table-app td.cell-device { max-width: 340px; overflow: hidden; text-overflow: ellipsis; }
}

/* modal รายละเอียดการถอยสถานะ (/Reports/Rollbacks) — เหตุผลเดียวกับข้างบน */
#rbBackdrop .modal-app { max-width: min(980px, 94vw); }
#rbBackdrop .modal-app__body { max-height: 72vh; overflow: auto; }
.modal-app__close { background: none; border: 0; color: var(--color-muted); cursor: pointer; font-size: 16px; line-height: 1; padding: 4px; }
.modal-app__close:hover { color: var(--color-text); }

.item-list-table {
    font-size: 12px;
}
.item-list-table thead th {
    padding: 8px 12px;
    font-size: 10px;
}
.item-list-table tbody td {
    padding: 8px 12px;
    line-height: 1.35;
}
.item-list-table tbody td[data-label="Code"] {
    font-size: 11px;
    line-height: 1.3;
}
.item-list-table tbody td:nth-child(3),
.item-list-table tbody td:nth-child(4),
.item-list-table tbody td:nth-child(5) {
    font-size: 12px;
}
.item-list-table tbody td[data-label=""] img {
    width: 34px !important;
    height: 34px !important;
}
.item-list-table .badge-app {
    font-size: 11px;
    padding: 4px 9px;
}
.item-list-table .btn-icon-app {
    width: 28px;
    height: 28px;
    font-size: 13px;
}

/* ปุ่ม action ในแถวรายการ (ดูรายละเอียด/แก้ไข/ลบ...) — ไอคอน + คำกำกับ แบบคอมแพกต์
   ใช้ค่า title เดิมเป็น label ผ่าน ::after จึงไม่ต้องแก้ทุกปุ่มในทุกหน้า */
.row-actions .btn-icon-app {
    width: auto;
    height: 30px;
    padding: 0 11px;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-surface);
    color: var(--color-muted);
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1;
}
.row-actions .btn-icon-app > i { font-size: 13px; line-height: 1; }
.row-actions .btn-icon-app::after {
    content: attr(title);
    white-space: nowrap;
}
.row-actions .btn-icon-app:hover {
    border-color: var(--color-border-strong);
    background: var(--color-surface-alt);
    color: var(--color-text);
}
/* โทนอันตรายบาง ๆ สำหรับปุ่มลบ/ยกเลิก (จับจาก class/ไอคอน ที่ใช้อยู่เดิม) */
.row-actions .btn-icon-app.is-danger,
.row-actions .btn-icon-app[data-cancel],
.row-actions .btn-icon-app[class*="-delete"],
.row-actions .btn-icon-app:has(> i.bi-trash) {
    color: var(--color-danger);
}
.row-actions .btn-icon-app.is-danger:hover,
.row-actions .btn-icon-app[data-cancel]:hover,
.row-actions .btn-icon-app[class*="-delete"]:hover,
.row-actions .btn-icon-app:has(> i.bi-trash):hover {
    background: var(--color-danger-soft);
    border-color: var(--color-danger);
    color: var(--color-danger);
}
/* มือถือ: ให้ปุ่ม action ห่อบรรทัดได้ ไม่ดันตารางล้น */
@media (max-width: 992px) {
    .table-app .row-actions { flex-wrap: wrap; gap: 6px; }
}

/* ค่าหลาย ๆ บรรทัดในเซลล์เดียว (เช่น เลขที่ส่ง + Pick) ให้ซ้อนกันแนวตั้งเสมอ
   — ในโหมดการ์ด <td> เป็น flex row ทำให้ <br> ถูกละเลย จึงต้องหุ้มด้วย .cell-stack */
.cell-stack { display: flex; flex-direction: column; gap: 2px; }

/* ปุ่ม "ดูรายละเอียด" หน้าใบส่งของ — ใส่โทนสีหลักให้เด่นขึ้น */
.row-actions .ship-detail-btn {
    color: var(--color-primary-hover);
    border-color: var(--color-primary);
    background: var(--color-primary-soft);
}
.row-actions .ship-detail-btn:hover {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

.bool-mark {
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    color: #fff;
    font-size: 17px;
    line-height: 1;
    box-shadow: inset 0 -1px 0 rgba(15, 23, 42, 0.12);
}
.bool-mark.is-yes { background: #22c55e; }
.bool-mark.is-no { background: #ef4444; }

.item-list-table .bool-mark {
    width: 26px;
    height: 26px;
    font-size: 15px;
}

/* card เดียวต่อช่อง — ไว้เช็คคร่าวๆ ไม่ต้องเด่น (1 บรรทัดต่อ template: "SiteType : คลัง") */
.order-card {
    display: inline-block;
    max-width: 180px;
    padding: 3px 7px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface-alt);
    font-size: 10px;
    line-height: 1.35;
    color: var(--color-muted);
}
.order-card__line {
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.order-card-empty { color: var(--color-faint); font-weight: 600; }

/* sortable header */
.th-sort { cursor: pointer; user-select: none; }
.th-sort i { font-size: 12px; opacity: 0.5; }

/* pagination */
.pagination-app {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-top: 1px solid var(--color-border);
    flex-wrap: wrap;
}
.pagination-app__info { font-size: var(--fs-sm); color: var(--color-muted); }
.pagination-app__pages { display: flex; gap: 4px; }
.pagination-app__pages a, .pagination-app__pages span {
    min-width: 32px; height: 32px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: var(--fs-sm);
    color: var(--color-text);
    text-decoration: none;
    padding: 0 6px;
}
.pagination-app__pages a:hover { background: var(--color-surface-alt); }
.pagination-app__pages .active { background: var(--color-primary); color: #fff; border-color: var(--color-primary); }
.pagination-app__pages .disabled { opacity: 0.4; pointer-events: none; }

/* ============================================================
   Empty state
   ============================================================ */
.empty-state {
    text-align: center;
    padding: var(--space-8) var(--space-5);
    color: var(--color-muted);
}
.empty-state i { font-size: 40px; color: var(--color-faint); }
.empty-state__title { font-size: var(--fs-md); font-weight: 600; color: var(--color-text); margin: var(--space-3) 0 var(--space-1); }
.empty-state__text { font-size: var(--fs-sm); margin-bottom: var(--space-4); }

/* loading skeleton + overlay */
.skeleton {
    background: linear-gradient(90deg, #eceef3 25%, #f4f5f8 37%, #eceef3 63%);
    background-size: 400% 100%;
    animation: skeleton 1.2s ease infinite;
    border-radius: var(--radius-sm);
    height: 14px;
}
@keyframes skeleton { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }

.loading-overlay {
    position: absolute;
    inset: 0;
    background: var(--overlay-scrim, rgba(255, 255, 255, 0.7));
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 30;
}
.loading-overlay.show { display: flex; }
.spinner-app {
    width: 36px; height: 36px;
    border: 3px solid var(--color-border-strong);
    border-top-color: var(--color-primary);
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ============================================================
   Global loading overlay — เต็มหน้าจอ (fixed)
   ควบคุมด้วย window.appLoading.show()/.hide() + auto ตอน navigate
   ============================================================ */
.app-loading {
    position: fixed;
    inset: 0;
    z-index: var(--z-loading);
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    background: var(--overlay-scrim, rgba(255, 255, 255, 0.62));
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
}
.app-loading.show { display: flex; }
/* is-nav = overlay ของ "กำลังโหลดหน้า" (initNavLoading) ซึ่งแตะ/คลิกเพื่อปิดได้
   ต้องมี cursor:pointer ไม่งั้น iOS/iPad Safari ไม่ยิง click ให้ div → ปิดไม่ได้
   (overlay ของ mutation ไม่มีคลาสนี้ = ปิดเองไม่ได้ตามเจตนา) */
.app-loading.is-nav { cursor: pointer; }
.app-loading__spinner {
    width: 44px; height: 44px;
    border: 4px solid var(--color-border-strong);
    border-top-color: var(--color-primary);
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
}
.app-loading__text {
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--color-text-strong, #1f2430);
}
@media (prefers-reduced-motion: reduce) {
    .app-loading__spinner { animation-duration: 1.6s; }
}

/* ============================================================
   Toast
   ============================================================ */
.toast-stack {
    position: fixed;
    top: 20px;
    right: 20px;
    z-index: var(--z-toast);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    max-width: 360px;
}
.toast-app {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-neutral);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    padding: var(--space-3) var(--space-4);
    animation: toast-in 0.2s ease;
}
@keyframes toast-in { from { opacity: 0; transform: translateX(12px); } to { opacity: 1; transform: none; } }
.toast-app.is-success { border-left-color: var(--color-success); }
.toast-app.is-error { border-left-color: var(--color-danger); }
.toast-app.is-warning { border-left-color: var(--color-warning); }
.toast-app.is-info { border-left-color: var(--color-info); }
.toast-app__icon { font-size: 18px; }
.toast-app.is-success .toast-app__icon { color: var(--color-success); }
.toast-app.is-error .toast-app__icon { color: var(--color-danger); }
.toast-app.is-warning .toast-app__icon { color: var(--color-warning); }
.toast-app.is-info .toast-app__icon { color: var(--color-info); }
.toast-app__body { flex: 1; font-size: var(--fs-sm); }
.toast-app__close { border: 0; background: transparent; color: var(--color-faint); cursor: pointer; font-size: 14px; }

/* inline alert */
.alert-app {
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
    font-size: var(--fs-sm);
    display: flex;
    gap: var(--space-2);
    align-items: flex-start;
    border: 1px solid transparent;
}
.alert-app.is-info { background: var(--color-info-soft); color: #1c4fb3; border-color: #cfdcfb; }
.alert-app.is-success { background: var(--color-success-soft); color: #137a52; border-color: #c6ebd9; }
.alert-app.is-warning { background: var(--color-warning-soft); color: #946700; border-color: #f3e0b5; }
.alert-app.is-danger { background: var(--color-danger-soft); color: #a93232; border-color: #f5c2c0; }

/* ============================================================
   Confirm modal (uses native <dialog> fallback styling)
   ============================================================ */
.modal-backdrop-app {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.45);
    display: none;
    align-items: center;
    justify-content: center;
    /* modal ทั่วไปอยู่ต่ำกว่า dropdown/date portal (2100) เพื่อให้ dropdown ในโมดอลแสดงทับโมดอลได้
       (เดิมใช้ --z-confirm=2200 ทำให้ panel ที่ portal ไป body ถูกโมดอลบัง มองไม่เห็นตัวเลือก) */
    z-index: var(--z-modal);
    padding: var(--space-4);
    cursor: pointer; /* iOS/iPadOS Safari ยิง click ให้ backdrop <div> เฉพาะเมื่อมี cursor:pointer — ไม่งั้นแตะนอกกล่องปิดโมดอลไม่ได้ */
}
.modal-backdrop-app.show { display: flex; }
.modal-backdrop-app .modal-app { cursor: auto; } /* คืน cursor ปกติภายในกล่อง (การแตะในกล่องไม่ปิดอยู่แล้ว) */
/* กล่องยืนยัน (appConfirm) ต้องอยู่บนสุดเสมอ — เหนือทั้ง modal และ dropdown portal */
#confirmBackdrop.modal-backdrop-app { z-index: var(--z-confirm); }
.modal-app {
    background: var(--color-surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    width: 100%;
    max-width: 420px;
    overflow: hidden;
    animation: toast-in 0.18s ease;
}
.modal-app__header { padding: var(--space-5) var(--space-5) 0; }
.modal-app__title { font-size: var(--fs-lg); font-weight: 700; margin: 0; display: flex; align-items: center; gap: var(--space-2); }
.modal-app__body { padding: var(--space-3) var(--space-5) var(--space-5); color: var(--color-muted); font-size: var(--fs-base); }
/* appConfirm ตั้งข้อความด้วย textContent → ต้อง pre-line ให้ \n ในข้อความขึ้นบรรทัดใหม่จริง
   (ข้อความที่ไม่มี \n เรนเดอร์เหมือนเดิมทุกประการ เพราะ pre-line ยังยุบช่องว่างซ้ำ) */
#confirmMessage { white-space: pre-line; }
.modal-app__footer { padding: var(--space-4) var(--space-5); background: var(--color-surface-alt); display: flex; justify-content: flex-end; gap: var(--space-2); }

/* โมดัลยืนยันการสั่ง RQ/PR — เลขเอกสารเป็นบรรทัดรอง + ตัวเลือก "ส่ง AX ทันที" เป็นการ์ดติ๊กได้ */
.stage-ax__docno {
    display: inline-flex; align-items: center; gap: 6px;
    margin: 4px 0 0; font-size: var(--fs-sm); color: var(--color-muted);
}
.stage-ax__docno strong { color: var(--color-text); font-weight: 700; letter-spacing: .2px; }
.stage-ax__note { font-size: var(--fs-sm); line-height: 1.55; margin: 0; }
.stage-ax__opt {
    display: flex; gap: 12px; align-items: flex-start;
    margin: var(--space-4) 0 0; padding: 12px 14px;
    border: 1px solid var(--color-border); border-radius: var(--radius-md);
    cursor: pointer; transition: border-color .15s ease, background .15s ease;
}
.stage-ax__opt:hover { border-color: var(--color-border-strong); background: var(--color-surface-alt); }
.stage-ax__opt.is-checked { border-color: var(--color-primary); background: var(--color-primary-soft); }
.stage-ax__opt input { width: 18px; height: 18px; margin: 2px 0 0; flex: 0 0 auto; accent-color: var(--color-primary); cursor: pointer; }
.stage-ax__opt-title { display: flex; align-items: center; gap: 6px; font-size: var(--fs-base); font-weight: 600; color: var(--color-text); }
.stage-ax__opt-desc { margin: 5px 0 0; font-size: var(--fs-sm); line-height: 1.5; color: var(--color-muted); }

/* ตั้งค่าทางลัดด่วน (ใช้ทั้งมือถือ/PC) — รายการเช็กบ็อกซ์ในโมดอล + ข้อความเมื่อยังไม่ได้ตั้ง */
.quick-cfg__hint { font-size: var(--fs-sm); color: var(--color-muted); margin: 0 0 var(--space-3); }
.quick-cfg__list { max-height: 52vh; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.quick-cfg__group {
    position: sticky; top: 0; z-index: 1;
    margin-top: 8px; padding: 8px 8px 5px;
    background: var(--color-surface); color: var(--color-muted);
    font-size: var(--fs-xs); font-weight: 700; letter-spacing: .02em;
}
.quick-cfg__group:first-child { margin-top: 0; }
.quick-cfg__item {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 8px; border-radius: var(--radius-md); cursor: pointer;
    font-size: var(--fs-base); color: var(--color-text);
}
.quick-cfg__item:hover { background: var(--color-surface-alt); }
.quick-cfg__item input { width: 18px; height: 18px; flex: 0 0 auto; accent-color: var(--color-primary); cursor: pointer; }
.quick-cfg__item i { font-size: 16px; color: var(--color-primary-hover); width: 20px; text-align: center; flex: 0 0 auto; }
.quick-cfg__item span { flex: 1 1 auto; }
.quick-cfg__order {
    flex: 0 0 auto; min-width: 20px; height: 20px; padding: 0 6px;
    border-radius: 10px; background: var(--color-primary); color: #fff;
    font-family: var(--ff-mono); font-size: 11px; font-weight: 700;
    display: none; align-items: center; justify-content: center;
}
.quick-cfg__item.is-picked .quick-cfg__order { display: inline-flex; }
.quick-empty-hint {
    grid-column: 1 / -1;
    padding: var(--space-4); text-align: center;
    color: var(--color-muted); font-size: var(--fs-sm);
    border: 1px dashed var(--color-border); border-radius: var(--radius-md);
}

/* ============================================================
   Responsive — Tablet / Mobile
   ============================================================ */
@media (max-width: 992px) {
    .app-sidebar {
        position: fixed;
        left: 0;
        top: 0;
        transform: translateX(-100%);
        transition: transform 0.22s ease;
        box-shadow: var(--shadow-lg);
    }
    .app-shell.drawer-open .app-sidebar { transform: translateX(0); }
    .app-shell.drawer-open .app-drawer-backdrop { display: block; }
    /* ignore desktop collapse on mobile — drawer ต้องเป็นเมนูเต็มแบบเว็บเสมอ
       (ไม่งั้นเปิด drawer แล้วเห็นแต่ไอคอน ไม่รู้ว่าแต่ละอันคืออะไร) */
    .app-shell.sidebar-collapsed .app-sidebar { width: var(--sidebar-width); }
    .app-shell.sidebar-collapsed .app-sidebar__brand-text,
    .app-shell.sidebar-collapsed .app-sidebar__search,
    .app-shell.sidebar-collapsed .nav-group__label,
    .app-shell.sidebar-collapsed .nav-group__toggle > span,
    .app-shell.sidebar-collapsed .nav-group__caret,
    .app-shell.sidebar-collapsed .nav-item span { display: revert; }
    .app-shell.sidebar-collapsed .nav-item { justify-content: flex-start; padding: 9px var(--space-3); }
    .app-shell.sidebar-collapsed .nav-group__toggle { justify-content: flex-start; padding: 9px var(--space-3); }
    .app-shell.sidebar-collapsed .nav-group__toggle > i:first-child { width: 20px; }
    /* คืนการเยื้อง + เส้นนำของเมนูย่อย และคืน accordion พับ/เปิด */
    .app-shell.sidebar-collapsed .nav-group--collapsible > .nav-group__items {
        margin: 2px 0 var(--space-2) 18px;
        padding-left: 8px;
        border-left: 1.5px solid var(--color-border);
    }
    .app-shell.sidebar-collapsed .nav-group--collapsible:not(.is-open) > .nav-group__items { display: none; }

    /* ---- App-style top bar (มือถือ): ชื่อหน้าอยู่กลาง ตัวหนา เหมือน native app ----
       ใช้กริด 3 ช่อง (ซ้าย | ชื่อ | ขวา) แทนการจัดกลางแบบ absolute — ชื่อยาว ๆ
       (เช่น "สั่งป้ายราคา Marketplace") จะถูกตัดด้วย ... ในช่องกลาง ไม่ทับไอคอนขวาอีก */
    .app-topbar {
        position: sticky;
        display: grid;
        grid-template-columns: auto minmax(0, 1fr) auto;
        gap: var(--space-2);
        isolation: isolate;
    }
    .app-topbar__title {
        margin: 0;
        max-width: 100%;
        text-align: center;
        font-weight: 700;
        font-size: var(--fs-md);
        pointer-events: none;
    }
    /* ปุ่มย้อนกลับ (app-bar) — แสดง/ซ่อนคุมด้วย JS */
    .topbar-back {
        color: var(--color-text);
        font-size: 22px;
        /* แยก hit target จากขอบจอซึ่งบางเครื่องสงวนไว้ให้ system back gesture */
        margin-left: max(0px, env(safe-area-inset-left, 0px));
    }
    /* บนมือถือซ่อน brand chip + ชื่อผู้ใช้ (ย้ายไปอยู่ใน drawer/เมนูผู้ใช้แล้ว) เหลือ avatar */
    .topbar-brand-chip { display: none; }
    .topbar-user__name { display: none; }
    .topbar-user__btn { padding: 4px; }
    /* app ไม่โชว์ breadcrumb — ใช้ชื่อใน app-bar + ปุ่มย้อนกลับแทน */
    .breadcrumb-bar { display: none; }
}

/* ปุ่ม back ซ่อนเสมอบน desktop (ใช้ hamburger ย่อ/ขยาย sidebar แทน) */
@media (min-width: 993px) {
    .topbar-back { display: none !important; }
}

@media (min-width: 993px) {
    .topbar-toggle.is-mobile { display: none; }
}

/* ============================================================
   Qty stepper (shared React component) — base / desktop
   ============================================================ */
.qty-stepper { display: inline-flex; align-items: center; gap: 6px; }
.qty-stepper__btn { width: 38px; min-height: 38px; padding: 0; }
.qty-stepper .qty-input { width: 88px; text-align: center; }
.qty-stepper__unit { font-size: 12px; color: var(--color-faint); min-width: 28px; }

/* ============================================================
   Stock count entry rows (React island) — base / desktop
   ============================================================ */
.count-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3);
    padding: 12px 14px;
    border-top: 1px solid var(--color-border);
    border-left: 6px solid var(--color-primary);
    box-shadow: inset 3px 0 0 var(--color-primary-soft);
}
/* บรรทัดข้อมูลเสริมใต้ชื่อสินค้า (คลัง / ขั้นต่ำ) — ใช้ในหน้าสั่งของ/ขอซื้อ/ของเสีย */
.count-row__meta { font-size: 11px; color: var(--color-faint); margin-top: 2px; }
/* ส่วนขยายท้ายแถว (หมายเหตุรายการ / รูปแนบ) — กินเต็มความกว้างใต้แถวหลัก */
.count-row__extra { flex: 1 1 100%; min-width: 0; margin-top: 2px; }
.count-row--counted {
    border-left-color: var(--color-success);
    box-shadow: inset 3px 0 0 var(--color-success-soft);
}
.count-row__no {
    flex: 0 0 26px;
    color: var(--color-primary-hover);
    font-size: 12px;
    font-weight: 700;
    text-align: center;
}
.count-row--counted .count-row__no { color: var(--color-success); }
.count-row__img {
    display: block;
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    object-fit: cover;
    object-position: center;
    border-radius: 6px;
    border: 1px solid var(--color-border);
    background: var(--color-surface-alt);
}
.count-row__img--empty {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 2px;
    box-sizing: border-box;
    font-size: 10px;
    line-height: 1.15;
    color: var(--color-faint);
    background: var(--color-surface-alt);
    border-style: dashed;
}
.count-row__img--empty .bi { font-size: 22px; opacity: 0.35; }
.count-row__info { flex: 1 1 160px; min-width: 0; }

/* ===== กรอบรูปสินค้าใช้ร่วมทุกหน้า: สำรองพื้นที่เท่ากันทุกสถานะ กัน UI ขยับตอนไม่มีรูป/โหลดรูปไม่สำเร็จ =====
   โครง: <span class="item-thumb item-thumb--sm"><img ... onerror="this.style.display='none'"></span>
   ไม่มี <img> หรือ img โหลดไม่สำเร็จ (display:none) → โชว์ ::before "ไม่มีรูป" (กรอบ dashed) */
.item-thumb {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    box-sizing: border-box;
    overflow: hidden;
    /* ขนาด + มุมโค้ง มาจาก size modifier ด้านล่าง */
}
.item-thumb::before {
    content: "ไม่มีรูป";
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 2px;
    box-sizing: border-box;
    font-size: 10px;
    line-height: 1.15;
    color: var(--color-faint);
    background: var(--color-surface-alt);
    border: 1px dashed var(--color-border);
    border-radius: inherit;
    z-index: 0;
}
.item-thumb > img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
    object-position: center;
    background: var(--color-surface-alt);
    border: 1px solid var(--color-border);
    border-radius: inherit;
    box-sizing: border-box;
    z-index: 1;
}
.item-thumb--sm { width: 40px; height: 40px; border-radius: 6px; }
.item-thumb--md { width: 44px; height: 44px; border-radius: 8px; }
.count-row__code { font-size: 11px; color: var(--color-faint); margin-bottom: 3px; }
.count-row__name { font-size: 14px; font-weight: 600; line-height: 1.3; }
/* ยอดรวมทุกจุดนับ — ย้ายมาไว้ใต้ชื่อสินค้าให้เห็นง่าย (chip เล็ก ๆ) */
.count-row__total {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    margin-top: 4px;
    padding: 2px 10px;
    border-radius: 999px;
    background: var(--color-primary-soft);
    color: var(--color-primary-hover);
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
}
.count-row__total strong { color: var(--color-primary-hover); font-size: 14px; font-weight: 800; }
.count-row--counted .count-row__total { background: var(--color-success-soft); color: var(--color-success); }
.count-row--counted .count-row__total strong { color: var(--color-success); }

/* จุดนับหลายจุด (สูงสุด 4) + ยอดรวม — วางชิดขวาของแถว, เรียงจากบนลงล่าง */
.count-row__points {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 6px;
}
.count-point { display: inline-flex; align-items: center; gap: 8px; }
/* กล่องช่องกรอกของจุดนับ — มีได้ 1 ช่อง (หน่วยใหญ่) หรือ 2 ช่อง (หน่วยใหญ่ + หน่วยย่อย)
   ให้ wrap ได้เองเมื่อที่ไม่พอ แทนที่จะดันแถวจนล้น */
.count-point__inputs {
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 8px;
}
.count-point__label {
    font-size: 12px;
    color: var(--color-muted);
    min-width: 44px;
    text-align: right;
}
.count-point__actions { display: inline-flex; align-items: center; gap: 8px; }
.count-point__add {
    border: 1px dashed var(--color-border);
    background: transparent;
    color: var(--color-primary);
    border-radius: 8px;
    padding: 4px 12px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.count-point__add:hover { background: var(--color-surface-alt); }
.count-point__minus { color: var(--color-muted); }
.count-point__total {
    font-size: 13px;
    color: var(--color-muted);
    border-top: 1px dashed var(--color-border);
    padding-top: 6px;
    white-space: nowrap;
}
.count-point__total strong { color: var(--color-text); font-size: 15px; }

/* แถบลอย (sticky) ของหน้านับสต๊อก: แท็บหมวด + ช่องค้นหา ติดจอใต้ topbar ตอนเลื่อนลง */
.count-sticky-head {
    position: sticky;
    top: var(--topbar-height);
    z-index: 30;
    background: var(--color-bg);
    margin-bottom: var(--space-3);
}
/* แท็บอยู่ใน sticky head แล้ว → ยกเลิก sticky ซ้อน (กันเด้งซ้อนกัน) เฉพาะในหน้านี้ */
.count-sticky-head .factory-tabs {
    position: static;
    top: auto;
    z-index: auto;
    box-shadow: none;
    margin-bottom: 6px;
}
.count-sticky-head .count-search-bar {
    margin-bottom: 0;
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}
/* ช่องค้นหายืด/หดได้ — min-width:0 กันไม่ให้ intrinsic width ของ input ดันแถวจนล้นแนวนอน
   (overflow แนวนอนคือสาเหตุที่ทำให้ปุ่ม fixed right:12px ถูกดันหลุดขอบขวาจนมองไม่เห็น) */
.count-search-bar__field { flex: 1 1 260px; min-width: 0; max-width: 420px; }
.count-search-bar__field .search-input,
.count-search-bar__field .input-app { min-width: 0; }
.count-scan-btn { flex: 0 0 auto; white-space: nowrap; }
.count-progress { flex: 0 0 auto; white-space: nowrap; font-size: 13px; color: var(--color-muted); }
.count-progress strong { color: var(--color-text); }

/* ปุ่มกลับขึ้นบนสุด — ลอยมุมขวาล่าง เหนือแถบบันทึก */
.count-to-top {
    position: fixed;
    right: 18px;
    bottom: calc(88px + env(safe-area-inset-bottom, 0px));
    width: 44px;
    height: 44px;
    padding: 0;
    border-radius: 999px;
    border: 1px solid var(--color-primary);
    background: var(--color-primary);
    color: #fff;
    box-shadow: var(--shadow-lg);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    cursor: pointer;
    z-index: 60; /* เหนือ save-bar (40) + sticky head (30) ต่ำกว่า topbar (100) */
    transition: background .15s ease, transform .15s ease;
}
.count-to-top:hover { background: var(--color-primary-hover); transform: translateY(-2px); }

/* แถบปุ่ม "ออกจากโหมดแก้ไข" ด้านบน (static ไม่ลอยตาม) — ชิดขวาเหนือการ์ดหัวเรื่อง */
.count-top-actions {
    display: flex;
    justify-content: flex-end;
    margin-bottom: var(--space-3);
}

/* ปุ่ม "บันทึก" สีดำ (ตามคำขอ) — ทึบทั้ง light/dark */
.count-save-btn { background: #111827; color: #fff; border-color: #111827; }
.count-save-btn:hover { background: #000; color: #fff; border-color: #000; }
/* สถานะ auto-save ใน save bar ของหน้านับสต๊อก — ดันปุ่มไปชิดขวา */
.count-save-status {
    margin-right: auto;
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 13px; color: var(--color-muted);
}

@media (max-width: 600px) {
    .app-content { padding: var(--space-4); }
    .filter-bar__actions { margin-left: 0; width: 100%; }

    /* จอแคบ: บีบช่องไฟกลุ่มไอคอนบน app-bar เพื่อคืนพื้นที่ให้ชื่อหน้า (ยังแตะได้ 38px เท่าเดิม) */
    .app-topbar__left, .app-topbar__right { gap: var(--space-1); }

    /* page header แบบแอป: ชื่อเล็กลง (app-bar โชว์ชื่อหลักแล้ว), ปุ่ม action เต็มกว้าง */
    .page-header { flex-direction: column; align-items: stretch; gap: var(--space-3); }
    .page-header__title { font-size: var(--fs-lg); }
    .page-header__actions { display: flex; flex-direction: column; gap: var(--space-2); }
    .page-header__actions .btn-app { width: 100%; justify-content: center; }

    /* filter เรียงแนวตั้ง + ช่องเต็มกว้าง ใช้ง่ายบนจอเล็ก */
    .filter-bar__row { flex-direction: column; align-items: stretch; }
    /* รีเซ็ต flex shorthand (เช่น inline flex:1 1 260px ของช่องค้นหา) — ไม่งั้น
       flex-basis 260px จะกลายเป็น "ความสูง" ตอนเรียงแนวตั้ง ทำให้เกิดช่องว่างใหญ่ */
    .filter-bar__row .field { width: 100%; min-width: 0 !important; flex: 0 0 auto !important; }
    .filter-bar__actions .btn-app { width: 100%; justify-content: center; }

    /* report toolbar: ช่องกรอง + ปุ่มส่งออก เต็มกว้าง เรียงแนวตั้งบนจอเล็ก */
    .report-toolbar { width: 100%; margin-left: 0; flex-wrap: wrap; }
    .report-toolbar__search { min-width: 0; flex: 1 1 100%; }
    .report-toolbar .btn-app { flex: 1 1 100%; justify-content: center; }
    /* โหมดการ์ด: คืนการตัดบรรทัดให้ค่าที่ยาว (เช่น ชื่อรายการ) ไม่ล้นการ์ด + ไม่จำกัดความกว้างคอลัมน์แคบ */
    .report-table.table-cards td { white-space: normal; }
    .report-table.table-cards td.col-narrow,
    .report-table.table-cards td.col-wrap { max-width: none; min-width: 0; overflow: visible; text-overflow: clip; }

    /* การ์ดลิสต์: กดแล้วมี feedback เหมือนแตะใน app */
    .table-app.table-cards tbody tr:active { background: var(--color-surface-alt); }
    /* compact card view for tables marked as such */
    .table-app.table-cards thead { display: none; }
    .table-app.table-cards tbody tr {
        display: block;
        border: 1px solid var(--color-border);
        border-radius: var(--radius-md);
        margin-bottom: var(--space-3);
        padding: var(--space-2);
    }
    .table-app.table-cards tbody td {
        display: flex;
        justify-content: space-between;
        gap: var(--space-4);
        border: 0;
        padding: 6px var(--space-2);
    }
    .table-app.table-cards tbody td::before {
        content: attr(data-label);
        font-weight: 600;
        color: var(--color-muted);
        font-size: var(--fs-xs);
    }

    /* โหมดการ์ด: ถอดกล่องขาวที่ครอบตารางออก ให้ช่องระหว่างการ์ดเป็นพื้นหลังเว็บ (เทาอ่อน) การ์ดจะลอยขึ้นมา */
    .transfer-receive-panel {
        background: transparent;
        border: 0;
        border-radius: 0;
        box-shadow: none;
    }

    /* หัวเอกสารบนมือถือ: label ซ้าย/ค่าขวา + บังคับ 2 คอลัมน์ให้ field สั้นจับคู่กันได้
       (สาขา|คลัง, วันที่ส่ง|จำนวนรายการ, ผู้ส่ง|ผู้รับ) ส่วนแถวค่ายาวใช้ .docmeta__row--wide กินเต็มบรรทัด */
    .docmeta {
        grid-template-columns: 1fr 1fr;
        gap: 0 16px;
    }
    .docmeta__row {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 10px;
        padding: 6px 0;
        border-bottom: 1px solid var(--color-border);
    }
    .docmeta__row--wide { grid-column: 1 / -1; }
    .docmeta dt {
        flex: 0 0 auto;
        color: var(--color-muted);
        font-size: 15px;
        font-weight: 600;
    }
    .docmeta dd {
        text-align: right;
        font-size: 14px;
        font-weight: 700;
    }

    /* Receive / Transfers: การ์ดเอกสารบนมือถือ (compact)
       ⚠️ ทุก selector ต้องมี 3 คลาส (`.table-app.table-cards.transfer-receive-table`) เพราะ `mobile-app.css`
       โหลดทีหลัง site.css และมีกฎ `.table-app.table-cards tbody td::before` ที่บังคับ font mono + 10px +
       uppercase + สี faint (specificity เท่ากัน ไฟล์ทีหลังชนะ) — IBM Plex Mono ไม่มีอักษรไทย ตัวไทยจึงตกไป
       ฟอนต์สำรอง ทำให้ label ดู "คนละฟอนต์ + เล็กจิ๋ว + จาง"  See LogHistory #10.
       ขนาดอักษรยึด "ความสูงที่ตาเห็น" (ที่ px เท่ากัน ตัวไทยสูง ~50% ของ em ส่วนละตินตัวพิมพ์ใหญ่ ~72%):
       ข้อมูลหลัก = ไทย 16px : ละติน 14px · meta (อ้างอิง/อัปเดตล่าสุด/ปุ่ม) ลดหนึ่งขั้น = ไทย 15px : ละติน 13px
       · หัวเรื่อง 17px · ระยะบนกริด 4px */
    .table-app.table-cards.transfer-receive-table tbody tr {
        position: relative;
        display: grid;
        grid-template-columns: 1fr auto;
        align-items: baseline;
        padding: 0 0 4px;
        margin-bottom: 12px;
        overflow: hidden;
        border: 1px solid var(--color-border);
        border-radius: 14px;
        background: var(--color-surface);
        box-shadow: 0 3px 14px rgba(15, 23, 42, .06);
    }
    .table-app.table-cards.transfer-receive-table tbody td {
        align-items: baseline;
        justify-content: flex-start;
        gap: 8px;
        padding: 4px 16px;
        font-size: 15px;
        line-height: 1.45;
    }
    /* label: บังคับกลับมาเป็นฟอนต์ปกติ ไม่ mono/ไม่ uppercase (ดู header ของบล็อกนี้) */
    .table-app.table-cards.transfer-receive-table tbody td::before {
        flex: 0 0 auto;
        font-family: var(--ff-sans);
        text-transform: none;
        letter-spacing: 0;
        color: var(--color-muted);
        font-size: 16px;
        font-weight: 600;
        line-height: 1.45;
    }

    /* หัวการ์ด: เลขที่โอน + สถานะมุมขวา */
    .table-app.table-cards.transfer-receive-table .transfer-card__document {
        grid-column: 1 / -1;
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        gap: 1px;
        padding: 12px 104px 6px 16px;
        border-bottom: 0;
        background: transparent;
    }
    .table-app.table-cards.transfer-receive-table .transfer-card__document::before { display: none; }
    .table-app.table-cards.transfer-receive-table .transfer-card__trb {
        font-family: var(--ff-sans);
        font-size: 17px;
        font-weight: 700;
        line-height: 1.3;
        color: var(--color-text);
    }
    .table-app.table-cards.transfer-receive-table .transfer-card__req { color: var(--color-muted); font-size: 13px; font-weight: 400; line-height: 1.4; }
    .table-app.table-cards.transfer-receive-table .transfer-card__req .th { font-size: 15px; }
    .table-app.table-cards.transfer-receive-table .transfer-card__status {
        position: absolute;
        top: 12px;
        right: 12px;
        display: block;
        padding: 0;
    }
    .table-app.table-cards.transfer-receive-table .transfer-card__status::before { display: none; }
    .table-app.table-cards.transfer-receive-table .transfer-card__status .badge-app { white-space: nowrap; }

    /* สาขา | คลัง บรรทัดเดียวกัน */
    .table-app.table-cards.transfer-receive-table .transfer-card__branch { grid-column: 1; }
    .table-app.table-cards.transfer-receive-table .transfer-card__warehouse { grid-column: 2; }
    /* วันส่ง: กินเต็มบรรทัดของตัวเอง (แถวสาขา|คลัง เต็มแล้ว) */
    .table-app.table-cards.transfer-receive-table .transfer-card__shipdate { grid-column: 1 / -1; }
    .table-app.table-cards.transfer-receive-table .transfer-card__branch span,
    .table-app.table-cards.transfer-receive-table .transfer-card__warehouse span,
    .table-app.table-cards.transfer-receive-table .transfer-card__shipdate span {
        color: var(--color-text);
        font-size: 14px;
        font-weight: 700;
    }

    /* โรงงาน: label สั้นพอที่ chip จะอยู่บรรทัดเดียวกัน */
    .table-app.table-cards.transfer-receive-table .transfer-card__factories {
        grid-column: 1 / -1;
        flex-wrap: wrap;
        align-items: baseline;
        gap: 8px;
        padding-top: 6px;
        padding-bottom: 12px;
        border-bottom: 1px solid var(--color-border);
    }
    .table-app.table-cards.transfer-receive-table .transfer-card__factory-list {
        display: flex;
        flex: 1 1 auto;
        flex-wrap: wrap;
        gap: 8px;
    }
    .table-app.table-cards.transfer-receive-table .transfer-card__factory {
        display: inline-flex;
        align-items: baseline;
        gap: 6px;
        padding: 4px 10px;
        border: 1px solid var(--color-border);
        border-radius: 8px;
        background: var(--color-surface-alt);
        color: var(--color-text);
        font-size: 14px;
        font-weight: 700;
        line-height: 1.45;
        white-space: nowrap;
    }
    .table-app.table-cards.transfer-receive-table .transfer-card__factory small { color: var(--color-muted); font-size: 16px; font-weight: 400; }

    /* ท้ายการ์ด: meta ซ้าย + ปุ่มดูรายละเอียดขวา อยู่แถวเดียวกัน */
    .table-app.table-cards.transfer-receive-table .transfer-card__updated {
        grid-column: 1;
        align-items: baseline;
        flex-wrap: wrap;
        gap: 4px 8px;
        padding-top: 10px;
    }
    .table-app.table-cards.transfer-receive-table .transfer-card__updated::before { display: none; }
    .table-app.table-cards.transfer-receive-table .transfer-card__updated > span,
    .table-app.table-cards.transfer-receive-table .transfer-card__updated > small {
        display: inline;
        text-align: left;
        color: var(--color-muted);
        font-size: 13px;
        font-weight: 400;
        line-height: 1.45;
    }
    .table-app.table-cards.transfer-receive-table .transfer-card__updated > small { font-size: 15px; }
    .table-app.table-cards.transfer-receive-table .transfer-card__action {
        grid-column: 2;
        align-self: center;
        justify-content: flex-end;
        padding: 10px 16px 4px;
    }
    .table-app.table-cards.transfer-receive-table .transfer-card__action::before { display: none; }
    .table-app.table-cards.transfer-receive-table .transfer-card__action .row-actions { width: auto; }
    .table-app.table-cards.transfer-receive-table .transfer-card__detail {
        height: 34px;
        padding: 0 12px;
        border-radius: 999px;
        border-color: var(--color-primary);
        background: var(--color-primary-soft);
        color: var(--color-primary-hover);
        font-size: 15px;
        font-weight: 600;
    }
    .table-app.table-cards.transfer-receive-table .transfer-card__detail > i { font-size: 13px; }

    /* ---- รายการใบโอน (Transfer Create/Manage) บนมือถือ ----
       ใช้โครง .count-row ชุดเดียวกับหน้าของเสีย/นับสต๊อก แต่ไม่มีรูปสินค้า
       → ตัดคอลัมน์ image ทิ้ง เหลือ (ลำดับ | ข้อมูล/ช่องกรอก) */
    .count-row--nopic {
        grid-template-columns: 26px minmax(0, 1fr);
        grid-template-areas:
            "no info"
            "no qty";
        min-height: 0;
    }


    /* ---- การ์ดใบส่งของ (Shipping) : อ่านง่ายขึ้นบนมือถือ ---- */
    /* ค่าที่ซ้อนหลายบรรทัด (เลขที่ส่ง+Pick) ให้ชิดขวาให้ตรงกับค่าอื่น ๆ */
    .ship-list-table.table-cards .cell-stack { align-items: flex-end; text-align: right; }
    /* เลขที่ส่งเป็นหัวข้อการ์ด: ตัวหนา/ใหญ่ขึ้นเล็กน้อย */
    .ship-list-table.table-cards tbody td[data-label="เลขที่ส่ง"] strong { font-size: var(--fs-md); }
    /* แถวปุ่ม action: ไม่มี label ให้ปุ่มขยายเต็มความกว้างการ์ด กดง่าย
       เว้นที่ว่างด้านขวา (padding-right) ไว้ให้เลขลำดับใบไม่ทับปุ่ม */
    .ship-list-table.table-cards tbody td[data-label=""] { padding-top: 10px; }
    .ship-list-table.table-cards tbody td[data-label=""]::before { display: none; }
    .ship-list-table.table-cards tbody td[data-label=""] .row-actions { width: 100%; padding-right: 32px; }
    .ship-list-table.table-cards tbody td[data-label=""] .ship-detail-btn {
        width: 100%;
        height: 36px;
        justify-content: center;
    }

    /* เลขลำดับใบ (1..N ต่อเนื่องข้ามหน้า) มุมขวาล่างของการ์ด เล็ก ๆ
       ให้รู้ว่าเลื่อนมาถึงใบที่เท่าไรแล้ว — เฉพาะมุมมองการ์ด (มือถือ) */
    .ship-list-table.table-cards tbody tr { position: relative; }
    .ship-list-table.table-cards tbody tr[data-cardno]::after {
        content: attr(data-cardno);
        position: absolute;
        right: 8px;
        bottom: 8px;
        min-width: 20px;
        padding: 1px 6px;
        border-radius: 999px;
        background: var(--color-surface-alt);
        color: var(--color-muted);
        font-size: 10px;
        font-weight: 700;
        line-height: 1.6;
        text-align: center;
        pointer-events: none;
    }

    /* ============================================================
       การ์ดสินค้า (มือถือ) — จัดวางใหม่ให้อ่านเป็นการ์ดจริง:
       รูปมุมขวาบน, code เป็น eyebrow, ชื่อเป็นหัวข้อ, meta/flag เรียงแนวนอน,
       สถานะ + ปุ่มแก้ไขแยกท้ายการ์ด
       ============================================================ */
    /* หมายเหตุ: ใส่ .table-app นำหน้าเพื่อดัน specificity ให้ชนะ mobile-app.css
       (`.table-app.table-cards tbody tr { padding:12px 14px }` spec เท่ากัน 0,2,2 และโหลดทีหลัง) */
    .table-app.item-list-table.table-cards tbody tr {
        position: relative;
        padding: 14px;
        padding-left: 74px;
    }
    /* แถว empty-state (ไม่พบสินค้า) ไม่มีรูป — ไม่ต้อง indent ซ้าย */
    .table-app.item-list-table.table-cards tbody tr:has(.empty-state) {
        padding-left: 14px;
    }
    .item-list-table.table-cards tbody td {
        display: block;
        padding: 0;
        border: 0;
    }
    .item-list-table.table-cards tbody td::before { display: none; }

    /* รูปสินค้า: ลอยมุมซ้ายบนของการ์ด */
    .item-list-table.table-cards tbody td[data-label=""]:first-child {
        position: absolute;
        top: 14px;
        left: 14px;
        width: 50px;
        height: 50px;
        display: flex;
        align-items: center;
        justify-content: center;
    }
    .item-list-table.table-cards tbody td[data-label=""]:first-child img {
        width: 50px !important;
        height: 50px !important;
    }
    .item-list-table.table-cards tbody td[data-label=""]:first-child .bi {
        font-size: 30px !important;
    }

    /* code = eyebrow เล็ก (เว้นที่ขวาให้ปุ่มสถานะที่ลอยมุมขวาบน) */
    .item-list-table.table-cards td[data-label="Code"] {
        font-size: 11px;
        font-weight: 600;
        color: var(--color-muted);
        letter-spacing: .02em;
        margin-bottom: 2px;
        padding-right: 64px;
    }
    /* ชื่อสินค้า = หัวข้อการ์ด */
    .item-list-table.table-cards td[data-label="ชื่อสินค้า"] {
        font-size: 15px;
        font-weight: 700;
        line-height: 1.3;
        margin-bottom: 8px;
        padding-right: 64px;
    }

    /* คลัง + หน่วย = meta แนวนอนพร้อม label นำหน้า */
    .item-list-table.table-cards td[data-label="คลัง"],
    .item-list-table.table-cards td[data-label="หน่วย"] {
        display: inline-flex;
        align-items: baseline;
        gap: 4px;
        margin: 0 14px 8px 0;
        font-size: 12.5px;
        color: var(--color-text);
    }
    .item-list-table.table-cards td[data-label="คลัง"]::before,
    .item-list-table.table-cards td[data-label="หน่วย"]::before {
        display: inline;
        content: attr(data-label) ":";
        color: var(--color-muted);
        font-weight: 600;
        font-size: 11px;
    }

    /* ใบสั่งของ: บล็อกเต็มกว้าง + label ด้านบน */
    .item-list-table.table-cards td[data-label="Order WH"],
    .item-list-table.table-cards td[data-label="Order Supplier"] {
        margin-bottom: 8px;
    }
    .item-list-table.table-cards td[data-label="Order WH"]::before,
    .item-list-table.table-cards td[data-label="Order Supplier"]::before {
        display: block;
        content: attr(data-label);
        color: var(--color-muted);
        font-weight: 600;
        font-size: 11px;
        margin-bottom: 4px;
    }

    /* Daily / Monthly / MKP = ชิปแนวนอนบรรทัดเดียว */
    .item-list-table.table-cards td[data-label="Daily"],
    .item-list-table.table-cards td[data-label="Monthly"],
    .item-list-table.table-cards td[data-label="MKP"],
    .item-list-table.table-cards td[data-label="WaitingBatch"] {
        display: inline-flex;
        align-items: center;
        gap: 5px;
        margin: 0 14px 10px 0;
        font-size: 12px;
        font-weight: 600;
        color: var(--color-muted);
        text-align: left;
    }
    .item-list-table.table-cards td[data-label="Daily"]::before,
    .item-list-table.table-cards td[data-label="Monthly"]::before,
    .item-list-table.table-cards td[data-label="MKP"]::before,
    .item-list-table.table-cards td[data-label="WaitingBatch"]::before {
        display: inline;
        content: attr(data-label);
    }
    /* WaitingBatch = เป็นบรรทัดของตัวเองชิดซ้าย ไม่ลอยต่อท้าย MKP
       ใช้ block-level flex (ไม่ใช่ width:100%) กันการ์ดล้นขอบเพราะ tr มี padding-left 74px */
    .item-list-table.table-cards td[data-label="WaitingBatch"] {
        display: flex;
        margin-right: 0;
        justify-content: flex-start;
    }

    /* สถานะ = ปุ่ม เปิด/ปิด ลอยมุมขวาบนของการ์ด (แทน toggle switch) */
    .item-list-table.table-cards td[data-label="Status"] {
        position: absolute;
        top: 12px;
        right: 12px;
        margin: 0;
        padding: 0;
        border: 0;
    }
    .item-list-table.table-cards td[data-label="Status"]::before { display: none; }

    /* แปลง switch (label ครอบ checkbox) ให้เป็นปุ่ม pill ที่มีข้อความ เปิด/ปิด —
       ซ่อนตัว switch เดิม แต่คลิก label ยัง toggle checkbox เดิม (data-item-active-toggle ทำงานต่อ) */
    .item-list-table.table-cards td[data-label="Status"] .item-active-switch {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 58px;
        min-height: 30px;
        margin: 0;
        padding: 0 14px;
        border-radius: var(--radius-pill);
        font-size: 12.5px;
        font-weight: 700;
        line-height: 1;
        cursor: pointer;
        background: var(--color-danger-soft);
        color: var(--color-danger);
    }
    .item-list-table.table-cards td[data-label="Status"] .item-active-switch .form-check-input {
        display: none;
    }
    .item-list-table.table-cards td[data-label="Status"] .item-active-switch::after {
        content: "ปิด";
    }
    .item-list-table.table-cards td[data-label="Status"] .item-active-switch:has(.form-check-input:checked) {
        background: var(--color-success-soft);
        color: var(--color-success);
    }
    .item-list-table.table-cards td[data-label="Status"] .item-active-switch:has(.form-check-input:checked)::after {
        content: "เปิด";
    }
    /* กรณีไม่มีสิทธิ์แก้ไข (เป็น badge แทน switch): ให้ลอยมุมขวาบนเช่นกัน */
    .item-list-table.table-cards td[data-label="Status"] .badge-app {
        margin: 0;
    }

    /* ปุ่มแก้ไข: เต็มกว้างใต้การ์ด */
    .item-list-table.table-cards tbody td[data-label=""]:last-child {
        margin-top: 10px;
    }
    .item-list-table.table-cards tbody td[data-label=""]:last-child .row-actions {
        justify-content: stretch;
    }
    .item-list-table.table-cards tbody td[data-label=""]:last-child .row-actions .btn-icon-app {
        width: 100%;
        justify-content: center;
        height: 38px;
    }

    .item-list-table.table-cards td[data-label="à¸„à¸¥à¸±à¸‡"],
    .item-list-table.table-cards td[data-label="à¸«à¸™à¹ˆà¸§à¸¢"],
    .item-list-table.table-cards td[data-label="Order WH"],
    .item-list-table.table-cards td[data-label="Order Supplier"],
    .item-list-table.table-cards td[data-label="Daily"],
    .item-list-table.table-cards td[data-label="Monthly"],
    .item-list-table.table-cards td[data-label="MKP"] {
        text-align: left !important;
        justify-content: flex-start;
    }

    .item-list-table.table-cards td[data-label="à¸„à¸¥à¸±à¸‡"],
    .item-list-table.table-cards td[data-label="à¸«à¸™à¹ˆà¸§à¸¢"],
    .item-list-table.table-cards td[data-label="Order WH"],
    .item-list-table.table-cards td[data-label="Order Supplier"],
    .item-list-table.table-cards td[data-label="Daily"],
    .item-list-table.table-cards td[data-label="WaitingBatch"] {
        margin-left: -60px;
    }

    .item-list-table.table-cards td[data-label="Order WH"],
    .item-list-table.table-cards td[data-label="Order Supplier"] {
        width: calc(100% + 60px);
    }

    .item-list-table.table-cards td[data-label="Order WH"] .order-card,
    .item-list-table.table-cards td[data-label="Order Supplier"] .order-card {
        display: inline-block;
        text-align: left;
        margin-left: 0;
        margin-right: auto;
    }

    .save-bar { padding: var(--space-3); }
    .btn-app { min-height: 44px; }

    .count-search-bar,
    .count-header-card,
    .count-group-card {
        margin-left: calc(var(--space-4) * -1);
        margin-right: calc(var(--space-4) * -1);
        border-radius: 0;
        border-left: 0;
        border-right: 0;
    }

    .count-entry-scroll {
        overflow: visible;
    }

    .count-entry-table thead {
        display: none;
    }

    .count-entry-table tbody,
    .count-entry-table tr,
    .count-entry-table td {
        display: block;
        width: 100%;
    }

    .count-entry-table tbody tr {
        border: 1px solid var(--color-border);
        border-radius: var(--radius-md);
        padding: var(--space-3);
        margin: 0 var(--space-3) var(--space-3);
        background: var(--color-surface);
        box-shadow: var(--shadow-xs);
    }

    .count-entry-table tbody tr:hover {
        background: var(--color-surface);
    }

    .count-entry-table tbody td {
        border: 0;
        padding: 0;
    }

    .count-entry-table .count-item-code {
        color: var(--color-muted);
        font-size: var(--fs-xs);
        font-weight: 700;
        letter-spacing: 0;
        margin-bottom: 2px;
    }

    .count-entry-table .count-item-name {
        color: var(--color-text);
        font-size: var(--fs-md);
        font-weight: 650;
        line-height: 1.35;
        margin-bottom: var(--space-3);
    }

    .count-entry-table .count-item-qty {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: center;
        gap: var(--space-3);
    }

    .count-entry-table .count-item-checked {
        margin-bottom: var(--space-2);
    }

    .counted-check {
        display: inline-flex;
        align-items: center;
        gap: var(--space-2);
        min-height: 36px;
        color: var(--color-muted);
        font-size: var(--fs-sm);
        font-weight: 700;
    }

    .counted-check input {
        width: 18px;
        height: 18px;
        accent-color: var(--color-primary);
    }

    .count-entry-table .count-item-qty::before {
        content: attr(data-label);
        color: var(--color-muted);
        font-size: var(--fs-xs);
        font-weight: 700;
    }

    .count-entry-table .qty-input {
        width: 132px;
        min-height: 48px;
        text-align: right;
        font-size: var(--fs-lg);
        font-weight: 700;
    }

    .count-entry-table .count-item-unit {
        color: var(--color-muted);
        font-size: var(--fs-xs);
        margin-top: 4px;
        text-align: right;
    }

    /* ---- React count-row: จัดรูปแบบใหม่บนมือถือ ----
       แถวบน = เลขลำดับ + รูป + รหัส/ชื่อ, แถวล่าง = ตัวนับชิดขวา */
    .count-row {
        display: grid;
        grid-template-columns: 28px 64px minmax(0, 1fr);
        grid-template-areas:
            "no image info"
            "no image qty";
        grid-template-rows: auto auto;
        align-items: center;
        column-gap: 10px;
        row-gap: 4px;
        min-height: 84px;
        padding: 8px 10px;
    }
    .count-row--counted { background: var(--color-surface-alt); }
    .count-row__no {
        grid-area: no;
        align-self: start;
        width: 28px;
        padding-top: 3px;
        font-size: var(--fs-sm);
    }
    .count-row__img,
    .count-row__img--empty {
        grid-area: image;
        align-self: start;
        width: 64px;
        height: 64px;
        object-fit: cover;
        object-position: center;
        border-radius: 9px;
    }
    .count-row__img--empty { font-size: 11px; }
    .count-row__img--empty .bi { font-size: 28px; }
    .count-row__info {
        grid-area: info;
        align-self: start;
        min-width: 0;
        padding-right: 2px;
    }
    .count-row__code { font-size: var(--fs-xs); line-height: 1.25; }
    .count-row__name { font-size: var(--fs-md); }

    /* ส่วนขยาย (หมายเหตุ/รูปแนบ) — กินเต็มแถวใต้ช่องกรอก และมีได้มากกว่า 1 ก้อน
       ใช้ span ทั้งแถวแทน grid-area ที่ตั้งชื่อไว้ ไม่งั้น 2 ก้อนจะทับกันในเซลล์เดียว */
    .count-row__extra { grid-column: 1 / -1; margin-top: 4px; }

    /* ตัวนับบนมือถือ: เรียงเป็น [หน่วย] [−] [ช่องกรอก] [+] ชิดขวา (หน่วยอยู่หน้าช่อง — ดูเหตุผลด้านล่าง) */
    .count-row .qty-stepper {
        grid-area: qty;
        align-self: end;
        flex-wrap: nowrap;
        justify-content: flex-end;
        gap: 5px;
        min-width: 0;
    }
    /* ชื่อหน่วยอยู่ "หน้า" ช่องกรอก (order: -1) เฉพาะมุมมองมือถือ
       เหตุผล: stepper จัดชิดขวา (justify-content: flex-end) ถ้าปล่อยชื่อหน่วยไว้ท้ายสุด
       ความยาวหน่วยที่ต่างกัน (ถุง / กิโลกรัม) จะดันช่องกรอก + ปุ่ม −/+ ให้เลื่อนไปมาคนละที่ทุกแถว
       ย้ายมาไว้หน้าสุดแล้ว ขอบขวาของ [−][ช่อง][+] คงที่ → ช่องกรอกอยู่ตำแหน่งเดียวกันทุกแถว
       (ชื่อหน่วยยาวขึ้นก็ยืดไปทางซ้ายแทน) + ห้าม shrink เพื่อไม่ให้ชื่อหน่วยถูกตัด */
    .count-row .qty-stepper__unit {
        order: -1;
        flex: 0 0 auto;
        white-space: nowrap;
        text-align: right;
        font-size: var(--fs-xs);
        font-weight: 600;
    }
    .count-row .qty-stepper__btn {
        width: 34px;
        min-height: 34px;
        flex: 0 0 auto;
        border-radius: var(--radius-md);
        padding: 0;
    }
    .count-row .qty-stepper .qty-input {
        flex: 0 0 auto;
        width: clamp(54px, 18vw, 84px);
        min-height: 34px;
        padding: 0 8px;
        font-size: var(--fs-base);
        font-weight: 600;
    }

    /* จุดนับหลายจุดบนมือถือ: wrapper ครองเซลล์ qty, แต่ละจุดเต็มกว้างชิดขวา */
    .count-row__points {
        grid-area: qty;
        align-self: end;
        width: 100%;
        gap: 6px;
        /* grid item ปกติ min-width:auto → ถ้าเนื้อในกว้างเกิน จะดันทั้งหน้าให้ scroll แนวนอน
           (อาการตอนเพิ่มช่องหน่วยย่อย: การ์ดล้นจอ กดปุ่มไม่ได้) — บังคับให้ย่อได้ */
        min-width: 0;
    }
    .count-point { flex-wrap: wrap; justify-content: flex-end; width: 100%; gap: 6px; }
    .count-point__label { flex: 0 0 auto; margin-right: auto; text-align: left; font-size: var(--fs-sm); font-weight: 600; }

    /* สินค้าที่มีหน่วยย่อย: บนมือถือวางช่องกรอกซ้อนลงล่าง (หน่วยใหญ่ / หน่วยย่อย) เต็มความกว้าง
       — ถ้าปล่อยเรียงข้างกันแบบ nowrap จะล้นจอจนกดปุ่ม −/+ และอ่านชื่อหน่วยไม่ได้ */
    .count-point__inputs { min-width: 0; }
    .count-point--dual .count-point__inputs {
        flex: 1 1 100%;
        flex-direction: column;
        align-items: stretch;
        gap: 6px;
    }
    .count-point--dual .count-point__inputs .qty-stepper { width: 100%; justify-content: flex-end; }
    .count-point__actions { justify-content: flex-end; gap: 6px; }
    .count-point__add { padding: 5px 10px; font-size: var(--fs-xs); }
    .count-point__total { align-self: flex-end; font-size: var(--fs-sm); }
}

/* ============================================================
   Error / 404 page
   ============================================================ */
.error-page {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-6);
    background: var(--color-bg);
}
.error-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    padding: var(--space-8) var(--space-6);
    text-align: center;
    max-width: 440px;
    width: 100%;
}
.error-card__icon {
    width: 72px;
    height: 72px;
    border-radius: 50%;
    background: var(--color-primary-soft);
    color: var(--color-primary-hover);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 34px;
    margin: 0 auto var(--space-4);
}
.error-card__code {
    font-size: 56px;
    font-weight: 800;
    line-height: 1;
    color: var(--color-primary);
    letter-spacing: 1px;
}
.error-card__title { font-size: var(--fs-xl); font-weight: 700; margin: var(--space-3) 0 var(--space-2); }
.error-card__message { color: var(--color-muted); font-size: var(--fs-base); margin-bottom: var(--space-5); }
.error-card__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: center; }

/* ============================================================
   Login page (เดิม — คงไว้)
   ============================================================ */
.login-page {
    min-height: 100vh;
    background: var(--color-surface);
    display: flex;
    align-items: stretch;
    justify-content: center;
    padding: 0;
}

.login-split {
    display: flex;
    width: 100%;
    min-height: 100vh;
}

.login-split__left {
    flex: 0 0 55%;
    position: relative;
    overflow: hidden;
    background: var(--color-surface);
    display: flex;
    align-items: center;
    justify-content: center;
}

.login-split__shape {
    position: absolute;
    top: 50%;
    left: clamp(-620px, -32vw, -220px);
    width: clamp(900px, 78vw, 1500px);
    aspect-ratio: 1;
    transform: translateY(-50%);
    border-radius: 50%;
    background: linear-gradient(135deg, var(--brand-start) 0%, var(--brand-end) 100%);
    box-shadow: 0 30px 70px var(--brand-shadow);
    transition: opacity 0.4s ease, background 0.25s ease, box-shadow 0.25s ease;
}

.login-split__shape::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: radial-gradient(circle at 28% 35%, rgba(255, 255, 255, 0.28), transparent 34%),
        linear-gradient(90deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0) 60%);
}

.login-split__brand {
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    color: var(--brand-end);
    padding: 24px 8px;
    gap: 28px;
    width: min(390px, 100%);
}

.login-brand-mark {
    width: 320px;
    max-width: 100%;
    display: grid;
    grid-template-rows: 142px 122px;
    justify-items: center;
    margin-bottom: 8px;
}

.login-brand-mark__arc {
    width: 320px;
    height: 182px;
    overflow: visible;
    grid-row: 1 / 3;
    grid-column: 1;
}

.login-brand-mark__arc text {
    fill: var(--brand-end);
    font-size: 24px;
    font-weight: 800;
    letter-spacing: 8px;
    text-transform: uppercase;
}

.login-brand-mark__logo-frame {
    grid-row: 2;
    grid-column: 1;
    width: 124px;
    height: 124px;
    border-radius: 50%;
    border: 3px solid var(--brand-shadow);
    background: rgba(255, 255, 255, 0.96);
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 14px 34px var(--brand-shadow);
    transform: translateY(-14px);
}

.login-split__logo {
    width: 92px;
    height: 92px;
    object-fit: contain;
    padding: 10px;
    border-radius: 50%;
}

@media (max-width: 1200px) {
    .login-brand-mark {
        width: 290px;
        grid-template-rows: 130px 112px;
    }

    .login-brand-mark__arc {
        width: 290px;
        height: 166px;
    }

    .login-brand-mark__arc text {
        font-size: 22px;
        letter-spacing: 7px;
    }

    .login-brand-mark__logo-frame {
        width: 112px;
        height: 112px;
        transform: translateY(-12px);
    }

    .login-split__logo {
        width: 84px;
        height: 84px;
    }
}

.login-split__right {
    flex: 1 1 40%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: var(--color-surface);
}

@media (max-width: 900px) {
    .login-split__left { display: none; }
    .login-split__right { flex: 1 1 auto; }
}

.login-card {
    width: 100%;
    max-width: 380px;
    background: transparent;
    border: none;
    box-shadow: none;
    padding: 16px 8px;
}

.login-card__avatar {
    width: 84px;
    height: 84px;
    border-radius: 50%;
    background: #e8e8ee;
    color: #b9b9c2;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 48px;
    margin: 0 auto 12px;
}

.login-card__subtitle {
    text-align: center;
    color: var(--color-muted);
    font-size: 14px;
    margin-bottom: 24px;
}

.login-form {
    display: flex;
    flex-direction: column;
    gap: 12px;
    width: 100%;
}

.login-field {
    display: flex;
    align-items: center;
    background: #f1f1f4;
    border-radius: 999px;
    padding: 0 18px;
    height: 48px;
    border: 1px solid transparent;
    transition: box-shadow 0.2s ease, background 0.2s ease, border-color 0.2s ease;
}

.login-field:focus-within {
    background: #ebebf0;
    border-color: transparent;
    box-shadow: 0 0 0 3px var(--brand-shadow);
}

.login-field__icon {
    color: #9a9aa6;
    font-size: 18px;
    margin-right: 10px;
    display: inline-flex;
}

.login-field__input {
    flex: 1;
    border: 0;
    background: transparent;
    outline: none;
    font-size: 14px;
    color: var(--color-text);
    height: 100%;
    padding: 0;
}

.login-field__input::placeholder {
    color: #9a9aa6;
}

.login-field--select .login-field__input {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%239a9aa6'><path d='M4.5 6l3.5 3.5L11.5 6z'/></svg>");
    background-repeat: no-repeat;
    background-position: right 4px center;
    background-size: 16px;
    padding-right: 22px;
    cursor: pointer;
}

.login-btn {
    margin-top: 10px;
    height: 48px;
    border-radius: 999px;
    border: 0;
    background: linear-gradient(135deg, var(--brand-start) 0%, var(--brand-end) 100%);
    color: #fff;
    font-weight: 600;
    font-size: 15px;
    letter-spacing: 0.4px;
    cursor: pointer;
    box-shadow: 0 8px 20px var(--brand-shadow);
    transition: transform 0.15s ease, box-shadow 0.2s ease, filter 0.2s ease;
}

.login-btn:hover {
    filter: brightness(1.05);
    box-shadow: 0 10px 24px var(--brand-shadow);
}

.login-btn:active {
    transform: translateY(1px);
}

.login-btn:disabled {
    opacity: 0.75;
    cursor: not-allowed;
}

/* Indeterminate progress bar ระหว่างเข้าสู่ระบบ (POST ก้อนเดียว -> บอก % จริงไม่ได้) */
.login-progress {
    margin-top: 12px;
    height: 4px;
    width: 100%;
    border-radius: 999px;
    background: var(--brand-shadow, rgba(0, 0, 0, 0.08));
    overflow: hidden;
}

.login-progress__bar {
    height: 100%;
    width: 40%;
    border-radius: 999px;
    background: linear-gradient(135deg, var(--brand-start) 0%, var(--brand-end) 100%);
    animation: loginProgressSlide 1.1s ease-in-out infinite;
}

@keyframes loginProgressSlide {
    0%   { transform: translateX(-120%); }
    100% { transform: translateX(320%); }
}

/* ระหว่าง submit: ล็อกช่องกรอกให้ดูปิดอยู่ (ค่ายังถูกส่งเพราะใช้ readOnly ไม่ใช่ disabled) */
.login-form--submitting .login-field {
    opacity: 0.6;
}

.login-form--submitting .login-brand-select,
.login-form--submitting .login-field--select {
    pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
    .login-progress__bar {
        animation: none;
        width: 100%;
        opacity: 0.6;
    }
}

.login-error {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    background: #fdecec;
    color: #b42318;
    border: 1px solid #f5c2c0;
    border-left-width: 4px;
    border-radius: var(--radius-md);
    padding: 10px 12px;
    font-size: 13px;
    margin-bottom: 12px;
    text-align: left;
}

.login-error__icon {
    font-size: 18px;
    line-height: 1.3;
    flex: 0 0 auto;
}

.login-error__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.login-error__title {
    font-weight: 700;
}

.login-error__text {
    opacity: 0.9;
    word-break: break-word;
}

/* ข้อมูลเข้าสู่ระบบไม่ถูกต้อง — แดง (ค่าเริ่มต้น) */
.login-error--credentials {
    background: #fdecec;
    color: #b42318;
    border-color: #f5c2c0;
}

/* เชื่อมต่อเซิร์ฟเวอร์ไม่ได้ — เหลือง/เตือน (อาจเป็นปัญหาเครือข่ายชั่วคราว) */
.login-error--connection {
    background: #fff7e6;
    color: #92500a;
    border-color: #f6d28a;
}

/* เซิร์ฟเวอร์ขัดข้อง — ส้มเข้ม */
.login-error--server {
    background: #fdeede;
    color: #9a3b12;
    border-color: #f3c39a;
}

.login-error-detail {
    background: #fff8f0;
    color: #7a2e0e;
    border: 1px solid #f1d5b8;
    border-radius: var(--radius-md);
    padding: 8px 12px;
    margin-bottom: 12px;
}

.login-error-detail > summary {
    cursor: pointer;
    font-size: 12px;
    font-weight: 600;
}

.login-error-detail pre {
    margin: 8px 0 0;
    white-space: pre-wrap;
    word-break: break-all;
    font-size: 12px;
    line-height: 1.5;
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
}

.fade-transition { transition: opacity 0.4s ease; }
.fade-hidden { opacity: 0; }
.fade-visible { opacity: 1; }

/* Login refresh */
.login-page {
    min-height: 100vh;
    background:
        linear-gradient(135deg, rgba(255, 255, 255, 0.84), rgba(246, 247, 251, 0.94)),
        var(--color-bg);
    overflow: hidden;
}

.login-split {
    position: relative;
    isolation: isolate;
}

.login-split::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background-image:
        linear-gradient(rgba(31, 36, 51, 0.045) 1px, transparent 1px),
        linear-gradient(90deg, rgba(31, 36, 51, 0.04) 1px, transparent 1px);
    background-size: 44px 44px;
    mask-image: linear-gradient(90deg, #000 0 45%, transparent 78%);
}

.login-split__left {
    flex-basis: 58%;
    background: #141922;
    align-items: stretch;
    justify-content: flex-start;
}

.login-split__media {
    position: absolute;
    inset: 0;
    background:
        linear-gradient(90deg, rgba(12, 15, 22, 0.56), rgba(12, 15, 22, 0.22)),
        var(--brand-image) center / cover no-repeat;
    filter: saturate(1.02) contrast(0.94);
    transform: scale(1.02);
    transition: opacity 0.4s ease, transform 0.8s ease;
}

.login-split__left::before {
    content: "";
    position: absolute;
    inset: 0;
    background:
        linear-gradient(115deg, rgba(16, 19, 27, 0.9) 0%, rgba(16, 19, 27, 0.52) 48%, rgba(16, 19, 27, 0.12) 100%),
        linear-gradient(0deg, rgba(16, 19, 27, 0.5), transparent 44%);
    z-index: 1;
}

.login-split__shape {
    z-index: 2;
    top: auto;
    right: clamp(-180px, -10vw, -90px);
    bottom: clamp(-340px, -24vw, -180px);
    left: auto;
    width: clamp(460px, 48vw, 780px);
    opacity: 0.92;
    transform: none;
    border-radius: 42% 58% 44% 56%;
    background:
        linear-gradient(135deg, var(--brand-start), var(--brand-end));
    box-shadow: 0 28px 86px var(--brand-shadow);
    animation: login-shape-drift 10s ease-in-out infinite alternate;
}

.login-split__shape::after {
    background:
        linear-gradient(135deg, rgba(255, 255, 255, 0.32), transparent 38%),
        repeating-linear-gradient(135deg, rgba(255, 255, 255, 0.11) 0 1px, transparent 1px 14px);
}

.login-split__shape {
    display: none;
}

.login-hero {
    position: relative;
    z-index: 3;
    align-self: center;
    max-width: 560px;
    padding: clamp(40px, 7vw, 96px);
    color: #fff;
}

.login-hero__badge,
.login-split__mobile-badge {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    min-height: 32px;
    padding: 0 13px;
    border-radius: var(--radius-pill);
    background: rgba(255, 255, 255, 0.12);
    border: 1px solid rgba(255, 255, 255, 0.22);
    color: rgba(255, 255, 255, 0.92);
    font-size: 12px;
    font-weight: 700;
    backdrop-filter: blur(12px);
}

.login-hero h1 {
    max-width: 540px;
    margin: 24px 0 16px;
    font-size: clamp(34px, 3.65vw, 50px);
    line-height: 1.15;
    font-weight: 750;
    color: #fff;
    text-wrap: balance;
    text-shadow: 0 2px 22px rgba(0, 0, 0, 0.28);
}

.login-hero p {
    max-width: 500px;
    margin: 0;
    color: rgba(255, 255, 255, 0.8);
    font-size: 17px;
    line-height: 1.7;
}

.login-hero__stats {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
    max-width: 500px;
    margin-top: 30px;
}

.login-hero__stats div {
    position: relative;
    min-height: 70px;
    border: 1px solid rgba(255, 255, 255, 0.13);
    border-radius: 10px;
    padding: 14px 15px 12px;
    background: rgba(14, 18, 26, 0.3);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
    backdrop-filter: blur(10px);
}

.login-hero__stats div::before {
    content: "";
    position: absolute;
    top: 0;
    right: 14px;
    left: 14px;
    height: 2px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.38);
}

.login-hero__stats strong {
    display: block;
    font-size: 22px;
    line-height: 1;
    color: #fff;
    font-weight: 760;
}

.login-hero__stats span {
    display: block;
    margin-top: 9px;
    color: rgba(255, 255, 255, 0.68);
    font-size: 13px;
    font-weight: 650;
    text-transform: none;
}

.login-split__right {
    position: relative;
    flex-basis: 42%;
    padding: clamp(28px, 5vw, 72px);
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(250, 249, 247, 0.92)),
        var(--color-surface);
}

.login-split__right::before {
    content: "";
    position: absolute;
    inset: 20px;
    border: 1px solid rgba(154, 160, 173, 0.2);
    border-radius: 22px;
    pointer-events: none;
}

.login-split__brand {
    width: min(430px, 100%);
    gap: 18px;
    padding: 28px 0;
    animation: login-panel-in 0.55s ease both;
}

.login-split__mobile-badge {
    display: none;
    background: rgba(255, 255, 255, 0.88);
    border-color: rgba(212, 215, 224, 0.85);
    color: var(--brand-end);
    backdrop-filter: none;
}

.login-brand-mark {
    width: 250px;
    grid-template-rows: 102px 104px;
    margin-bottom: -2px;
}

.login-brand-mark__arc {
    width: 250px;
    height: 138px;
}

.login-brand-mark__arc text {
    font-size: 19px;
    letter-spacing: 7px;
}

.login-brand-mark__logo-frame {
    width: 106px;
    height: 106px;
    border-width: 1px;
    border-color: rgba(255, 255, 255, 0.72);
    box-shadow: 0 16px 42px var(--brand-shadow), inset 0 0 0 8px rgba(255, 255, 255, 0.75);
}

.login-split__logo {
    width: 82px;
    height: 82px;
}

.login-heading {
    width: 100%;
    text-align: center;
}

.login-heading__eyebrow {
    display: block;
    color: var(--brand-end);
    font-size: var(--fs-xs);
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.login-heading h2 {
    margin: 7px 0 6px;
    color: var(--color-text);
    font-size: 28px;
    font-weight: 800;
}

.login-heading p {
    max-width: 340px;
    margin: 0 auto;
    color: var(--color-muted);
    font-size: var(--fs-sm);
    line-height: 1.65;
}

.login-form {
    gap: 10px;
}

.login-field {
    height: 52px;
    border-radius: var(--radius-lg);
    background: #f7f7fa;
    border-color: #e8e9ef;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.85);
}

.login-field:hover {
    background: #fff;
    border-color: var(--brand-start);
}

.login-field:focus-within {
    background: #fff;
    border-color: var(--brand-start);
    box-shadow: 0 0 0 4px var(--brand-shadow);
}

.login-field__icon {
    width: 22px;
    justify-content: center;
    color: var(--brand-end);
}

.login-field__input {
    font-size: var(--fs-base);
    font-weight: 600;
}

.login-field .ss {
    flex: 1;
}

.login-field .ss__control {
    min-height: 100%;
    height: 100%;
    border: 0;
    border-radius: 0;
    padding: 0 4px 0 0;
    background: transparent;
    box-shadow: none;
}

.login-field .ss__control:hover,
.login-field .ss.open .ss__control {
    border: 0;
    background: transparent;
    box-shadow: none;
}

.login-field .ss__summary {
    color: var(--color-text);
    font-size: var(--fs-base);
    font-weight: 700;
}

.login-field .ss__panel {
    left: -50px;
    right: -18px;
    top: calc(100% + 10px);
    border-radius: var(--radius-lg);
}

.login-btn {
    height: 52px;
    border-radius: var(--radius-lg);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    position: relative;
    font-weight: 800;
}

.login-btn::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(100deg, transparent 0 32%, rgba(255, 255, 255, 0.28) 45%, transparent 58% 100%);
    transform: translateX(-120%);
    transition: transform 0.55s ease;
}

.login-btn:hover::before {
    transform: translateX(120%);
}

.login-btn .btn-label,
.login-btn .spinner-border {
    position: relative;
    z-index: 1;
}

.login-footer-note {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    max-width: 350px;
    color: var(--color-muted);
    font-size: var(--fs-xs);
    line-height: 1.5;
}

.login-footer-note i {
    color: var(--brand-end);
    margin-top: 1px;
}

.login-error {
    width: 100%;
    margin: 0;
    text-align: left;
}

@keyframes login-shape-drift {
    from { transform: translate3d(0, 0, 0) rotate(-4deg); }
    to { transform: translate3d(-18px, -16px, 0) rotate(5deg); }
}

@keyframes login-panel-in {
    from { opacity: 0; transform: translateY(12px); }
    to { opacity: 1; transform: translateY(0); }
}

@media (max-width: 1100px) {
    .login-hero {
        padding: 48px;
    }

    .login-hero h1 {
        font-size: 38px;
    }

    .login-hero__stats {
        grid-template-columns: 1fr;
        max-width: 280px;
    }

    .login-hero__stats div {
        min-height: 70px;
    }
}

@media (max-width: 900px) {
    .login-page {
        align-items: center;
        padding: 22px;
        background:
            linear-gradient(160deg, rgba(246, 247, 251, 0.96), #fff 62%),
            var(--color-bg);
    }

    .login-split {
        min-height: calc(100vh - 44px);
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .login-split::before {
        mask-image: linear-gradient(180deg, #000, transparent 86%);
        opacity: 0.55;
    }

    .login-split__left {
        display: block;
        position: absolute;
        inset: 0;
        flex: none;
        min-height: 0;
        background: transparent;
        pointer-events: none;
    }

    .login-split__media {
        display: none;
    }

    .login-split__left::before {
        display: none;
    }

    .login-hero {
        display: none;
    }

    .login-split__right {
        flex: none;
        width: min(100%, 440px);
        min-height: auto;
        padding: 20px;
        border: 1px solid rgba(212, 215, 224, 0.9);
        border-radius: 22px;
        box-shadow: 0 18px 48px rgba(31, 36, 51, 0.14);
    }

    .login-split__right::before {
        display: none;
    }

    .login-split__brand {
        padding: 8px 0 4px;
        gap: 16px;
    }

    .login-split__mobile-badge {
        display: inline-flex;
    }

    .login-brand-mark {
        width: 210px;
        grid-template-rows: 82px 86px;
    }

    .login-brand-mark__arc {
        width: 210px;
        height: 112px;
    }

    .login-brand-mark__arc text {
        font-size: 16px;
        letter-spacing: 6px;
    }

    .login-brand-mark__logo-frame {
        width: 88px;
        height: 88px;
        transform: translateY(-10px);
    }

    .login-split__logo {
        width: 68px;
        height: 68px;
    }

    .login-heading h2 {
        font-size: 24px;
    }
}

@media (max-width: 480px) {
    .login-page {
        padding: 12px;
        align-items: stretch;
    }

    .login-split {
        min-height: calc(100vh - 24px);
    }

    .login-split__right {
        width: 100%;
        padding: 18px 16px;
        border-radius: 18px;
    }

    .login-split__brand {
        gap: 14px;
    }

    .login-brand-mark {
        width: 184px;
        grid-template-rows: 68px 76px;
        margin-bottom: -8px;
    }

    .login-brand-mark__arc {
        width: 184px;
        height: 96px;
    }

    .login-brand-mark__arc text {
        font-size: 14px;
        letter-spacing: 5px;
    }

    .login-brand-mark__logo-frame {
        width: 76px;
        height: 76px;
    }

    .login-split__logo {
        width: 60px;
        height: 60px;
    }

    .login-heading p {
        font-size: var(--fs-xs);
    }

    .login-field,
    .login-btn {
        height: 50px;
        border-radius: var(--radius-md);
    }
}

@media (prefers-reduced-motion: reduce) {
    .login-split__shape,
    .login-split__brand {
        animation: none;
    }

    .login-btn::before {
        display: none;
    }
}

/* ============================================================
   Role edit
   ============================================================ */
.role-edit-page {
    --role-check-size: 20px;
}

.role-edit-card .card-app__body {
    padding: var(--space-5);
}

.role-compact-alert {
    align-items: flex-start;
    font-size: var(--fs-sm);
    line-height: 1.55;
}

.role-toolbar {
    display: flex;
    align-items: end;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
}

.role-search-field {
    flex: 1 1 280px;
    max-width: 420px;
    margin-bottom: 0;
}

.role-toolbar__meta {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2);
    flex-wrap: wrap;
    padding-bottom: 1px;
}

/* แยกกลุ่มสิทธิ์เมนู Web / App */
.role-perm-section {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    padding: var(--space-4);
    margin-bottom: var(--space-4);
}

.role-perm-section:last-child {
    margin-bottom: 0;
}

.role-perm-section__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
    margin-bottom: var(--space-3);
}

.role-perm-section__title {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--fs-base);
    font-weight: 700;
    color: var(--color-text);
}

.role-perm-section__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: var(--radius-md);
    background: var(--color-primary-soft, rgba(37, 99, 235, .12));
    color: var(--color-primary);
    font-size: 18px;
    flex-shrink: 0;
}

.role-perm-section__sub {
    display: block;
    font-size: var(--fs-xs);
    font-weight: 400;
    color: var(--color-muted);
    margin-top: 1px;
}

.role-perm-section__meta {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.role-perm-section__tools {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    flex-wrap: wrap;
    margin-bottom: var(--space-3);
}

.role-perm-section__tools .role-search-field {
    flex: 1 1 240px;
    max-width: 360px;
}

.role-bulk {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.role-perm-section__shown {
    font-size: var(--fs-xs);
    color: var(--color-muted);
}

.role-perm-section__empty {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-4);
    border: 1px dashed var(--color-border);
    border-radius: var(--radius-md);
    color: var(--color-muted);
    font-size: var(--fs-sm);
}

.role-matrix-wrap {
    max-height: 62vh;
    overflow: auto;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
}

.role-perm-table thead th {
    z-index: 2;
}

.role-perm-table tbody td {
    padding-top: 10px;
    padding-bottom: 10px;
}

.role-perm-table input[type="checkbox"],
.role-choice input[type="radio"],
.role-branch-option input[type="checkbox"],
.branch-pick-option input[type="checkbox"] {
    width: var(--role-check-size, 20px);
    height: var(--role-check-size, 20px);
    accent-color: var(--color-primary);
    flex-shrink: 0;
}

.role-perm-table input[type="checkbox"]:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

.role-menu-cell {
    display: grid;
    gap: 2px;
    min-width: 0;
}

.role-menu-cell strong {
    color: var(--color-text);
    font-size: var(--fs-sm);
    font-weight: 650;
    line-height: 1.25;
}

.role-menu-cell span {
    color: var(--color-muted);
    font-family: var(--ff-mono);
    font-size: var(--fs-xs);
    line-height: 1.25;
}

.role-choice-group {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-3);
}

.role-choice,
.role-branch-option,
.branch-pick-option {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 46px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    padding: 10px 12px;
    cursor: pointer;
    width: 100%;
    overflow-wrap: anywhere;
    transition: border-color 0.12s ease, background 0.12s ease, box-shadow 0.12s ease;
}

.role-choice:hover,
.role-branch-option:hover,
.branch-pick-option:hover {
    border-color: var(--color-primary);
    background: var(--color-surface-alt);
}

.role-choice:has(input:checked),
.role-branch-option:has(input:checked),
.branch-pick-option:has(input:checked) {
    border-color: var(--color-primary);
    background: var(--color-primary-soft);
    box-shadow: inset 3px 0 0 var(--color-primary);
}

.branch-pick-list,
.role-branch-list {
    column-count: 3;
    column-gap: var(--space-2);
    padding: 2px;
}

.branch-pick-list .branch-item {
    break-inside: avoid;
    margin-bottom: var(--space-2);
}

.role-branch-option,
.branch-pick-option {
    min-height: 42px;
    font-size: var(--fs-sm);
}

/* Marketplace ในฟอร์มสินค้า — อ่านอย่างเดียว (ตั้งค่าจริงที่หน้า Supplier) */
.mkp-readonly {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface-alt);
    padding: 12px 14px;
    margin-bottom: 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.mkp-readonly__row { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.mkp-readonly__value { font-weight: 600; text-align: right; }
.mkp-readonly__branches { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; max-height: 168px; overflow-y: auto; }
.mkp-readonly__chip {
    padding: 3px 9px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    font-size: var(--fs-xs);
}

/* Quick Setup template — inline ในการ์ดข้อมูล Role */
.role-quick-inline__row {
    display: flex;
    align-items: stretch;
    gap: var(--space-2);
}

.role-quick-inline__row .select-app {
    flex: 1 1 auto;
    min-width: 0;
}

.role-quick-inline__row .btn-app {
    flex-shrink: 0;
    white-space: nowrap;
}

.role-hint {
    color: var(--color-faint);
    cursor: help;
    font-size: var(--fs-sm);
}

/* แท็บหลัก */
.role-tabs {
    display: flex;
    gap: var(--space-1);
    border-bottom: 1px solid var(--color-border);
    margin-bottom: var(--space-4);
    overflow-x: auto;
}

.role-tab {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    border: 0;
    background: transparent;
    padding: var(--space-3) var(--space-4);
    margin-bottom: -1px;
    border-bottom: 2px solid transparent;
    color: var(--color-muted);
    font-size: var(--fs-base);
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: color 0.12s ease, border-color 0.12s ease;
}

.role-tab:hover {
    color: var(--color-primary-hover);
}

.role-tab.is-active {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
}

.role-tab__count {
    display: inline-flex;
    align-items: center;
    border-radius: var(--radius-pill);
    background: var(--color-surface-alt);
    color: var(--color-muted);
    font-size: var(--fs-xs);
    font-weight: 600;
    padding: 2px 8px;
}

.role-tab.is-active .role-tab__count {
    background: var(--color-primary-soft);
    color: var(--color-primary);
}

.role-tabpanel { display: none; }
.role-tabpanel.is-active { display: block; }

/* segmented Web / App */
.role-seg {
    display: inline-flex;
    gap: 4px;
    padding: 4px;
    border-radius: var(--radius-md);
    background: var(--color-surface-alt);
    border: 1px solid var(--color-border);
    margin-bottom: var(--space-3);
}

.role-seg__btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    border: 0;
    background: transparent;
    border-radius: var(--radius-sm);
    padding: 7px var(--space-3);
    color: var(--color-muted);
    font-size: var(--fs-sm);
    font-weight: 600;
    cursor: pointer;
    transition: background 0.12s ease, color 0.12s ease, box-shadow 0.12s ease;
}

.role-seg__btn.is-active {
    background: var(--color-surface);
    color: var(--color-primary);
    box-shadow: var(--shadow-sm);
}

.role-seg__badge {
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    color: var(--color-muted);
    font-size: var(--fs-xs);
    font-weight: 600;
    padding: 1px 7px;
}

.role-seg__btn.is-active .role-seg__badge {
    background: var(--color-primary-soft);
    color: var(--color-primary);
}

.role-seg-panel { display: none; }
.role-seg-panel.is-active { display: block; }

/* หัวคอลัมน์ matrix: label + checkbox เลือกทั้งคอลัมน์ */
.role-perm-table thead th .th-label {
    display: block;
    line-height: 1.2;
}

.role-perm-table thead th .th-all {
    margin-top: 4px;
    width: 17px;
    height: 17px;
    accent-color: var(--color-primary);
    cursor: pointer;
}

/* คอลัมน์ 'อ่าน' = ตัวควบคุม — เน้นให้เห็นชัด */
.role-perm-table thead th.col-gate,
.role-perm-table tbody td.col-gate {
    background: var(--color-primary-soft);
    box-shadow: inset 1px 0 0 var(--color-border), inset -1px 0 0 var(--color-border);
}

/* zebra ช่วยกวาดสายตาตามแถว */
.role-perm-table tbody tr:nth-child(even) td:not(.col-gate) {
    background: var(--color-surface-alt);
}

/* ขอบเขตสาขา & คลัง — สองคอลัมน์ */
.role-scope-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-4);
}

.role-scope-panel {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    padding: var(--space-4);
}

.role-scope-panel__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
}

.role-scope-panel__title {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--fs-base);
    font-weight: 700;
    color: var(--color-text);
}

.role-scope-picker__tools {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    flex-wrap: wrap;
    margin-bottom: var(--space-3);
}

.role-scope-picker .role-branch-list {
    column-count: initial;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: var(--space-2);
    align-content: start;
    max-height: 340px;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 2px;
}

.role-scope-picker .role-branch-list .branch-item {
    margin-bottom: 0;
}

/* ============================================================
   Matrix สิทธิ์ต่อหน้า — ใช้ร่วมกันระหว่าง /MainData/Roles และ /MainData/RoleLevels/Edit
   ============================================================ */
/* การ์ดต่อหน้า + หมวดใหญ่ */
.role-card-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 360px), 1fr)); gap: 12px; margin-top: 12px; }
.role-perm-card { position: relative; border: 1px solid var(--app-border, #e2e8f0); border-radius: 10px; padding: 12px 14px; background: var(--app-card-bg, #fff); transition: border-color .15s, box-shadow .15s; }
.role-perm-card.is-on { border-color: var(--app-primary, #2563eb); box-shadow: 0 0 0 1px var(--app-primary, #2563eb) inset; }
.role-perm-card__head { display: flex; }
.role-perm-card__gate { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; margin: 0; width: 100%; }
.role-perm-card__gate input[type="checkbox"] { margin-top: 3px; flex: 0 0 auto; width: 17px; height: 17px; }
.role-perm-card__title { display: flex; flex-direction: column; line-height: 1.3; }
.role-perm-card__title strong { font-size: 14px; }
.role-perm-card__code { font-size: 11px; color: var(--app-muted, #94a3b8); }
.role-perm-card__actions { display: flex; flex-wrap: wrap; gap: 8px 16px; margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--app-border, #e2e8f0); }
.role-perm-chk { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer; margin: 0; }
.role-perm-chk input[type="checkbox"]:disabled + span { opacity: .45; }
.role-perm-chk__code { font-size: 11px; color: var(--app-muted, #94a3b8); }
.role-cat { margin-top: 18px; }
.role-cat:first-child { margin-top: 8px; }
.role-cat__head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding-bottom: 6px; border-bottom: 2px solid var(--app-border, #e2e8f0); }
.role-cat__title { font-size: 14px; font-weight: 700; display: inline-flex; align-items: center; gap: 7px; }
.role-cat__count { font-size: 11px; font-weight: 600; color: var(--app-muted, #94a3b8); background: var(--app-soft, rgba(148,163,184,.15)); border-radius: 999px; padding: 1px 8px; }
.role-cat__tools { display: inline-flex; gap: 6px; }
.btn-xs-app { font-size: 11px !important; padding: 2px 8px !important; }
.role-embed-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 14px; }
.role-embed-head__title { font-size: 17px; font-weight: 700; margin: 0; }
/* หน้าที่ยังไม่มีใน V2 — เทา + กดไม่ได้ */
.role-perm-card.is-locked { opacity: .55; background: var(--app-soft, rgba(148,163,184,.08)); border-style: dashed; }
.role-perm-card.is-locked .role-perm-card__gate,
.role-perm-card.is-locked .role-perm-chk { cursor: not-allowed; }
.role-perm-card.is-locked input[type="checkbox"] { cursor: not-allowed; }
.role-perm-card__na { margin-left: auto; align-self: flex-start; font-size: 10px; font-weight: 600; color: var(--app-muted, #94a3b8);
    border: 1px solid var(--app-border, #e2e8f0); border-radius: 999px; padding: 1px 7px; white-space: nowrap; }

/* ============================================================
   Bulk user add
   ============================================================ */
.bulk-lines-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
}

.bulk-user-table-wrap {
    overflow-x: auto;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
}

/* กว้างพอดีพื้นที่ ไม่บังคับให้เลื่อนแนวนอน (ต่ำกว่า 768px สลับเป็นการ์ดอยู่แล้ว) */
.bulk-user-table {
    width: 100%;
    min-width: 720px;
}

.bulk-user-table th,
.bulk-user-table td {
    vertical-align: top;
}

.bulk-user-table .input-app,
.bulk-user-table .select-app {
    min-height: 38px;
    font-size: var(--fs-sm);
}

.bulk-row-no {
    color: var(--color-muted);
    font-family: var(--ff-mono);
    font-size: var(--fs-sm);
    padding-top: 17px !important;
    text-align: center;
}

.bulk-user-page.is-all-branch .bulk-position-input::placeholder {
    color: var(--color-faint);
}

.bulk-user-page.is-branch-role .bulk-position-input::placeholder {
    color: var(--color-muted);
}

/* ============================================================
   User form modal
   ============================================================ */
.modal-open-app {
    overflow: hidden;
}

.user-form-modal {
    position: fixed;
    inset: 0;
    z-index: 1800;
    display: none;
}

.user-form-modal.show {
    display: block;
}

.user-form-modal__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, 0.55);
    opacity: 0;
    transition: opacity 0.22s ease;
}

.user-form-modal.is-in .user-form-modal__backdrop {
    opacity: 1;
}

.user-form-modal__panel {
    position: absolute;
    top: 5vh;
    left: 50%;
    bottom: 5vh;
    width: min(920px, calc(100vw - 48px));
    transform: translateX(-50%) translateY(10px) scale(0.985);
    display: grid;
    grid-template-rows: auto 1fr;
    min-height: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
    opacity: 0;
    transition:
        opacity 0.22s ease,
        transform 0.24s cubic-bezier(0.16, 1, 0.3, 1);
}

.user-form-modal.is-in .user-form-modal__panel {
    opacity: 1;
    transform: translateX(-50%) translateY(0) scale(1);
}

.user-form-modal.is-drawer .user-form-modal__panel {
    top: 0;
    right: 0;
    bottom: 0;
    left: auto;
    width: 70vw;
    border-top: 0;
    border-right: 0;
    border-bottom: 0;
    border-radius: var(--radius-lg) 0 0 var(--radius-lg);
    opacity: 1;
    transform: translateX(100%);
    transition:
        opacity 0.16s ease,
        transform 0.28s cubic-bezier(0.16, 1, 0.3, 1);
}

.user-form-modal.is-in.is-drawer .user-form-modal__panel {
    transform: translateX(0);
}

.user-form-modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    border-bottom: 1px solid var(--color-border);
    background: var(--color-surface-alt);
    padding: 12px 16px;
}

.user-form-modal__header h2 {
    margin: 0;
    font-size: var(--fs-lg);
    font-weight: 700;
}

.user-form-modal__body {
    overflow-y: auto;
    min-height: 0;
    background: var(--color-surface);
}

/* ============================================================
   Image lightbox — modal ดูรูปเต็มจอ ซูม/หมุน/พลิก/เลื่อนรูป (wwwroot/js/image-lightbox.js)
   ============================================================ */
/* ห้ามล็อกสกอลล์ด้วย overflow:hidden ที่ html — สกอลบาร์หาย+สกอลล์ถูกดันเป็น 0 หน้าเด้ง JS กันที่ overlay แทน See LogHistory #51. */
.img-lb {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: none;
}

.img-lb.show {
    display: block;
}

.img-lb__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(10, 12, 20, 0.86);
    opacity: 0;
    transition: opacity 0.2s ease;
}

.img-lb.is-in .img-lb__backdrop {
    opacity: 1;
}

.img-lb__panel {
    position: absolute;
    inset: 0;
    display: grid;
    grid-template-rows: auto 1fr;
    min-height: 0;
    opacity: 0;
    transform: scale(0.98);
    transition: opacity 0.2s ease, transform 0.22s cubic-bezier(0.16, 1, 0.3, 1);
}

.img-lb.is-in .img-lb__panel {
    opacity: 1;
    transform: scale(1);
}

.img-lb__toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: 10px 14px;
    color: #fff;
}

.img-lb__counter {
    font-size: var(--fs-sm, 0.85rem);
    opacity: 0.85;
    min-width: 60px;
}

.img-lb__tools {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

.img-lb__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: var(--radius-md);
    border: 1px solid rgba(255, 255, 255, 0.22);
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
    cursor: pointer;
    transition: background 0.15s ease;
}

.img-lb__btn:hover {
    background: rgba(255, 255, 255, 0.18);
}

.img-lb__btn--close {
    background: rgba(220, 53, 69, 0.25);
    border-color: rgba(220, 53, 69, 0.4);
}

.img-lb__btn--close:hover {
    background: rgba(220, 53, 69, 0.4);
}

.img-lb__stage {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    min-height: 0;
    padding: 0 56px 24px;
}

.img-lb__img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    touch-action: none;
    user-select: none;
    transition: transform 0.08s linear;
}

.img-lb__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.22);
    background: rgba(255, 255, 255, 0.1);
    color: #fff;
    font-size: 1.1rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1;
}

.img-lb__nav:hover {
    background: rgba(255, 255, 255, 0.22);
}

.img-lb__nav--prev {
    left: 8px;
}

.img-lb__nav--next {
    right: 8px;
}

@media (max-width: 600px) {
    .img-lb__stage {
        padding: 0 40px 16px;
    }

    .img-lb__nav {
        width: 36px;
        height: 36px;
    }
}

/* ============================================================
   Item form — ตาราง template ใบสั่งของ (input ขนาดกะทัดรัดในเซลล์)
   ============================================================ */
.input-sm-app,
.select-sm-app {
    padding: 4px 8px;
    font-size: var(--fs-sm, 0.85rem);
}

.item-templ-table td {
    vertical-align: middle;
}

/* Modal จัดการ master หน่วยสั่ง (เพิ่ม/แก้ไข/ลบ) */
.ou-manager {
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.ou-add {
    display: flex;
    gap: 8px;
}

.ou-add .input-app {
    flex: 1 1 auto;
}

.ou-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.ou-empty {
    color: var(--color-text-muted, #6b7280);
    font-size: var(--fs-sm, 0.85rem);
    padding: 8px 2px;
}

.ou-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 6px 10px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.ou-row.is-editing {
    background: var(--color-surface-alt);
}

.ou-row__name {
    font-size: var(--fs-sm, 0.9rem);
    word-break: break-word;
}

.ou-row .input-app {
    flex: 1 1 auto;
}

.ou-row__actions {
    display: flex;
    align-items: center;
    gap: 4px;
    flex: 0 0 auto;
}

/* ===== modal จัดการคลัง (Warehouse) — ใช้โครง .ou-* ร่วมกัน ===== */
.wh-add { display: flex; flex-wrap: wrap; gap: 8px; }
.wh-add .input-app { flex: 1 1 140px; min-width: 0; }
.wh-add [data-wh-add] { flex: 0 0 auto; }
.wh-edit { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; flex: 1 1 auto; }
.wh-edit .input-app { flex: 1 1 120px; min-width: 0; }
.wh-code-fixed {
    flex: 0 0 auto;
    font-size: var(--fs-sm, 0.9rem);
    padding: 4px 8px;
    background: var(--color-surface-alt);
    border-radius: var(--radius-sm, 6px);
}
.wh-site-tag {
    display: inline-block;
    margin-left: 4px;
    padding: 1px 7px;
    font-size: var(--fs-xs, 0.72rem);
    color: var(--color-primary-hover);
    background: var(--color-primary-soft);
    border-radius: 10px;
    white-space: nowrap;
}

/* panel ขนาดเล็กสำหรับ modal กลางจอ (จัดการหน่วยสั่ง) */
.user-form-modal__panel--sm {
    width: min(520px, calc(100vw - 32px));
    bottom: auto;
    max-height: min(80vh, 640px);
}

/* สวิตช์เปิด/ปิด active ในตาราง Item (override bootstrap float ให้วางแนวนอนกับข้อความ) */
.item-active-switch {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding-left: 0;
    min-height: auto;
    cursor: pointer;
}

.item-active-switch .form-check-input {
    float: none;
    margin-left: 0;
    margin-top: 0;
    cursor: pointer;
}

/* เปิดใช้งาน = เขียว */
.item-active-switch .form-check-input:checked {
    background-color: var(--color-success, #16a34a);
    border-color: var(--color-success, #16a34a);
}

.item-active-switch .form-check-input:focus {
    border-color: var(--color-success, #16a34a);
    box-shadow: 0 0 0 0.2rem rgba(22, 163, 74, 0.25);
}

/* ประวัติการแก้ไข (audit log) ในฟอร์ม Item/User */
.audit-history {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-height: 240px;
    overflow-y: auto;
}

.audit-history__row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: 13px;
}

.audit-history__row .badge-app {
    flex: 0 0 auto;
    margin-top: 1px;
}

.audit-history__meta {
    color: var(--color-text-muted, #6b7280);
    font-size: 12px;
}

.audit-history__changes {
    color: var(--color-text-muted, #6b7280);
    font-size: 12px;
    margin-top: 4px;
    white-space: pre-line;
}

.user-form-saving {
    align-items: center;
    color: var(--color-text-muted, #6b7280);
    display: inline-flex;
    font-size: 13px;
    gap: 8px;
    min-height: 36px;
}

.user-form.is-saving {
    cursor: wait;
}

/* ส่วนเลือกรูปสินค้าในฟอร์ม Item */
.item-image-picker {
    display: flex;
    align-items: flex-start;
    gap: var(--space-4);
}

.item-image-picker__preview img {
    width: 96px;
    height: 96px;
    object-fit: cover;
    border-radius: 8px;
    border: 1px solid var(--color-border);
}

.item-templ-table .field__error {
    display: block;
    font-size: 11px;
}

/* บาร์โค้ดหลายตัว (I_ITEM_Barcode) ในฟอร์มสินค้า */
.barcode-rows { display: flex; flex-direction: column; gap: 8px; }
.barcode-row { display: flex; gap: 8px; align-items: center; }
.barcode-row .input-app { flex: 1 1 auto; min-width: 0; }
.barcode-row__unit { flex: 0 0 160px; max-width: 160px; }
@media (max-width: 600px) {
    .barcode-row__unit { flex: 1 1 120px; max-width: none; }
}

/* ============================================================
   User form (เพิ่ม/แก้ไขผู้ใช้) — ฟอร์มแบบ flat ใช้ทั้งหน้าเต็มและใน modal
   ============================================================ */
.user-form__section {
    padding: var(--space-4) var(--space-5);
}

.user-form__section + .user-form__section {
    border-top: 1px solid var(--color-border);
}

.user-form__section--alert {
    padding-bottom: 0;
}

.user-form__section--alert + .user-form__section {
    border-top: 0;
}

.user-form__title {
    margin: 0 0 var(--space-3);
    font-size: var(--fs-sm);
    font-weight: 700;
}

.user-form__hint {
    margin: -6px 0 var(--space-3);
    font-size: var(--fs-xs);
    color: var(--color-muted);
}

.user-form__hint.is-locked { color: var(--color-warning, #b45309); }

/* fieldset ครอบส่วนที่ล็อกตามสิทธิ์ — ต้อง reset ให้ไม่รบกวน layout ของ .row/.field */
.user-form__lock {
    border: 0;
    padding: 0;
    margin: 0;
    min-width: 0;
}

.user-form__lock:disabled { opacity: .65; }

/* ฟิลด์กะทัดรัด: ใช้ gutter ของ .row แทน margin ของ .field */
.user-form .field { margin-bottom: 0; gap: 4px; }

.user-form .input-app,
.user-form .select-app {
    min-height: 36px;
    padding: 6px 10px;
    font-size: var(--fs-sm);
}

.user-form .ms__control {
    min-height: 36px;
    padding: 5px 10px;
    font-size: var(--fs-sm);
}

.user-form .form-check-label { font-size: var(--fs-sm); }

.user-form__switches {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-5);
    padding-top: 2px;
}

/* ตัวเลือกขอบเขตสาขาแบบ pill */
.scope-choice {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
}

.scope-choice label {
    display: flex;
    align-items: center;
    gap: 8px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    padding: 7px 14px;
    cursor: pointer;
    font-size: var(--fs-sm);
}

.scope-choice label:hover { border-color: var(--color-primary); }

.scope-choice label:has(input:checked) {
    border-color: var(--color-primary);
    background: var(--color-primary-soft);
    font-weight: 600;
}

.scope-choice input[type="radio"] { accent-color: var(--color-primary); }

/* branch picker แบบกะทัดรัด — scope ใต้ .user-form เพื่อไม่กระทบหน้า Roles */
.branch-pick-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.branch-pick-toolbar .search-input { flex: 0 1 240px; }

.branch-pick-count {
    margin-left: auto;
    font-size: var(--fs-xs);
    color: var(--color-muted);
    white-space: nowrap;
}

.user-form .branch-pick-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
    gap: 4px;
    max-height: 224px;
    overflow-y: auto;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 6px;
    margin-top: var(--space-2);
}

.user-form .branch-pick-list .branch-item { margin-bottom: 0; }

.user-form .branch-pick-option {
    min-height: 30px;
    padding: 3px 8px;
    font-size: var(--fs-sm);
    border-color: transparent;
    background: transparent;
}

.user-form .branch-pick-option:hover {
    background: var(--color-surface-alt);
    border-color: var(--color-border);
}

.user-form .branch-pick-option:has(input:checked) {
    background: var(--color-primary-soft);
    border-color: transparent;
    box-shadow: none;
}

.user-form .branch-pick-option input[type="checkbox"] { width: 16px; height: 16px; }

.branch-item.is-hidden { display: none; }

/* save bar ท้ายฟอร์ม (sticky ทั้งใน modal และหน้าเต็ม) */
.user-form__save-bar { border-radius: 0 0 var(--radius-lg) var(--radius-lg); }

@media (max-width: 768px) {
    .user-form__section { padding: var(--space-4); }
}

.shell-hidden {
    background: var(--color-bg);
}

.shell-hidden > .breadcrumb-bar,
.shell-hidden > .page-header,
.shell-hidden > form,
.shell-hidden > .alert-app {
    margin-left: var(--space-5);
    margin-right: var(--space-5);
}

.shell-hidden > .breadcrumb-bar {
    margin-top: var(--space-5);
}

.shell-hidden > form {
    margin-bottom: 88px;
}

/* ============================================================
   App-Like Kit (PlanAppLikeMobileUI Phase 1) — base/desktop
   component กลาง opt-in: list loader state, filter drawer trigger,
   bottom action bar, link button. Mobile-specific อยู่ใน mobile-app.css
   ============================================================ */

/* list loader state (ใช้กับ data-app-list) */
.list-loading { padding: var(--space-4) var(--space-2); display: flex; flex-direction: column; gap: var(--space-3); }
.skeleton-row { height: 44px; border-radius: var(--radius-md); }

/* ปุ่มลิงก์ (เช่นปุ่ม "ลองใหม่" ใน error state) */
.btn-link-app {
    background: none; border: 0; padding: 0;
    color: var(--color-primary); font: inherit; font-weight: 600;
    cursor: pointer; text-decoration: underline;
}
.btn-link-app:hover { color: var(--color-primary-hover); }

/* filter trigger (มือถือ) — desktop ซ่อน, filter-bar แสดงปกติ */
.filter-trigger { display: none; }

/* bottom action bar มาตรฐาน (desktop = sticky ท้าย form เหมือน save-bar) */
.action-bar {
    position: sticky;
    bottom: 0;
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    padding: var(--space-3) var(--space-5);
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2);
    box-shadow: 0 -2px 8px rgba(15, 23, 42, 0.05);
    z-index: 40;   /* เหตุผลเดียวกับ .save-bar — ต้องอยู่เหนือแถบ tab/ค้นหาที่ sticky (30) */
}
.action-bar__spacer { flex: 1; }
/* คำโปรยในแถบปุ่ม: จอกว้างอยู่แถวเดียวกับปุ่ม (ชิดขวาก่อนปุ่ม) · จอแคบขึ้นบรรทัดเองเหนือปุ่ม
   order -1 = อยู่หน้าปุ่มเสมอไม่ว่าวางไว้ตรงไหนใน markup · basis 320px กันประโยคถูกบีบเป็นคอลัมน์แคบ */
.action-bar { flex-wrap: wrap; }
.action-bar__note {
    order: -1;
    flex: 1 1 320px;
    align-self: center;
    text-align: right;
    font-size: var(--fs-xs);
    color: var(--color-muted);
}
@media (max-width: 768px) {
    .action-bar__note { flex-basis: 100%; text-align: center; }
}

@media (max-width: 768px) {
    .bulk-lines-header {
        flex-direction: column;
        align-items: stretch;
    }

    .bulk-user-table-wrap {
        border: 0;
        border-radius: 0;
        overflow: visible;
        background: transparent;
    }

    .bulk-user-table,
    .bulk-user-table tbody,
    .bulk-user-table tr,
    .bulk-user-table td {
        display: block;
        width: 100%;
        min-width: 0;
    }

    .bulk-user-table thead {
        display: none;
    }

    .bulk-user-table tr {
        border: 1px solid var(--color-border);
        border-radius: var(--radius-md);
        background: var(--color-surface);
        box-shadow: var(--shadow-xs);
        margin-bottom: var(--space-3);
        padding: var(--space-3);
    }

    .bulk-user-table td {
        padding: 6px 0;
    }

    .bulk-row-no {
        padding-top: 0 !important;
        text-align: left;
        font-weight: 700;
    }

    .user-form-modal__panel {
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        width: auto;
        transform: none;
        opacity: 1;
        border-radius: 0;
        border: 0;
    }

    .user-form-modal.is-drawer .user-form-modal__panel {
        width: 100%;
        border-radius: 0;
    }

    /* modal กลางจอ (เช่น "ตั้งค่าหน่วยสั่ง"): บนมือถือ media query ตั้ง transform:none ไว้แล้ว
       แต่ rule `.user-form-modal.is-in .user-form-modal__panel` (translateX(-50%)) มี
       specificity สูงกว่าเลยทับกลับ ทำให้ panel ถูกเลื่อนออกนอกจอด้านซ้าย — ยกเลิกเฉพาะ
       ตัวที่ไม่ใช่ drawer (drawer มี rule เลื่อนของตัวเองอยู่แล้ว) */
    .user-form-modal.is-in:not(.is-drawer) .user-form-modal__panel {
        transform: none;
    }

    .shell-hidden > .breadcrumb-bar,
    .shell-hidden > .page-header,
    .shell-hidden > form,
    .shell-hidden > .alert-app {
        margin-left: var(--space-4);
        margin-right: var(--space-4);
    }
}

@media (prefers-reduced-motion: reduce) {
    .user-form-modal__backdrop,
    .user-form-modal__panel,
    .user-form-modal.is-drawer .user-form-modal__panel {
        transition: none;
    }
}

@media (max-width: 768px) {
    .role-edit-page {
        margin-left: calc(var(--space-4) * -1);
        margin-right: calc(var(--space-4) * -1);
    }

    .role-edit-card {
        border-left: 0;
        border-right: 0;
        border-radius: 0;
        box-shadow: none;
    }

    .role-edit-card .card-app__body {
        padding: var(--space-4);
    }

    .role-toolbar {
        align-items: stretch;
        flex-direction: column;
    }

    .role-search-field {
        max-width: none;
        width: 100%;
    }

    .role-toolbar__meta {
        justify-content: flex-start;
    }

    .role-matrix-wrap {
        max-height: none;
        overflow: visible;
        border: 0;
        border-radius: 0;
        box-shadow: none;
        background: transparent;
    }

    .role-perm-table thead {
        display: none;
    }

    .role-perm-table,
    .role-perm-table tbody,
    .role-perm-table tr,
    .role-perm-table td {
        display: block;
        width: 100%;
    }

    .role-perm-table tbody tr {
        border: 1px solid var(--color-border);
        border-radius: var(--radius-md);
        background: var(--color-surface);
        box-shadow: var(--shadow-xs);
        margin-bottom: var(--space-3);
        padding: var(--space-3);
    }

    .role-perm-table tbody tr:hover {
        background: var(--color-surface);
    }

    .role-menu-cell-wrap {
        margin-bottom: var(--space-3);
    }

    .role-menu-cell strong {
        font-size: var(--fs-base);
    }

    .role-perm-table tbody td[data-label] {
        display: flex;
        align-items: center;
        justify-content: space-between;
        min-height: 40px;
        padding: 6px 0;
        border-top: 1px solid var(--color-border);
    }

    .role-perm-table tbody td[data-label]::before {
        content: attr(data-label);
        color: var(--color-muted);
        font-size: var(--fs-sm);
        font-weight: 600;
        text-align: left;
    }

    .role-choice-group {
        grid-template-columns: 1fr;
    }

    .branch-pick-list,
    .role-branch-list {
        column-count: 1;
        max-height: none;
        overflow: visible;
    }

    .role-scope-grid {
        grid-template-columns: 1fr;
    }

    .role-scope-picker .role-branch-list {
        max-height: 50vh;
    }

    .role-quick-inline {
        margin-top: var(--space-2);
    }

    /* การ์ดเมนูบนมือถือ: ไม่ใช้เส้นขอบคอลัมน์/zebra ที่ออกแบบไว้สำหรับตาราง */
    .role-perm-table tbody td.col-gate {
        background: transparent;
        box-shadow: none;
    }

    .role-perm-table tbody tr:nth-child(even) td:not(.col-gate) {
        background: transparent;
    }
}

/* toggle เบา ๆ ในแถบเครื่องมือ (เช่น "เฉพาะที่เลือก" ในหน้าแก้ไขเอกสาร) */
.lite-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--color-muted);
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}
.lite-toggle input { width: 15px; height: 15px; accent-color: var(--color-primary); cursor: pointer; }
.lite-toggle:hover { color: var(--color-text); }

/* Quick Remark chips — ปุ่มลัดเติมหมายเหตุรายการ (หน้า Waste) */
/* แถบปุ่มลัดหมายเหตุ — บังคับแถวเดียว ล้นแล้วเลื่อนแนวนอน (กันแถวรายการสูงขึ้นเพราะ chip ตัดบรรทัด) */
.qr-chips {
    display: flex;
    gap: 6px;
    margin-bottom: 6px;
    overflow-x: auto;
    padding-bottom: 2px;
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
}
.qr-chips > .qr-chip { flex: 0 0 auto; }
.qr-chips::-webkit-scrollbar { height: 5px; }
.qr-chips::-webkit-scrollbar-thumb { background: var(--color-border-strong); border-radius: 999px; }

.qr-chip {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.6;
    color: var(--color-muted);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    cursor: pointer;
    white-space: nowrap;
    transition: background .12s, border-color .12s, color .12s;
}
.qr-chip:hover { color: var(--color-text); border-color: var(--color-primary); }
.qr-chip.is-active {
    color: #fff;
    background: var(--color-primary);
    border-color: var(--color-primary);
}

/* เมนู "แบบอื่น" ในหัวหน้า (ใช้ native <details>/<summary> ไม่ต้อง JS) */
.hdr-more { position: relative; display: inline-block; }
.hdr-more > summary { list-style: none; cursor: pointer; }
.hdr-more > summary::-webkit-details-marker { display: none; }
.hdr-more__menu {
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    min-width: 230px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md, 0 8px 24px rgba(15,23,42,.12));
    padding: 6px;
    z-index: 50;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.hdr-more__menu a {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-radius: var(--radius-sm, 8px);
    color: var(--color-text);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}
.hdr-more__menu a:hover { background: var(--color-surface-alt); }

/* ============================================================================
   Factory tabs — แถบ tab สลับ "หมวด" (โรงงาน) ในหน้าแก้ไขเอกสาร (RQ/PR)
   เดสก์ท็อป = แถบ pill กดสลับ; มือถือ = แถบ tab เลื่อนแนวนอน + sticky แบบแอป
   ============================================================================ */
.factory-tabs {
    display: flex;
    gap: 8px;
    align-items: center;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    /* ติดจอใต้ topbar ตอนเลื่อนลง (ทั้ง desktop และ mobile) */
    position: sticky;
    top: var(--topbar-height);
    z-index: 30;
    background: var(--color-bg);
    padding: 10px 2px;
    margin-bottom: 6px;
    box-shadow: 0 4px 8px -4px rgba(15, 23, 42, .08);
}
.factory-tabs::-webkit-scrollbar { height: 6px; }
.factory-tabs::-webkit-scrollbar-thumb { background: var(--color-border-strong); border-radius: 999px; }

.factory-tab {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-surface);
    color: var(--color-muted);
    font-size: 13px;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.factory-tab:hover { border-color: var(--color-border-strong); color: var(--color-text); }
.factory-tab.is-active {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
    box-shadow: 0 2px 6px rgba(169, 134, 112, .35);
}
.factory-tab.is-dim { opacity: .4; }            /* ไม่มี match ตอนค้นหา */
.factory-tab.is-active.is-dim { opacity: .7; }
.factory-tab > i { font-size: 13px; }

/* segmented pill group — เลือกโหมดนับรายวัน (เดือนคู่/คี่/รวมรหัส) */
.seg-group {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 8px;
}
.seg-btn {
    display: inline-flex;
    align-items: center;
    padding: 8px 16px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-surface);
    color: var(--color-muted);
    font-size: 13px;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.seg-btn:hover { border-color: var(--color-border-strong); color: var(--color-text); }
.seg-btn.is-active {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
    box-shadow: 0 2px 6px rgba(169, 134, 112, .35);
}
.seg-btn > i { font-size: 13px; margin-right: 2px; }
.seg-btn--ghost { border-style: dashed; }
.seg-divider {
    width: 1px;
    align-self: stretch;
    background: var(--color-border);
    margin: 2px 2px;
}

/* ===== มอดัลจัดการ Custom Template นับสต๊อก ===== */
.card-app__footer {
    padding: 12px 16px;
    border-top: 1px solid var(--color-border);
}
.tmpl-list { display: flex; flex-direction: column; gap: 8px; }
.tmpl-list__row {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 12px;
    border: 1px solid var(--color-border);
    border-radius: 10px;
    background: var(--color-surface);
}
.tmpl-list__name { flex: 1; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tmpl-del { color: var(--color-danger, #c0392b); }
.tmpl-list__tools { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.tmpl-list__search { flex: 1 1 220px; max-width: 360px; }
.tmpl-list__meta { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.tmpl-list__count { font-size: 12px; color: var(--color-muted); white-space: nowrap; }
.tmpl-list__actions { display: inline-flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.tmpl-list__row.is-enforced { border-color: var(--color-success); }
.count-monthly-tpl {
    display: flex; align-items: center; gap: 8px 12px; flex-wrap: wrap;
    margin-top: 12px; padding: 8px 12px;
    border: 1px solid var(--color-border); border-radius: 10px; background: var(--color-bg);
}
.count-monthly-tpl__text { flex: 1 1 240px; font-size: 13px; color: var(--color-text); }
.count-monthly-tpl__text > i { color: var(--color-primary); margin-right: 4px; }
.tpl-edit-head { display: flex; align-items: flex-end; gap: 16px; flex-wrap: wrap; }
.tpl-edit-note { flex-basis: 100%; font-size: 12px; color: var(--color-muted); }
@media (max-width: 640px) {
    .tmpl-list__row { flex-wrap: wrap; }
    .tmpl-list__name { flex-basis: 100%; white-space: normal; }
    .tmpl-list__actions { margin-left: auto; }
    .tmpl-list__search { max-width: none; }
}

.tmpl-selected { display: flex; flex-direction: column; gap: 6px; }
.tmpl-selected--empty {
    padding: 12px; border: 1px dashed var(--color-border); border-radius: 10px;
    color: var(--color-muted); font-size: 13px; text-align: center;
}
.tmpl-selected__row {
    display: flex; align-items: center; gap: 6px;
    padding: 6px 8px; border: 1px solid var(--color-border); border-radius: 8px;
    background: var(--color-surface);
}
.tmpl-selected__no {
    flex: 0 0 auto; width: 24px; height: 24px; border-radius: 999px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--color-primary); color: #fff; font-size: 12px; font-weight: 700;
}
.tmpl-selected__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }

.tmpl-pool {
    max-height: 260px; overflow-y: auto;
    border: 1px solid var(--color-border); border-radius: 10px;
    display: flex; flex-direction: column;
}
.tmpl-pool__row {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 10px; border: none; border-bottom: 1px solid var(--color-border);
    background: transparent; color: var(--color-text); text-align: left; font: inherit;
    cursor: pointer; width: 100%;
}
.tmpl-pool__row:last-child { border-bottom: none; }
.tmpl-pool__row:hover { background: var(--color-bg); }
.tmpl-pool__row.is-on { background: var(--color-bg); }  /* fallback: iPadOS/Safari < 16.2 ไม่รองรับ color-mix */
.tmpl-pool__row.is-on { background: color-mix(in srgb, var(--color-primary) 12%, transparent); }
.tmpl-pool__row > i { flex: 0 0 auto; font-size: 16px; color: var(--color-primary); }
.tmpl-pool__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }

/* ===== หน้าจัดการ Template (drag-and-drop) ===== */
.tpl-topbar { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; }
.tpl-dnd { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
@media (max-width: 820px) { .tpl-dnd { grid-template-columns: 1fr; } }
.tpl-pane { display: flex; flex-direction: column; }
.tpl-pane__body { display: flex; flex-direction: column; gap: 10px; }
.tpl-scroll { display: flex; flex-direction: column; gap: 6px; max-height: 56vh; overflow-y: auto; padding-right: 2px; }
.tpl-more { padding: 8px; font-size: 12px; color: var(--color-muted); text-align: center; }

.tpl-item {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 10px; border: 1px solid var(--color-border); border-radius: 8px;
    background: var(--color-surface);
}
/* ลากได้ทั้งการ์ด: เมาส์ใช้ระยะ, ทัชใช้กดค้าง (delay) จึงไม่ต้อง touch-action:none (นิ้วปัดยังเลื่อนสกอลล์ได้) */
.tpl-item__grip { color: var(--color-muted); flex: 0 0 auto; padding: 2px; font-size: 18px; }
.tpl-item.is-drag { cursor: grab; }
.tpl-item.is-drag:active { cursor: grabbing; }
.tpl-quickadd { display: flex; gap: 8px; flex-wrap: wrap; padding: 0 16px 10px; }
.tpl-drop-search { padding: 0 16px 8px; }
.tpl-item--pool { cursor: grab; }
.tpl-item--pool.is-added { opacity: .5; cursor: default; }
.tpl-item--pool.is-dragging { opacity: .4; }
.tpl-item__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.tpl-item__code { font-size: 12px; }
.tpl-item__name { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tpl-item__badge { flex: 0 0 auto; }
.tpl-item__added { color: var(--color-success); flex: 0 0 auto; width: 34px; text-align: center; }
.tpl-item__add { flex: 0 0 auto; color: var(--color-primary); cursor: pointer; }
.tpl-item__no {
    flex: 0 0 auto; width: 22px; height: 22px; border-radius: 999px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--color-primary); color: #fff; font-size: 11px; font-weight: 700;
}
.tpl-item__rm { flex: 0 0 auto; color: var(--color-danger, #c0392b); }
.tpl-item--overlay {
    box-shadow: 0 8px 20px rgba(15, 40, 52, .25); background: var(--color-surface);
    max-width: 320px; cursor: grabbing;
}
.tpl-item--overlay .tpl-item__name { margin-left: 8px; }

.tpl-drop { min-height: 160px; border-radius: 10px; transition: background .15s ease, box-shadow .15s ease; }
.tpl-drop.is-over { background: color-mix(in srgb, var(--color-primary) 10%, transparent); box-shadow: inset 0 0 0 2px var(--color-primary); }
.tpl-drop__empty {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
    min-height: 160px; color: var(--color-muted); text-align: center;
    border: 2px dashed var(--color-border); border-radius: 10px;
}
.tpl-drop__empty > i { font-size: 30px; }
/* เส้น preview ตำแหน่งที่จะแทรกตอนลากจากซ้ายมาขวา */
.tpl-drop__ph {
    display: flex; align-items: center; gap: 6px;
    padding: 8px 10px; margin: 1px 0;
    border: 2px dashed var(--color-primary); border-radius: 8px;
    background: color-mix(in srgb, var(--color-primary) 10%, transparent);
    color: var(--color-primary); font-size: 13px; font-weight: 600;
}

/* Import รหัสจากไฟล์ (หน้า Template) — โมดัลล็อก ปิดได้ด้วยปุ่ม X เท่านั้น */
.tpl-import.modal-backdrop-app { cursor: default; }
.tpl-import__box { max-width: 760px; max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); display: flex; flex-direction: column; }
.tpl-import .modal-app__footer { flex-wrap: wrap; }
.tpl-import .modal-app__header { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.tpl-import__body { overflow-y: auto; color: var(--color-text); display: flex; flex-direction: column; gap: 12px; }
.tpl-import__guide { border: 1px solid var(--color-border); border-radius: var(--radius-md); padding: 10px 12px; background: var(--color-surface-alt); }
.tpl-import__guide summary { cursor: pointer; font-weight: 600; }
.tpl-import__guide-grid { display: flex; gap: 16px; align-items: flex-start; margin-top: 8px; }
.tpl-import__guide ol { margin: 0; padding-left: 20px; font-size: var(--fs-sm); line-height: 1.6; flex: 1; }
.tpl-import__sample { flex: 0 0 auto; display: flex; flex-direction: column; gap: 8px; align-items: stretch; }
.tpl-import__sample table { border-collapse: collapse; font-size: 12px; background: var(--color-surface); }
.tpl-import__sample th, .tpl-import__sample td { border: 1px solid var(--color-border); padding: 3px 8px; min-width: 28px; }
.tpl-import__sample th { background: var(--color-surface-alt); color: var(--color-muted); font-weight: 600; text-align: center; }
.tpl-import__sample td:nth-child(2) { min-width: 96px; }
.tpl-import__drop {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
    min-height: 170px; padding: 16px; text-align: center; cursor: pointer;
    border: 2px dashed var(--color-border-strong, var(--color-border)); border-radius: 10px; color: var(--color-muted);
    transition: background .15s ease, border-color .15s ease;
}
.tpl-import__drop > i { font-size: 34px; }
.tpl-import__drop:hover, .tpl-import__drop:focus-visible { border-color: var(--color-primary); }
.tpl-import__drop.is-over { border-color: var(--color-primary); background: var(--color-primary-soft); color: var(--color-primary); }
.tpl-import__drop.is-busy { cursor: progress; }
.tpl-import__spin { animation: spin 1s linear infinite; }
.tpl-import__link { color: var(--color-primary); text-decoration: underline; }
.tpl-import__hint { font-size: 12px; color: var(--color-muted); }
.tpl-import__file { font-weight: 600; word-break: break-all; }
.tpl-import__stats { display: flex; flex-wrap: wrap; gap: 6px; }
.tpl-import__cols { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.tpl-import__cols h4 { display: flex; align-items: center; gap: 6px; margin: 0 0 6px; font-size: var(--fs-base); color: var(--color-success); }
.tpl-import__cols h4.is-danger { color: var(--color-danger); }
.tpl-import__cols h4 .btn-app { margin-left: auto; }
.tpl-import__list { max-height: 38vh; overflow-y: auto; border: 1px solid var(--color-border); border-radius: var(--radius-md); }
.tpl-import__row { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-bottom: 1px solid var(--color-border); font-size: 13px; }
.tpl-import__row:last-child { border-bottom: 0; }
.tpl-import__row.is-already { opacity: .6; }
.tpl-import__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--color-muted); }
.tpl-import__none { padding: 10px; font-size: 13px; color: var(--color-muted); text-align: center; }
@media (max-width: 640px) {
    .tpl-import__guide-grid { flex-direction: column; }
    .tpl-import__cols { grid-template-columns: 1fr; }
}
.factory-tab__name {
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.factory-tab__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 999px;
    background: var(--color-primary-soft);
    color: var(--color-primary-hover);
    font-size: 11px;
    font-weight: 700;
}
.factory-tab.is-active .factory-tab__count {
    background: rgba(255, 255, 255, .25);
    color: #fff;
}

/* มือถือ: tab bar เลื่อนแนวนอน + ติดจอใต้ topbar (เหมือนแอป) + แตะง่ายขึ้น + bleed เต็มขอบ */
@media (max-width: 992px) {
    .factory-tabs {
        margin: 0 calc(-1 * var(--space-4, 16px)) 6px;
        padding: 8px var(--space-4, 16px);
    }
    .factory-tab { padding: 9px 16px; font-size: 13px; }
    .factory-tab__name { max-width: 130px; }
}

/* แถวรายการ (read-only) หน้า Detail — ให้หน้าตาเหมือนแถวในหน้า Manage (FactoryLineEditor) */
.detail-item-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border-top: 1px solid var(--color-border);
    flex-wrap: wrap;
}
.detail-item-row:first-child { border-top: 0; }
.detail-item-row__img {
    width: 44px;
    height: 44px;
    object-fit: cover;
    border-radius: 8px;
    border: 1px solid var(--color-border);
    flex: 0 0 auto;
}
.detail-item-row__info { flex: 1 1 160px; min-width: 0; }
.detail-item-row__code { font-size: 11px; color: var(--color-faint); }
.detail-item-row__name { font-size: 14px; font-weight: 600; line-height: 1.3; }
.detail-item-row__sub { font-size: 11px; color: var(--color-faint); }
.detail-item-row__qty { flex: 0 0 auto; text-align: right; white-space: nowrap; }
.detail-item-row__qty strong { font-size: 16px; font-weight: 700; color: var(--color-text); }
.detail-item-row__qty span { font-size: 12px; color: var(--color-muted); margin-left: 4px; }

/* ===== Tooltip ไอคอนเล็ก ๆ (info hint) — ใช้บอกที่มาของข้อมูล/ช่วยอธิบาย field ===== */
.info-hint {
    position: relative;
    display: inline-flex;
    align-items: center;
    margin-left: 4px;
    color: var(--color-faint);
    cursor: help;
    line-height: 1;
    vertical-align: middle;
}
.info-hint > i { font-size: 13px; }
.info-hint:hover { color: var(--color-primary); }
.info-hint__bubble {
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%) translateY(4px);
    min-width: 180px;
    max-width: 280px;
    padding: 8px 10px;
    background: var(--color-text);
    color: #fff;
    font-size: var(--fs-xs);
    font-weight: 400;
    line-height: 1.45;
    white-space: normal;
    text-align: left;
    border-radius: 6px;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.22);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.12s ease, transform 0.12s ease;
    z-index: 1100;
    pointer-events: none;
}
.info-hint__bubble::after {
    content: "";
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border: 5px solid transparent;
    border-top-color: var(--color-text);
}
.info-hint:hover .info-hint__bubble,
.info-hint:focus .info-hint__bubble,
.info-hint:focus-within .info-hint__bubble {
    opacity: 1;
    visibility: visible;
    transform: translateX(-50%) translateY(0);
}
.info-hint__bubble code {
    color: #ffe08a;
    background: rgba(255, 255, 255, 0.12);
    padding: 0 3px;
    border-radius: 3px;
    font-size: 0.95em;
}

/* ============================================================
   โหมดสแกนบาร์โค้ดนับสต๊อก (BarcodeScanner.jsx) — overlay เต็มจอ
   ดีไซน์โทนมืดโดยเจตนา (ฉากหลังคือภาพกล้อง) → ใช้ได้ทั้ง 2 ธีม
   ============================================================ */
.bscan {
    position: fixed;
    inset: 0;
    z-index: 2110; /* เหนือโมดอล (.user-form-modal = 1800) — overlay เต็มจอถูกเปิดจากในโมดอลได้ See LogHistory #51. */
    display: flex;
    flex-direction: column;
    background: #0b0f14;
    color: #f1f5f9;
}
.bscan__video-wrap { position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden; }
.bscan__video { width: 100%; height: 100%; object-fit: cover; display: block; }
.bscan__error {
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 24px;
    text-align: center;
    font-size: 15px;
    color: #fca5a5;
}
.bscan__error .bi { font-size: 40px; }

/* กรอบเล็งกลางจอ + เส้นสแกน */
.bscan__aim {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}
.bscan__aim span {
    width: min(78vw, 420px);
    height: min(32vh, 200px);
    border: 2px solid rgba(255, 255, 255, 0.85);
    border-radius: 14px;
    box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.35); /* มืดรอบกรอบ ให้เล็งง่าย */
    position: relative;
    overflow: hidden;
}
.bscan__aim span::after {
    content: '';
    position: absolute;
    left: 8px;
    right: 8px;
    height: 2px;
    background: rgba(74, 222, 128, 0.9);
    animation: bscanline 1.6s ease-in-out infinite alternate;
}
@keyframes bscanline { from { top: 8%; } to { top: 92%; } }
@media (prefers-reduced-motion: reduce) { .bscan__aim span::after { animation: none; top: 50%; } }

.bscan__engine-tag {
    position: absolute;
    bottom: 10px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 11px;
    color: rgba(241, 245, 249, 0.75);
    background: rgba(0, 0, 0, 0.45);
    padding: 2px 10px;
    border-radius: 999px;
}

/* แถบบน: ปิด + สลับโหมด + ไฟฉาย */
.bscan__topbar {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: calc(10px + env(safe-area-inset-top, 0px)) 12px 10px;
    background: linear-gradient(rgba(0, 0, 0, 0.55), transparent);
}
.bscan__icon-btn {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.35);
    background: rgba(0, 0, 0, 0.45);
    color: #fff;
    font-size: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    flex: 0 0 auto;
}
.bscan__icon-btn.is-on { background: #fbbf24; border-color: #fbbf24; color: #1f2937; }
.bscan__icon-spacer { width: 42px; flex: 0 0 auto; }
.bscan__mode {
    display: flex;
    gap: 4px;
    background: rgba(0, 0, 0, 0.45);
    border: 1px solid rgba(255, 255, 255, 0.25);
    border-radius: 999px;
    padding: 3px;
}
.bscan__mode-btn {
    border: 0;
    background: transparent;
    color: rgba(255, 255, 255, 0.8);
    font-size: 13px;
    padding: 6px 14px;
    border-radius: 999px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}
.bscan__mode-btn.is-active { background: var(--color-primary, #2563eb); color: #fff; font-weight: 600; }

/* panel ล่าง: ผลสแกน/คีย์แพด/ผูกบาร์โค้ด */
.bscan__panel {
    flex: 0 0 auto;
    background: #111827;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    padding: 12px 14px calc(12px + env(safe-area-inset-bottom, 0px));
    max-height: 55vh;
    overflow-y: auto;
}
.bscan__hint {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    color: rgba(241, 245, 249, 0.7);
    font-size: 14px;
    padding: 10px 0;
}
.bscan__hint .bi { font-size: 20px; }
.bscan__card { display: flex; flex-direction: column; gap: 10px; }
.bscan__card--warn .bscan__notfound {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    color: #fbbf24;
    font-size: 14px;
}
.bscan__raw {
    background: rgba(255, 255, 255, 0.1);
    border-radius: 6px;
    padding: 1px 8px;
    font-size: 13px;
    word-break: break-all;
}
.bscan__item-code { font-size: 13px; color: rgba(241, 245, 249, 0.65); }
.bscan__item-name { font-size: 15px; font-weight: 600; }
.bscan__total {
    display: flex;
    align-items: baseline;
    gap: 8px;
    font-size: 14px;
    color: rgba(241, 245, 249, 0.75);
}
.bscan__total strong { font-size: 30px; color: #4ade80; line-height: 1; }
.bscan__actions { display: flex; gap: 8px; flex-wrap: wrap; }
/* ปุ่ม outline บนพื้นมืด — ยกคอนทราสต์จาก token ปกติ */
.bscan__panel .btn-app.btn-outline-app {
    background: transparent;
    color: #e2e8f0;
    border-color: rgba(255, 255, 255, 0.35);
}
.bscan__qty-input {
    font-size: 20px;
    text-align: center;
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
    border-color: rgba(255, 255, 255, 0.3);
}
.bscan__list-title { font-size: 14px; color: rgba(241, 245, 249, 0.85); }
.bscan__list { display: flex; flex-direction: column; gap: 6px; max-height: 32vh; overflow-y: auto; }
.bscan__list-item {
    display: flex;
    align-items: center;
    gap: 10px;
    text-align: left;
    border: 1px solid rgba(255, 255, 255, 0.15);
    background: rgba(255, 255, 255, 0.05);
    color: #f1f5f9;
    border-radius: 10px;
    padding: 10px 12px;
    font-size: 14px;
    cursor: pointer;
}
.bscan__list-item:active { background: rgba(255, 255, 255, 0.15); }
.bscan__list-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.bscan__list-total { flex: 0 0 auto; color: #4ade80; }
.bscan__list-empty { color: rgba(241, 245, 249, 0.55); font-size: 13px; padding: 8px 2px; }
.bscan__binding { color: rgba(241, 245, 249, 0.75); font-size: 13px; display: inline-flex; align-items: center; gap: 6px; }

/* scanner แบบ lite (หน้า Razor: โอน/รับของ) — ใช้ .bscan* ร่วมกับโหมดนับสต๊อก เพิ่มเฉพาะหัวข้อ + สถานะ error */
.bscan__lite-title {
    flex: 1 1 auto;
    text-align: center;
    font-size: 15px;
    font-weight: 600;
    color: #fff;
    text-shadow: 0 1px 3px rgba(0,0,0,.6);
}
.bscan__hint.is-error { color: #fca5a5; }


/* ===== รายการใบโอน (Transfer Create/Manage) =====
   ใช้แถว .count-row ชุดเดียวกับหน้าของเสีย/นับสต๊อก แต่ไม่มีรูปสินค้า */

/* .count-row ตั้ง display: flex/grid ไว้ ซึ่งชนะ display:none ของ [hidden] จาก UA
   → ตัวกรองคำค้นที่สั่ง row.hidden = true จะไม่มีผลถ้าไม่บังคับตรงนี้ */
.count-row[hidden] { display: none !important; }


/* เลขลำดับ — CSS counter นับเฉพาะแถวที่มองเห็น (กรองคำค้นแล้วเลขเรียงใหม่ให้เอง
   ไม่ต้องมี JS ไล่เขียนเลขทีละแถว ซึ่งมีได้ถึง ~2,500 แถว/หน้า) */
.trf-items { counter-reset: trfrow; }
.trf-items .count-row:not([hidden]) { counter-increment: trfrow; }
.trf-items .count-row:not([hidden]) .count-row__no::after { content: counter(trfrow); }

/* ช่อง "จำนวนโอน" ไม่ตั้งค่า 0 ไว้ล่วงหน้า — โชว์ 0 จาง ๆ เป็น placeholder แทน
   เพื่อไม่ให้พิมพ์ต่อท้ายเลข 0 เดิมแล้วกลายเป็นยอดผิด (5 -> 50) */
.trf-qty::placeholder { color: var(--color-faint); opacity: 1; }

/* ===== รายการของเสียที่ถูกนำออกจากเทมเพลตแล้ว (off-template) =====
   ใบเก่าที่บันทึกยอดไว้ก่อนรายการถูกปิด ต้องยังเห็นรายการนั้น (proc GetWasteDetailV2)
   แต่ต้องเห็นชัดว่า "รายการนี้ถูกนำออกจากการ Waste แล้ว" → กรอบแดง + แท็ก */
.row-offtmpl > td {
    background: var(--color-danger-soft);
    border-top: 2px solid var(--color-danger);
    border-bottom: 2px solid var(--color-danger);
}
.row-offtmpl > td:first-child { border-left: 2px solid var(--color-danger); }
.row-offtmpl > td:last-child { border-right: 2px solid var(--color-danger); }

/* แถวรายการในหน้าแก้ไข (React island — ไม่ใช่ตาราง) */
.item-offtmpl {
    background: var(--color-danger-soft);
    box-shadow: inset 0 0 0 2px var(--color-danger);
    border-radius: var(--radius-md);
}

/* แท็กบอกสถานะ/วันที่ถูกนำออก — วางต่อท้ายชื่อสินค้า */
.offtmpl-tag {
    display: inline-flex; align-items: center; gap: 4px;
    margin-left: 6px; padding: 1px 8px; border-radius: 999px;
    background: var(--color-danger); color: #fff;
    font-size: var(--fs-xs); font-weight: 600; white-space: nowrap;
}
.offtmpl-tag i { font-size: .85em; }

@media (max-width: 600px) {
    /* โหมดการ์ด: ตีกรอบรอบทั้งการ์ดแทนการตีกรอบราย cell */
    .table-app.table-cards tbody tr.row-offtmpl {
        border: 2px solid var(--color-danger);
        background: var(--color-danger-soft);
    }
    .table-app.table-cards tbody tr.row-offtmpl > td { border: 0; background: transparent; }
    .offtmpl-tag { margin-left: 0; margin-top: 4px; white-space: normal; }
}

/* ===== แผ่นเลือกแหล่งรูปภาพบนมือถือ (site.js: initImageSourcePicker) =====
   แตะปุ่ม "เพิ่มรูป/เลือกรูป" บนมือถือ → เลือกก่อนว่าจะถ่ายรูปใหม่ หรือหยิบจากคลังภาพ */
/* z-index ต้องเหนือทั้ง overlay กล้อง/สแกน (2110-2130) และโมดอล (1800) ไม่งั้นแผ่นเปิดอยู่ใต้ฉากดำ/ใต้โมดอล See LogHistory #24, #51. */
.img-src-sheet { position: fixed; inset: 0; z-index: 2140; display: flex; align-items: flex-end; justify-content: center; touch-action: manipulation; }
.img-src-sheet__backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.45); }
.img-src-sheet__panel {
    position: relative; width: min(460px, 100%);
    background: var(--color-surface); color: var(--color-text);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    padding: 14px 14px calc(14px + env(safe-area-inset-bottom, 0px));
    display: flex; flex-direction: column; gap: 8px;
    box-shadow: 0 -10px 40px rgba(0,0,0,.28);
    animation: imgSrcUp .18s ease-out;
}
@keyframes imgSrcUp { from { transform: translateY(16px); opacity: 0; } to { transform: none; opacity: 1; } }
.img-src-sheet__title { font-weight: 600; text-align: center; padding: 2px 0 6px; color: var(--color-muted); font-size: var(--fs-sm); }
.img-src-sheet__opt {
    display: flex; align-items: center; gap: 12px; width: 100%;
    padding: 14px 16px; border: 1px solid var(--color-border); border-radius: var(--radius-md);
    background: var(--color-bg); color: inherit; font: inherit; font-weight: 600; cursor: pointer;
}
.img-src-sheet__opt i { font-size: 20px; color: var(--color-primary); }
.img-src-sheet__opt:active { background: var(--color-border); }
.img-src-sheet__cancel {
    width: 100%; padding: 12px 16px; margin-top: 4px;
    border: none; border-radius: var(--radius-md);
    background: transparent; color: var(--color-muted); font: inherit; cursor: pointer;
}

/* จอใหญ่ (แท็บเล็ตแนวนอน) วางกลางจอแทนแปะขอบล่าง */
@media (min-width: 720px) {
    .img-src-sheet { align-items: center; }
    .img-src-sheet__panel { border-radius: var(--radius-lg); padding-bottom: 14px; }
}

/* ===== กล้องในหน้าเว็บ (camera-capture.js) — ต่อยอดจาก .bscan (โทนมืด ใช้ได้ทั้ง 2 ธีม) ===== */
.cam-cap { z-index: 2120; }   /* ต่ำกว่าแผ่นเลือกแหล่งรูป (2140) ได้ — แผ่นถูกถอดออกก่อนเปิดกล้องเสมอ */
.cam-cap__state {
    position: absolute; inset: 0; z-index: 2;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 12px; padding: 24px; text-align: center;
    background: #0b0f14; color: #e2e8f0; font-size: 15px; line-height: 1.6;
}
.cam-cap__state[hidden] { display: none; }
.cam-cap .bscan__topbar { z-index: 3; }   /* ปุ่มปิด/สลับกล้องต้องกดได้แม้ตอนขึ้นข้อความสถานะทับ */
.cam-cap__state .bi { font-size: 40px; }
.cam-cap__state.is-error { color: #fca5a5; }
.cam-cap__bar {
    flex: 0 0 auto; background: #0b0f14;
    padding: 10px 12px calc(12px + env(safe-area-inset-bottom, 0px));
    display: flex; flex-direction: column; gap: 10px;
}
.cam-cap__thumbs { display: flex; gap: 8px; overflow-x: auto; }
.cam-cap__thumbs:empty { display: none; }
.cam-cap__thumb { position: relative; flex: 0 0 auto; }
.cam-cap__thumb img {
    width: 56px; height: 56px; object-fit: cover; display: block;
    border-radius: var(--radius-md); border: 1px solid rgba(255, 255, 255, .3);
}
.cam-cap__thumb button {
    position: absolute; top: -6px; right: -6px; width: 22px; height: 22px;
    border-radius: 50%; border: none; background: rgba(0, 0, 0, .8); color: #fff;
    font-size: 12px; line-height: 1; cursor: pointer;
}
.cam-cap__actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.cam-cap__shutter {
    width: 64px; height: 64px; border-radius: 50%; flex: 0 0 auto;
    border: 3px solid rgba(255, 255, 255, .9); background: transparent;
    display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.cam-cap__shutter span { width: 48px; height: 48px; border-radius: 50%; background: #fff; display: block; }
.cam-cap__shutter:active span { transform: scale(.9); }
.cam-cap__shutter:disabled { opacity: .4; cursor: default; }
.cam-cap__actions .btn-app { flex: 1 1 0; min-width: 0; justify-content: center; }

/* ===== สแกนเอกสารเต็มจอ (doc-scan.js) — ต่อยอดจาก .bscan/.cam-cap ===== */
.dscan { z-index: 2130; background: #f4f4f4; color: #171717; color-scheme: light; }   /* เหนือกล้องถ่ายรูปปกติ (2120) */
.dscan__live { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.dscan__live[hidden] { display: none; }
.dscan__state {
    position: absolute; inset: 0; z-index: 4;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 12px; padding: 24px; text-align: center;
    background: rgba(20, 20, 20, .96); color: #fafafa; font-size: 15px; line-height: 1.6;
}
.dscan__state[hidden] { display: none; }
.dscan__state .bi { font-size: 40px; }
.dscan__state.is-error { color: #fff; }
.dscan .bscan__topbar { z-index: 5; }   /* ปุ่มปิดต้องกดได้แม้ตอนขึ้นข้อความสถานะทับ */
/* ปุ่ม outline บนพื้นมืด — token ปกติเป็นสีเข้ม อ่านไม่ออกบนฉากกล้อง (เหมือน .bscan__panel) */
.dscan .btn-app.btn-outline-app,
.cam-cap .btn-app.btn-outline-app {
    background: rgba(255, 255, 255, .06);
    color: #e2e8f0;
    border-color: rgba(255, 255, 255, .38);
}
.dscan .btn-app.btn-outline-app:disabled,
.cam-cap .btn-app.btn-outline-app:disabled { color: rgba(226, 232, 240, .45); border-color: rgba(255, 255, 255, .18); }
.dscan .btn-app.btn-outline-app:hover,
.cam-cap .btn-app.btn-outline-app:hover { background: rgba(255, 255, 255, .16); color: #fff; }
.dscan__hint {
    position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%); z-index: 3;
    max-width: 92%; text-align: center; font-size: 13px; line-height: 1.5;
    color: #f1f5f9; background: rgba(0, 0, 0, .55); padding: 6px 14px; border-radius: 999px;
}
.dscan__hint[hidden] { display: none; }
.dscan__hint.is-warn { background: #333; color: #fff; font-weight: 600; }

/* หน้าตรวจกรอบ — ภาพกินพื้นที่จอที่เหลือทั้งหมด (ของเดิมย่อลงกล่องเล็กจนอ่านไม่ออก) */
.dscan__edit {
    position: absolute; inset: 0; z-index: 2;
    display: flex; align-items: center; justify-content: center;
    padding: 8px; background: #f0f0f0; overflow: hidden;
}
.dscan__edit[hidden] { display: none; }
.dscan__stage { position: relative; touch-action: none; user-select: none; line-height: 0; }
.dscan__stage canvas { display: block; border-radius: 8px; background: #222; }
.dscan__svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.dscan__svg polygon { fill: rgba(255, 255, 255, .06); stroke: #fff; filter: drop-shadow(0 1px 2px #000); stroke-width: 2; }
.dscan__dot {
    position: absolute; width: 38px; height: 38px; margin: -19px 0 0 -19px; border-radius: 50%;
    border: 2px solid #171717; background: rgba(255, 255, 255, .6); cursor: grab; touch-action: none;
}
.dscan__dot::after { content: ''; position: absolute; inset: 11px; border-radius: 50%; background: #fff; }
.dscan__dot.is-drag { cursor: grabbing; background: rgba(0, 0, 0, .15); }

.dscan__bar {
    flex: 0 0 auto; background: #f0f0f0;
    padding: 10px 12px calc(12px + env(safe-area-inset-bottom, 0px));
}
.dscan__actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.dscan__actions[hidden] { display: none; }
.dscan__actions .btn-app { flex: 1 1 0; min-width: 0; justify-content: center; }
.dscan__actions--edit { flex-direction: column; align-items: stretch; gap: 10px; }
.dscan__modes { display: flex; gap: 6px; overflow-x: auto; }
.dscan__modes .btn-app { flex: 0 0 auto; }
.dscan__modes [data-ds-mode].is-on { background: #171717; color: #fff; border-color: #171717; }
.dscan__confirm { display: flex; gap: 10px; }
.dscan__confirm .btn-app { flex: 1 1 0; justify-content: center; }
/* ปุ่มหลักสีดำบนแถบเครื่องมือสีขาว */
.dscan .btn-app.btn-primary-app { background: #171717; border-color: #171717; color: #fff; font-weight: 600; }
.dscan .btn-app.btn-primary-app:hover { background: #333; border-color: #333; color: #fff; }
.dscan .btn-app.btn-primary-app:disabled { background: #e5e5e5; border-color: #e5e5e5; color: #999; }

/* จุดกลางขอบ — ลากเลื่อนทั้งด้าน */
.dscan__mid {
    position: absolute; width: 30px; height: 30px; margin: -15px 0 0 -15px; border-radius: 50%;
    border: 2px solid #171717; background: rgba(255, 255, 255, .45); cursor: grab; touch-action: none;
}
.dscan__mid.is-drag { cursor: grabbing; background: rgba(0, 0, 0, .15); }
/* แว่นขยายตอนลากจุด — วางฝั่งตรงข้ามกับนิ้ว */
.dscan__loupe {
    position: absolute; top: calc(64px + env(safe-area-inset-top, 0px)); z-index: 3; width: 116px; height: 116px; border-radius: 50%;
    border: 3px solid #fff; box-shadow: 0 4px 16px rgba(0, 0, 0, .6); background: #f0f0f0; pointer-events: none;
}
.dscan__loupe[hidden] { display: none; }

/* หน้าผลลัพธ์ — ภาพดัดแล้วตามฟิลเตอร์ที่เลือก */
.dscan__result {
    position: absolute; inset: 0; z-index: 2;
    display: flex; align-items: center; justify-content: center;
    padding: 8px 8px 56px; background: #f0f0f0; overflow: hidden;
}
.dscan__result[hidden] { display: none; }
.dscan__rwrap { position: relative; border-radius: 6px; overflow: hidden; background: #fff; box-shadow: 0 6px 24px rgba(0, 0, 0, .5); }
.dscan__rwrap canvas { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
.dscan__sweep {
    position: absolute; left: 0; right: 0; top: 0; height: 3px; opacity: 0; pointer-events: none;
    background: #4ade80; box-shadow: 0 0 14px 4px rgba(74, 222, 128, .7);
}
.dscan__rwrap.is-reveal [data-ds-rcanvas] { animation: dscan-reveal .9s ease-in-out both; }
.dscan__rwrap.is-reveal .dscan__sweep { animation: dscan-sweep .9s ease-in-out both; }
@keyframes dscan-reveal { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes dscan-sweep { 0% { top: 0; opacity: 1; } 92% { top: 100%; opacity: 1; } 100% { top: 100%; opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
    .dscan__rwrap.is-reveal [data-ds-rcanvas], .dscan__rwrap.is-reveal .dscan__sweep { animation: none; }
}
.dscan__filters { display: flex; gap: 8px; overflow-x: auto; align-items: center; }
.dscan__filters .btn-app { flex: 0 0 auto; }
.dscan__filter {
    flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 4px;
    padding: 4px; border-radius: 10px; border: 2px solid transparent;
    background: #f5f5f5; color: #666; font-size: 12px; cursor: pointer;
}
.dscan__thumb { width: 64px; height: 56px; display: flex; align-items: center; justify-content: center; }
.dscan__thumb canvas { display: block; width: auto; height: auto; max-width: 64px; max-height: 56px; border-radius: 4px; background: #fff; }
.dscan__filter.is-on { border-color: #171717; color: #171717; font-weight: 600; }
.dscan__hint.is-ok { background: #171717; color: #fff; font-weight: 600; }
.dscan__hint.is-block { background: #171717; color: #fff; font-weight: 600; }
.dscan__hint.is-busy::before {
    content: ''; display: inline-block; width: 12px; height: 12px; margin-right: 6px; vertical-align: -2px;
    border: 2px solid rgba(255, 255, 255, .4); border-top-color: #fff; border-radius: 50%;
    animation: dscan-spin .8s linear infinite;
}
@keyframes dscan-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .dscan__hint.is-busy::before { animation: none; } }

/* ถามก่อนปิดเมื่อสแกนหลายหน้าไว้แล้ว — อยู่ใน overlay เอง (appConfirm อยู่ใต้ z-index สแกน) */
.dscan__ask {
    position: absolute; inset: 0; z-index: 10;
    display: flex; align-items: center; justify-content: center; padding: 16px; background: rgba(0, 0, 0, .6);
}
.dscan__ask[hidden] { display: none; }
.dscan__ask-box {
    width: min(360px, 100%); display: flex; flex-direction: column; gap: 10px;
    padding: 18px; border-radius: 14px; background: #fff; color: #171717; font-size: 15px; line-height: 1.6;
}
.dscan__ask-box .btn-app { justify-content: center; }

/* Document scanner: white chrome, neutral workspace, camera kept unobstructed. */
.dscan [hidden] { display: none !important; }
.dscan__header { flex: 0 0 auto; background: #fff; border-bottom: 1px solid #e5e5e5; }
.dscan .bscan__topbar { position: relative; background: #fff; padding: calc(10px + env(safe-area-inset-top, 0px)) 16px 10px; }
.dscan .bscan__icon-btn { flex: 0 0 auto; border: 1px solid #e5e5e5; background: #fff; color: #171717; border-radius: 12px; width: 44px; height: 44px; }
/* ปุ่มปิดกับขั้นตอนอยู่แถวเดียวกัน — padding ขวาเท่าปุ่มปิดให้ขั้นตอนอยู่กลางจอ */
.dscan__steps { flex: 1; min-width: 0; display: flex; justify-content: center; gap: 24px; margin: 0; padding: 0 44px 0 0; list-style: none; }
.dscan__steps li { display: flex; align-items: center; gap: 7px; font-size: 12px; color: #737373; white-space: nowrap; }
.dscan__steps li > span { display: grid; place-items: center; width: 22px; height: 22px; border: 1px solid #ddd; border-radius: 50%; font-size: 10px; }
.dscan__steps [aria-current] { color: #171717; font-weight: 600; }
.dscan__steps [aria-current] > span { background: #171717; color: #fff; border-color: #171717; }
.dscan .bscan__video-wrap { background: #171717; }
.dscan__guide { position: absolute; inset: 12% 14% 18%; pointer-events: none; }
.dscan__guide span { position: absolute; width: 28px; height: 28px; border: solid rgba(255,255,255,.8); filter: drop-shadow(0 1px 2px #222); }
.dscan__guide span:nth-child(1) { top: 0; left: 0; border-width: 2px 0 0 2px; border-radius: 12px 0 0 0; }
.dscan__guide span:nth-child(2) { top: 0; right: 0; border-width: 2px 2px 0 0; border-radius: 0 12px 0 0; }
.dscan__guide span:nth-child(3) { bottom: 0; right: 0; border-width: 0 2px 2px 0; border-radius: 0 0 12px 0; }
.dscan__guide span:nth-child(4) { bottom: 0; left: 0; border-width: 0 0 2px 2px; border-radius: 0 0 0 12px; }
.dscan:not([data-screen="cam"]) .dscan__guide { display: none; }
.dscan__guide { transition: opacity .2s; }
.dscan.is-locked .dscan__guide { opacity: 0; }
.dscan__hint { width: max-content; max-width: min(90%, 640px); bottom: 16px; padding: 10px 16px; border-radius: 12px; color: #fff; background: rgba(23,23,23,.9); }
.dscan__hint.is-warn::before, .dscan__hint.is-block::before { content: '!'; display: inline-grid; place-items: center; border: 1px solid currentColor; border-radius: 50%; width: 18px; height: 18px; margin-right: 6px; font-weight: 700; }
.dscan__hint.is-ok::before { content: '\2713'; margin-right: 6px; }
.dscan__bar { background: #fff; border-top: 1px solid #e5e5e5; padding: 16px 20px calc(16px + env(safe-area-inset-bottom, 0px)); }
.dscan__actions { max-width: 720px; margin-inline: auto; gap: 16px; }
.dscan .btn-app { min-height: 44px; border-radius: 12px; }
.dscan .btn-app.btn-outline-app { background: #fff; border-color: #ddd; color: #262626; }
.dscan .btn-app.btn-outline-app:hover { background: #f5f5f5; color: #171717; }
.dscan .btn-app.btn-outline-app:disabled { color: #999; border-color: #eee; }
.dscan__capture { flex: 0 0 88px; display: flex; flex-direction: column; align-items: center; gap: 6px; font-size: 11px; color: #737373; }
.dscan .cam-cap__shutter { width: 68px; height: 68px; border: 2px solid #171717; background: #fff; }
.dscan .cam-cap__shutter span { width: 54px; height: 54px; background: #171717; }
.dscan__edit { padding-bottom: 56px; }
.dscan__stage canvas { border-radius: 2px; }
.dscan__dot, .dscan__mid { background: #fff; box-shadow: 0 1px 5px #0005; }
.dscan__dot::after { background: #171717; }
.dscan__filters { justify-content: center; padding: 2px 0 10px; }
.dscan__filter { padding: 6px; border-radius: 10px; }
.dscan__filter.is-on { background: #ededed; }
.dscan__modes { justify-content: center; padding-bottom: 8px; }
.dscan__confirm { flex-wrap: wrap; }
.dscan__confirm .btn-app { flex-basis: 100px; }
.dscan__rwrap { border-radius: 2px; box-shadow: 0 8px 28px #0002; }
.dscan__state .btn-app.btn-outline-app { background: #fff; color: #171717; }
.dscan button:focus-visible { outline: 2px solid #737373; outline-offset: 3px; }
@media (min-width: 900px) {
    .dscan .bscan__topbar { padding-inline: max(24px, calc((100vw - 1000px) / 2)); }
    .dscan__guide { left: calc(50% - 220px); right: calc(50% - 220px); }
}
@media (max-width: 380px) {
    .dscan .bscan__topbar { padding-inline: 12px; }
    .dscan__steps { gap: 12px; padding-right: 0; }
    .dscan__bar { padding-inline: 12px; }
    .dscan__actions { gap: 8px; }
    .dscan__filters { justify-content: flex-start; }
}
@media (max-height: 500px) and (orientation: landscape) {
    .dscan__steps, .dscan__capture > span { display: none; }
    .dscan .bscan__topbar { padding-block: 6px; }
    .dscan__bar { padding-top: 6px; padding-bottom: calc(6px + env(safe-area-inset-bottom, 0px)); }
    .dscan__actions--edit { flex-direction: row; align-items: center; }
    .dscan__modes, .dscan__filters { padding-bottom: 0; }
    .dscan__thumb { display: none; }
    .dscan__confirm { flex: 1; flex-wrap: nowrap; }
    .dscan__confirm .btn-app { flex-basis: 0; }
    .dscan .cam-cap__shutter { width: 48px; height: 48px; }
    .dscan .cam-cap__shutter span { width: 36px; height: 36px; }
}

/* ============================================================
   AX Monitor — การ์ด "งานค้างสาย AX" บนหน้า Dashboard
   (read-only; เห็นได้เมื่อมีสิทธิ์ VIEW เมนู 1925 '/Admin/AxMonitor')
   ============================================================ */
.axmon__totals {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-4);
    margin-bottom: var(--space-4);
}
.axmon__total {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    min-width: 130px;
}
.axmon__total-label { font-size: var(--fs-xs); color: var(--color-muted); }
.axmon__total-value { font-size: var(--fs-xl); font-weight: 700; line-height: 1.1; }
.axmon__total--pending { background: var(--color-warning-soft); border-color: transparent; }
.axmon__total--pending .axmon__total-value { color: var(--color-warning); }
.axmon__total--failed { background: var(--color-danger-soft); border-color: transparent; }
.axmon__total--failed .axmon__total-value { color: var(--color-danger); }
.axmon__total--ok { background: var(--color-success-soft); border-color: transparent; }
.axmon__total--ok .axmon__total-value { color: var(--color-success); }
.axmon__range { font-size: var(--fs-sm); margin-left: auto; }

/* 2 หมวด (ขาเข้า/ขาออก) — จอกว้างวางคู่กัน, จอแคบเรียงลงมา */
.axmon__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: var(--space-4);
}
.axmon-cat {
    border: 1px solid var(--color-border);
    border-left: 4px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-4);
    background: var(--color-surface);
}
.axmon-cat.is-failed { border-left-color: var(--color-danger); }
.axmon-cat.is-pending { border-left-color: var(--color-warning); }
.axmon-cat.is-clean { border-left-color: var(--color-success); }
.axmon-cat__head {
    display: flex;
    align-items: flex-start;   /* หัวการ์ดมี 2 บรรทัด (ชื่อหมวด + คำอธิบาย) → ไอคอนชิดบรรทัดแรก */
    gap: var(--space-2);
    font-weight: 600;
    font-size: var(--fs-sm);
    margin-bottom: var(--space-3);
}
.axmon-cat__head > .bi { font-size: 1.05rem; line-height: 1; }
.axmon-cat__title { overflow-wrap: anywhere; }
.axmon-cat__sub {
    display: block;
    font-size: var(--fs-xs);
    font-weight: 400;
    color: var(--color-muted);
    margin-top: 2px;
}
.axmon-cat__nums { display: flex; gap: var(--space-5); }

/* บรรทัดย่อยรายประเภทเอกสารในการ์ดกลุ่ม — ตัวเลขที่กดได้พาไปหน้าที่จัดการได้จริง */
.axmon-rows {
    margin-top: var(--space-4);
    border-top: 1px solid var(--color-border);
    padding-top: var(--space-2);
}
.axmon-row {
    display: grid;
    grid-template-columns: 1fr 56px 64px;
    align-items: center;
    gap: var(--space-2);
    padding: 5px 0;
    font-size: var(--fs-sm);
}
.axmon-row + .axmon-row { border-top: 1px dashed var(--color-border); }
.axmon-row--head {
    font-size: var(--fs-xs);
    color: var(--color-muted);
    padding-top: 0;
    padding-bottom: 2px;
}
.axmon-row--head + .axmon-row { border-top: none; }
.axmon-row--head > span:not(:first-child),
.axmon-row__num { text-align: right; }
.axmon-row__label {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
    overflow-wrap: anywhere;
}
.axmon-row__label .bi { color: var(--color-muted); flex: 0 0 auto; }
.axmon-row__num {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    text-decoration: none;
    color: inherit;
}
a.axmon-row__num { text-decoration: underline; text-underline-offset: 3px; }
.axmon-num { display: flex; flex-direction: column; gap: 2px; }
.axmon-num__label { font-size: var(--fs-xs); color: var(--color-muted); }
.axmon-num__value {
    font-size: var(--fs-lg);
    font-weight: 700;
    line-height: 1.1;
    text-decoration: none;
    color: inherit;
}
a.axmon-num__value { text-decoration: underline; text-underline-offset: 3px; }
.axmon-num__value--warn { color: var(--color-warning); }
.axmon-num__value--danger { color: var(--color-danger); }

/* มือถือ: ตัวเลขรวมเรียงเต็มความกว้าง อ่านง่ายกว่าเบียดกัน */
@media (max-width: 575.98px) {
    .axmon__total { flex: 1 1 45%; min-width: 0; }
    .axmon__range { margin-left: 0; flex: 1 1 100%; }
}

/* Dashboard — AI ตรวจรูปบิล (สิทธิ์ VIEW เมนู 1930 '/Admin/AiUsage') */
.aiuse__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; font-size: var(--fs-sm); color: var(--color-muted); margin-bottom: var(--space-3); }
.aiuse__tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--space-3); margin-bottom: var(--space-4); }
.aiuse__tile { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: var(--space-3) var(--space-4); border: 1px solid var(--color-border); border-radius: var(--radius-md); }
.aiuse__tile--cost { background: var(--color-primary-soft); border-color: transparent; }
.aiuse__label { display: flex; align-items: center; gap: 6px; font-size: var(--fs-xs); color: var(--color-muted); }
.aiuse__value { font-size: var(--fs-xl); font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.aiuse__value.is-zero { color: var(--color-muted); font-weight: 600; }
.aiuse__sub { font-size: var(--fs-xs); color: var(--color-muted); font-variant-numeric: tabular-nums; }
.aiuse__table td.num, .aiuse__table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.aiuse__table td.nowrap { white-space: nowrap; }
.aiuse__foot { display: flex; justify-content: flex-end; margin-top: var(--space-3); font-size: var(--fs-sm); }

/* ============================================================
   Dashboard — งานรายวัน (Daily Mission) : การ์ดตัวเลข
   ตัวเลขค้าง/สถานะเป็นตัวเอก · แถบสีซ้ายบอกสถานะโดยไม่ต้องอ่าน
   ============================================================ */
.mission-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
    gap: 8px;
}
.mission-tile {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 10px 12px 11px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface-alt);
    text-decoration: none;
    color: var(--color-text);
    transition: border-color .15s, background .15s, transform .15s;
}
.mission-tile::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background: var(--color-border-strong);
}
.mission-tile:hover { border-color: var(--color-border-strong); background: var(--color-surface); color: var(--color-text); }
.mission-tile:focus-visible { outline: 2px solid var(--color-info); outline-offset: 2px; }

.mission-tile__label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: var(--fs-xs);
    color: var(--color-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.mission-tile__label i { font-size: 13px; flex: none; }

.mission-tile__value {
    display: flex;
    align-items: center;
    gap: 6px;
    font-family: var(--ff-mono);
    font-variant-numeric: tabular-nums;
    font-size: 22px;
    font-weight: 600;
    line-height: 1.05;
    letter-spacing: -.02em;
}
.mission-tile__value i { display: none; font-size: 15px; }
.mission-tile__unit { font-size: var(--fs-xs); color: var(--color-faint); }

/* รอทำ = โทนเตือน · ทำแล้ว = เขียว + ติ๊ก · โหลดพัง = แดง */
.mission-tile.is-pending::before { background: var(--color-warning); }
.mission-tile.is-pending .mission-tile__value { color: var(--color-warning); }

.mission-tile.is-done::before { background: var(--color-success); }
.mission-tile.is-done .mission-tile__value { color: var(--color-success); }

/* ค่าที่เป็นคำ (เช่น "ลงนับแล้ว") ใช้ฟอนต์ปกติ ส่วนตัวเลขคงขนาด/ฟอนต์เดียวกันทุกสถานะ */
.mission-tile__value.is-word { font-family: var(--ff-sans); font-size: var(--fs-md); }
.mission-tile.is-done .mission-tile__value i { display: inline-block; }

.mission-tile.is-failed::before { background: var(--color-danger); }
.mission-tile.is-failed .mission-tile__value { color: var(--color-danger); }

@media (max-width: 575.98px) {
    .mission-list { grid-template-columns: 1fr 1fr; }
}

/* dropdown กรองสาขาบนการ์ดงานรายวัน (โชว์เมื่อผู้ใช้เห็นมากกว่า 1 สาขา) */
.mission-branch { min-width: 190px; margin-bottom: var(--space-3); }
.card-app__header .mission-branch { margin-bottom: 0; min-width: 210px; }
.mission-range { margin-bottom: var(--space-3); }
.card-app__header [data-mission-range] { min-width: 230px; }

/* ===== ลายเซ็นเอกสาร V2 (wwwroot/js/doc-signature.js) — ต้องอยู่เหนือ modal ยืนยันส่งของ ===== */
.ds-modal { position: fixed; inset: 0; z-index: calc(var(--z-confirm) + 10); display: flex; align-items: center; justify-content: center; padding: 16px; }
.ds-modal[hidden] { display: none; }
.ds-modal__backdrop { position: absolute; inset: 0; background: rgba(15, 23, 42, .55); cursor: pointer; }
.ds-modal__panel { position: relative; width: min(640px, 100%); max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); overflow: auto; background: var(--surface-solid, var(--color-surface)); color: var(--color-text); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.ds-modal__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ds-modal__title { font-size: var(--fs-lg); margin: 0; }
.ds-modal__x { border: 0; background: transparent; color: var(--color-muted); font-size: 18px; cursor: pointer; min-width: 44px; min-height: 44px; }
.ds-modal__foot { display: flex; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
.ds-tabs { display: flex; gap: 6px; flex-wrap: wrap; }
.ds-tab { flex: 1 1 140px; border: 1px solid var(--color-border); background: var(--color-surface-alt); color: var(--color-text); border-radius: var(--radius-md); padding: 8px 10px; font-size: var(--fs-sm); cursor: pointer; }
.ds-tab.is-active { border-color: var(--color-primary); background: var(--color-primary-soft); color: var(--color-primary); font-weight: 600; }
.ds-canvas { width: 100%; height: clamp(200px, 38vh, 320px); background: #fff; border: 1px dashed var(--color-border-strong); border-radius: var(--radius-md); touch-action: none; cursor: crosshair; display: block; }
.ds-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; }
.ds-hint { color: var(--color-muted); font-size: var(--fs-sm); }
.ds-check { display: flex; align-items: center; gap: 8px; margin-top: 10px; font-size: var(--fs-sm); cursor: pointer; }
.ds-preview { background: #fff; border: 1px solid var(--color-border); border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; min-height: 140px; padding: 8px; }
.ds-preview img { max-width: 100%; max-height: 180px; }
.ds-empty { color: var(--color-muted); font-size: var(--fs-sm); padding: 24px 8px; text-align: center; }
body.ds-open { overflow: hidden; }
/* กล่องแสดงลายเซ็นในหน้าเอกสาร (ปุ่ม "เซ็นชื่อ" + รูปย่อ) */
.ds-slot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ds-slot__img { height: 48px; max-width: 180px; background: #fff; border: 1px solid var(--color-border); border-radius: var(--radius-sm); padding: 2px 6px; object-fit: contain; }
.ds-slot__meta { font-size: var(--fs-xs); color: var(--color-muted); }
.ds-error { color: var(--color-danger); background: var(--color-danger-soft); border-radius: var(--radius-sm); padding: 8px 10px; font-size: var(--fs-sm); }
.ds-loading { color: var(--color-muted); font-size: var(--fs-sm); padding: 24px 8px; text-align: center; }
/* toast ที่เด้งตอน modal ลายเซ็นเปิดต้องอยู่เหนือ scrim */
body.ds-open .toast-stack { z-index: calc(var(--z-confirm) + 20); }
