/* =====================================================================
   RWDF — Responsive Web Development Framework (UWW)
   ไฟล์กลางไฟล์เดียวที่กำหนดมาตรฐานการแสดงผลของทุกหน้า/ทุก Module
   โหลดเป็นไฟล์สุดท้ายใน <head> (หลัง sidebar.css / premium.css)
   ต้องใช้คู่กับ assets/js/rwdf.js (defer)

   หลักการ
   1) Mobile First  — ค่าเริ่มต้นคือมือถือ แล้วขยายด้วย @media (min-width)
   2) Breakpoints กลาง (CSS Pixel — CSS ใช้ var() ใน @media ไม่ได้ จึงต้องเขียนตัวเลขตรงนี้ให้ตรงกัน)
        XS   0 –  575   Smartphone
        SM 576 –  767   Large Smartphone      @media (min-width: 576px)
        MD 768 –  991   Tablet                @media (min-width: 768px)
        LG 992 – 1199   Small Laptop          @media (min-width: 992px)   ← sidebar เต็ม
        XL 1200– 1399   Desktop               @media (min-width: 1200px)
        XXL 1400+       Large Desktop         @media (min-width: 1400px)
      rwdf.js อ่านชุดเดียวกันจาก --rw-bp-* และตั้ง <html data-bp="xs|sm|md|lg|xl|xxl">
   3) ค่ากลางทั้งหมดเป็น CSS Variables (--rw-*) — แก้ที่เดียวได้ทั้งระบบ
   4) Component ปรับตามพื้นที่ที่ได้รับ ไม่ผูกกับยี่ห้อ/รุ่นอุปกรณ์
   5) กฎของไฟล์นี้ใช้ความจำเพาะต่ำ (ส่วนใหญ่ไม่มี !important) — หน้าที่ต้องการต่างออกไป
      override ได้ด้วย selector ที่เจาะจงกว่า หรือ ตั้งค่าตัวแปร --rw-* เฉพาะหน้า/เฉพาะ component

   คลาสสำหรับงานใหม่ (reusable components)
     .rw-container       กรอบเนื้อหา กว้างสูงสุดตามจอ + gutter มาตรฐาน
     .rw-grid            Dashboard/การ์ด: 1 → 2 → 3 → 4 คอลัมน์ (ปรับด้วย --rw-cols-*)
     .rw-form            ฟอร์ม: 1 → 2 → 3 คอลัมน์   (.rw-span-all = เต็มแถว)
     .rw-table-wrap      กล่องเลื่อนแนวนอนของตาราง (rwdf.js ครอบให้เองถ้าลืม)
     .rw-table-cards     ตารางที่เปลี่ยนเป็นการ์ดบนมือถือ (rwdf.js เติม data-label จากหัวตาราง)
     .rw-modal           กล่อง modal: เกือบเต็มจอ → ขนาดกลาง → จำกัดความกว้าง
     .rw-stack / .rw-cluster   แนวตั้ง / แถวที่ตัดบรรทัดเอง
     .rw-hide-down-{sm,md,lg} / .rw-hide-up-{sm,md,lg}   ซ่อนตาม breakpoint
     .rw-sr-only         ซ่อนจากสายตา แต่ screen reader อ่านได้
   ===================================================================== */

/* ── 1) Design Tokens ─────────────────────────────────────────────── */
:root {
  /* breakpoints (อ้างอิงให้ JS / เอกสาร — ใช้ใน @media โดยตรงไม่ได้) */
  --rw-bp-sm: 576;
  --rw-bp-md: 768;
  --rw-bp-lg: 992;
  --rw-bp-xl: 1200;
  --rw-bp-xxl: 1400;

  /* ระยะห่าง (spacing scale) */
  --rw-space-1: 4px;
  --rw-space-2: 8px;
  --rw-space-3: 12px;
  --rw-space-4: 16px;
  --rw-space-5: 24px;
  --rw-space-6: 32px;

  /* gutter ด้านข้างของพื้นที่เนื้อหา: มือถือแคบ → จอใหญ่ (ปรับต่อเนื่องตามความกว้าง) */
  --rw-gutter: clamp(14px, 4vw, 20px);
  --rw-gutter-lg: 36px;
  --rw-pad-top: 16px;
  --rw-pad-bottom: 24px;

  /* ตัวอักษร: ปรับต่อเนื่อง 15px (มือถือ) → 16px (จอใหญ่) */
  --rw-fs-body: clamp(15px, 14.4px + .17vw, 16px);
  --rw-fs-small: .875rem;
  --rw-fs-h1: clamp(1.3rem, 1.1rem + 1vw, 1.75rem);
  --rw-fs-h2: clamp(1.1rem, 1rem + .5vw, 1.4rem);
  --rw-lh-body: 1.5;

  /* ปุ่ม/ช่องกรอก */
  --rw-tap: 44px;          /* ขนาดแตะขั้นต่ำสำหรับ touch (WCAG 2.5.5 / Apple HIG) */
  --rw-control-h: 40px;    /* ความสูงมาตรฐานของ control เมื่อใช้เมาส์ */
  --rw-control-fs: 16px;   /* ≥16px กัน iOS ซูมหน้าเองตอนโฟกัสช่องกรอก */

  /* รูปทรง */
  --rw-radius: 12px;
  --rw-radius-lg: 20px;

  /* Layout */
  --rw-content-max: 1600px;
  --rw-modal-w: 640px;
  --rw-cols-xs: 1;
  --rw-cols-md: 2;
  --rw-cols-lg: 3;
  --rw-cols-xl: 4;
  --rw-form-cols-xs: 1;
  --rw-form-cols-md: 2;
  --rw-form-cols-xl: 3;
}

/* ── 2) Base (ทุกขนาดจอ) ──────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

body {
  /* !important: admin.css / บางหน้าตั้ง 15px !important ไว้ — ฟอนต์ฐานต้องมาจาก token กลางที่เดียว */
  font-size: var(--rw-fs-body) !important;
  line-height: var(--rw-lh-body);
  /* ไม่มีเลื่อนแนวนอนทั้งหน้า (ส่วนที่กว้างต้องเลื่อนในกล่องของตัวเอง) */
  overflow-x: clip;
}

img, video, canvas, svg, iframe { max-width: 100%; }
img, video { height: auto; }
/* ภาพที่ถูกกำหนดทั้ง width/height ไว้ในแอตทริบิวต์ ต้องไม่บิดสัดส่วนเมื่อถูกบีบ */
img[width][height] { height: auto; }
.main img { object-fit: contain; }
.main img.rw-cover, .main .avatar img, .main img[class*="avatar"], .main img[class*="photo"] { object-fit: cover; }

/* คำยาว (ชื่อไฟล์/URL/อีเมล) ตัดบรรทัดได้ ไม่ดันกรอบให้ล้น
   ใช้ break-word (ไม่ใช่ anywhere) และ *ไม่* ใส่ min-width:0 ให้ div/span ทั่วไป — เคยทำให้ pill/นาฬิกาในแถบบนถูกบีบ
   (ถ้า flex/grid child ของหน้าใดต้องหดได้ ให้ใส่ min-width:0 เฉพาะ component นั้น) */
.main { min-width: 0; }
.main :where(p, li, td, th, h1, h2, h3, h4, label, a, [class*="badge"], [class*="chip"], [class*="pill"], [class*="tag"]) {
  overflow-wrap: break-word;
}
.main :where([class*="badge"], [class*="chip"], [class*="pill"]) { max-width: 100%; }

/* ── 3) Layout: พื้นที่เนื้อหา (.main) ────────────────────────────── */
.main {
  /* !important: บางหน้าตั้ง padding ของ .main เป็น 6–10px ด้วย !important — gutter ต้องมาจาก token กลาง */
  padding-left: var(--rw-gutter) !important;
  padding-right: var(--rw-gutter) !important;
}
@media (min-width: 992px) {
  /* เดสก์ท็อป: ใช้ค่าเดิมของระบบ (36px) ให้ตรงกับ layout ที่ออกแบบไว้ */
  .main { padding-left: var(--rw-gutter-lg) !important; padding-right: var(--rw-gutter-lg) !important; }
}

/* หัวข้อหน้า — ขนาดเดียวกันทุกหน้า (หน้าเดิมกำหนดไว้ 16.8–30px ต่างกัน) */
.main .page-header h1 { font-size: var(--rw-fs-h1) !important; line-height: 1.25; }
.main .page-header { flex-wrap: wrap; row-gap: var(--rw-space-3); }

/* หน้าที่มี topbar/แถวเครื่องมือ: ตัดบรรทัดแทนการล้น */
.main :where(.toolbar, .filter-bar, .card-actions, .page-actions, .header-actions, .btn-row, .actions) {
  flex-wrap: wrap;
  row-gap: var(--rw-space-2);
}

/* ── 4) Typography ────────────────────────────────────────────────── */
.main small, .main .text-small { font-size: var(--rw-fs-small); }

/* ── 5) Form & Button ─────────────────────────────────────────────── */
/* ช่องกรอก/ปุ่ม: กว้างไม่เกินกล่องที่ใส่ */
.main :where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]),
              select, textarea) {
  max-width: 100%;
}
.main :where(textarea) { min-height: 88px; }

/* มือถือ/แท็บเล็ต (ทุกอุปกรณ์ที่ไม่ใช่จอใหญ่): ฟอนต์ช่องกรอก 16px กัน iOS ซูม */
@media (max-width: 991.98px) {
  .main :where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]),
                select, textarea) {
    font-size: var(--rw-control-fs);
  }
}

/* ทัชสกรีน: พื้นที่แตะอย่างน้อย 44px (ปุ่มรูปไอคอนในตาราง/การ์ดก็เช่นกัน)
   ยกเว้น .rw-tap-auto และ widget แจ้งเตือน (.uwn-*) ที่กำหนดขนาดเองในแถบบนที่แคบ */
@media (pointer: coarse) {
  .main :where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]):not([type="hidden"]),
                select) {
    min-height: var(--rw-tap);
  }
  .main :where(button, .btn, a.btn, [role="button"], input[type="button"], input[type="submit"]):not(.rw-tap-auto):not([class*="uwn-"]) {
    min-height: var(--rw-tap);
    min-width: var(--rw-tap);
  }
  /* checkbox / radio: ขยายกล่องคลิกด้วย label โดยไม่ดันเลย์เอาต์ */
  .main :where(input[type="checkbox"], input[type="radio"]) { width: 20px; height: 20px; }
  .main label:has(> input[type="checkbox"], > input[type="radio"]) { min-height: 32px; }
  .sidebar .nav-item { min-height: var(--rw-tap); }
}
/* เมาส์: ความสูง control มาตรฐานเท่ากันทุกหน้า */
@media (pointer: fine) {
  .main :where(select, input[type="text"], input[type="search"], input[type="email"], input[type="password"],
                input[type="number"], input[type="date"], input[type="time"], input[type="tel"]) {
    min-height: var(--rw-control-h);
  }
}

/* ── 6) Table ─────────────────────────────────────────────────────── */
.rw-table-wrap,
.uww-table-scroll {
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.rw-table-wrap > table, .uww-table-scroll > table { min-width: 100%; }
.main table { max-width: none; }

/* โหมดการ์ดบนมือถือ (opt-in): ใส่ class rw-table-cards ที่ <table> */
@media (max-width: 575.98px) {
  table.rw-table-cards, table.rw-table-cards tbody, table.rw-table-cards tr, table.rw-table-cards td { display: block; width: 100%; }
  table.rw-table-cards { min-width: 0 !important; }
  table.rw-table-cards thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  table.rw-table-cards tr {
    margin-bottom: var(--rw-space-3);
    border: 1px solid rgba(15, 23, 42, .1);
    border-radius: var(--rw-radius);
    padding: var(--rw-space-2) var(--rw-space-3);
    background: #fff;
  }
  table.rw-table-cards td {
    display: flex;
    gap: var(--rw-space-3);
    justify-content: space-between;
    align-items: flex-start;
    text-align: right;
    border: 0;
    padding: 6px 0;
  }
  table.rw-table-cards td::before {
    content: attr(data-label);
    flex: 0 0 38%;
    max-width: 38%;
    text-align: left;
    font-weight: 600;
    color: #5b667a;
  }
  table.rw-table-cards td:not([data-label])::before { content: none; }
}

/* ── 7) Modal ─────────────────────────────────────────────────────── */
/* ทุก modal ไม่เกินพื้นที่หน้าจอ ไม่ว่าแนวตั้ง/แนวนอน/ซูม 200% และเลื่อนข้างในได้
   :where() = specificity 0 → เป็นแค่เพดาน ไม่ทับ max-width ของ modal แต่ละหน้า (เช่น กล้องสแกน 480px) */
:where(.modal-overlay > *, .modal-bg > *, .modal-box, dialog, [role="dialog"], .rw-modal) {
  max-width: calc(100vw - 24px);
  max-height: calc(100vh - 24px);
  max-height: calc(100dvh - 24px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.rw-modal { width: 100%; margin: auto; }
@media (min-width: 768px) { .rw-modal { width: min(560px, 100%); } }
@media (min-width: 992px) { .rw-modal { width: min(var(--rw-modal-w), 100%); } }

/* ── 8) Reusable layout components (งานใหม่) ──────────────────────── */
.rw-container {
  width: 100%;
  max-width: var(--rw-content-max);
  margin-inline: auto;
  padding-inline: var(--rw-gutter);
}
.rw-stack { display: flex; flex-direction: column; gap: var(--rw-space-4); }
.rw-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--rw-space-3); }

.rw-grid {
  display: grid;
  gap: var(--rw-space-4);
  grid-template-columns: repeat(var(--rw-cols-xs), minmax(0, 1fr));
}
@media (min-width: 768px)  { .rw-grid { grid-template-columns: repeat(var(--rw-cols-md), minmax(0, 1fr)); } }
@media (min-width: 992px)  { .rw-grid { grid-template-columns: repeat(var(--rw-cols-lg), minmax(0, 1fr)); } }
@media (min-width: 1400px) { .rw-grid { grid-template-columns: repeat(var(--rw-cols-xl), minmax(0, 1fr)); } }

.rw-form {
  display: grid;
  gap: var(--rw-space-3) var(--rw-space-4);
  grid-template-columns: repeat(var(--rw-form-cols-xs), minmax(0, 1fr));
}
@media (min-width: 768px)  { .rw-form { grid-template-columns: repeat(var(--rw-form-cols-md), minmax(0, 1fr)); } }
@media (min-width: 1200px) { .rw-form { grid-template-columns: repeat(var(--rw-form-cols-xl), minmax(0, 1fr)); } }
.rw-form > .rw-span-all { grid-column: 1 / -1; }

/* ซ่อน/แสดงตาม breakpoint */
@media (max-width: 575.98px) { .rw-hide-down-sm { display: none !important; } }
@media (max-width: 767.98px) { .rw-hide-down-md { display: none !important; } }
@media (max-width: 991.98px) { .rw-hide-down-lg { display: none !important; } }
@media (min-width: 576px)    { .rw-hide-up-sm { display: none !important; } }
@media (min-width: 768px)    { .rw-hide-up-md { display: none !important; } }
@media (min-width: 992px)    { .rw-hide-up-lg { display: none !important; } }

.rw-sr-only {
  position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── 9) แนวนอนบนมือถือ (จอเตี้ย) ─────────────────────────────────── */
@media (orientation: landscape) and (max-height: 500px) {
  :root { --rw-pad-top: 8px; --rw-pad-bottom: 12px; }
  .modal-overlay > *, .modal-bg > *, .modal-box, dialog, [role="dialog"], .rw-modal {
    max-height: calc(100dvh - 12px);
  }
  .sidebar-brand { padding-top: 10px !important; padding-bottom: 8px !important; min-height: 0; }
  .sidebar .nav-item { margin-top: 1px !important; margin-bottom: 1px !important; }
  .nav-section { padding-top: 10px !important; padding-bottom: 4px !important; }
}

/* ── 10) การเข้าถึง (Accessibility) ───────────────────────────────── */
/* ซูมถึง 200% = viewport เหลือ ~640px: ห้ามมีอะไรล็อกความกว้างค้างไว้ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; }
}
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--uww-brand, #2563eb);
  outline-offset: 2px;
}

/* ── 11) โหมดประหยัดเอฟเฟกต์ (มือถือ / เครื่องสเปกต่ำ) ───────────────────
   ปิด backdrop-filter, blur และ animation ที่วนไม่รู้จบ (ของตกแต่งล้วนๆ)
   คงไว้: spinner โหลด, transition ตอนกด/เปิด-ปิด, animation ที่เล่นครั้งเดียว
   เปิดอัตโนมัติเมื่อ: จอ ≤ 767.98px, จอสัมผัส (pointer:coarse), ผู้ใช้ตั้ง "ลดการเคลื่อนไหว"
   หรือ rwdf.js ตรวจเจอเครื่องสเปกต่ำ (RAM ≤ 2GB, CPU ≤ 2 คอร์, Data Saver, เน็ต 2G)
   → ใส่ <html data-perf="lite"> (และ RWDF.lite = true)
   ชุดกฎมีสองชุดเหมือนกัน (media query / html[data-perf="lite"]) แก้ชุดหนึ่งต้องแก้อีกชุด
   ถ้าเพิ่ม animation ตกแต่งแบบวนซ้ำ (infinite) ใหม่ในหน้าใด ให้เพิ่ม selector ที่นี่ทั้งสองชุด */
@media (max-width: 767.98px), (hover: none) and (pointer: coarse), (prefers-reduced-motion: reduce) {
  html *, html *::before, html *::after { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
  html .light-orb { display: none !important; }
  html body, html body::before, html body::after { animation: none !important; }
  html .brand-icon-wrap, html .brand-icon-wrap::before, html .brand-icon-wrap::after { animation: none !important; }
  html .brand h1::after { animation: none !important; opacity: 0 !important; }
  html .orb { animation: none !important; will-change: auto !important; }
  html .glass::after, html .uww-star, html .uww-shot, html .uww-flash { display: none !important; }
  html .status-dot.ok, html .status-dot.ok::after, html .status-dot.warn::after { animation: none !important; }
  html .leave-today.alert-red .lt-ico, html .cal-day.today, html .session-timer.danger { animation: none !important; }
  html .pdpa-row, html .alert-icon, html .alert-icon i, html .pdpa-gate .card::before { animation: none !important; }
  html .card:has(> .profile-card)::before, html .card:has(> .profile-card)::after, html .card:has(> .profile-card) .avatar { animation: none !important; }
}
html[data-perf="lite"] *, html[data-perf="lite"] *::before, html[data-perf="lite"] *::after { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
html[data-perf="lite"] .light-orb { display: none !important; }
html[data-perf="lite"] body, html[data-perf="lite"] body::before, html[data-perf="lite"] body::after { animation: none !important; }
html[data-perf="lite"] .brand-icon-wrap, html[data-perf="lite"] .brand-icon-wrap::before, html[data-perf="lite"] .brand-icon-wrap::after { animation: none !important; }
html[data-perf="lite"] .brand h1::after { animation: none !important; opacity: 0 !important; }
html[data-perf="lite"] .orb { animation: none !important; will-change: auto !important; }
html[data-perf="lite"] .glass::after, html[data-perf="lite"] .uww-star, html[data-perf="lite"] .uww-shot, html[data-perf="lite"] .uww-flash { display: none !important; }
html[data-perf="lite"] .status-dot.ok, html[data-perf="lite"] .status-dot.ok::after, html[data-perf="lite"] .status-dot.warn::after { animation: none !important; }
html[data-perf="lite"] .leave-today.alert-red .lt-ico, html[data-perf="lite"] .cal-day.today, html[data-perf="lite"] .session-timer.danger { animation: none !important; }
html[data-perf="lite"] .pdpa-row, html[data-perf="lite"] .alert-icon, html[data-perf="lite"] .alert-icon i, html[data-perf="lite"] .pdpa-gate .card::before { animation: none !important; }
html[data-perf="lite"] .card:has(> .profile-card)::before, html[data-perf="lite"] .card:has(> .profile-card)::after, html[data-perf="lite"] .card:has(> .profile-card) .avatar { animation: none !important; }
